示例#1
0
/*! function to resume recognizer */
static switch_status_t pocketsphinx_asr_resume(switch_asr_handle_t *ah)
{
	pocketsphinx_t *ps = (pocketsphinx_t *) ah->private_info;
	switch_status_t status = SWITCH_STATUS_FALSE;

	switch_mutex_lock(ps->flag_mutex);
	switch_clear_flag(ps, PSFLAG_HAS_TEXT);
	ps->silence_time = switch_micro_time_now();
	if (!switch_test_flag(ps, PSFLAG_READY)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Manually Resuming\n");

		if (ps_start_utt(ps->ps, NULL)) {
			status = SWITCH_STATUS_GENERR;
		} else {
			switch_set_flag(ps, PSFLAG_READY);
		}
	}
	switch_mutex_unlock(ps->flag_mutex);

	return status;
}
示例#2
0
SWITCH_DECLARE(switch_status_t) switch_strftime_tz(const char *tz, const char *format, char *date, size_t len, switch_time_t thetime)
{
	time_t timep;

	const char *tz_name = tz;
	const char *tzdef;

	switch_size_t retsize;

	struct tm tm = { 0 };
	switch_time_exp_t stm;

	if (!thetime) {
		thetime = switch_micro_time_now();
	}

	timep = (thetime) / (int64_t) (1000000);

	if (!zstr(tz_name)) {
		tzdef = switch_lookup_timezone(tz_name);
	} else {
		/* We set the default timezone to GMT. */
		tz_name = "GMT";
		tzdef = "GMT";
	}

	if (tzdef) {				/* The lookup of the zone may fail. */
		tztime(&timep, tzdef, &tm);
		tm2switchtime(&tm, &stm);
		switch_strftime_nocheck(date, &retsize, len, zstr(format) ? "%Y-%m-%d %T" : format, &stm);
		if (!zstr_buf(date)) {
			return SWITCH_STATUS_SUCCESS;
		}
	}
	return SWITCH_STATUS_FALSE;
}
示例#3
0
static void do_rotate(cdr_fd_t *fd)
{
	switch_time_exp_t tm;
	char date[80] = "";
	switch_size_t retsize;
	char *p;
	size_t len;

	close(fd->fd);
	fd->fd = -1;

	if (globals.rotate) {
		switch_time_exp_lt(&tm, switch_micro_time_now());
		switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d-%H-%M-%S", &tm);

		len = strlen(fd->path) + strlen(date) + 2;
		p = switch_mprintf("%s.%s", fd->path, date);
		assert(p);
		switch_file_rename(fd->path, p, globals.pool);
		free(p);
	}

	do_reopen(fd);

	if (fd->fd < 0) {
		switch_event_t *event;
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error opening %s\n", fd->path);
		if (switch_event_create(&event, SWITCH_EVENT_TRAP) == SWITCH_STATUS_SUCCESS) {
			switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Critical-Error", "Error opening cdr file %s\n", fd->path);
			switch_event_fire(&event);
		}
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s CDR logfile %s\n", globals.rotate ? "Rotated" : "Re-opened", fd->path);
	}

}
示例#4
0
/*! 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);
	ps->silence_time = switch_micro_time_now();
	switch_clear_flag(ps, PSFLAG_START_OF_SPEECH);
	switch_clear_flag(ps, PSFLAG_NOINPUT_TIMEOUT);
	switch_clear_flag(ps, PSFLAG_NOINPUT);
	switch_clear_flag(ps, PSFLAG_NOMATCH);
	switch_clear_flag(ps, PSFLAG_SPEECH_TIMEOUT);
	if (ps->start_input_timers) {
		switch_set_flag(ps, PSFLAG_INPUT_TIMERS);
	} else {
		switch_clear_flag(ps, PSFLAG_INPUT_TIMERS);
	}
	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;
}
示例#5
0
static switch_status_t set_json_cdr_log_dirs()
{
	switch_time_exp_t tm;
	char *path = NULL;
	char date[80] = "";
	switch_size_t retsize;
	switch_status_t status = SWITCH_STATUS_SUCCESS, dir_status;
	int err_dir_index;

	switch_time_exp_lt(&tm, switch_micro_time_now());
	switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d-%H-%M-%S", &tm);

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Rotating log file paths\n");

	if (!zstr(globals.base_log_dir)) {
		if (globals.rotate) {
			if ((path = switch_mprintf("%s%s%s", globals.base_log_dir, SWITCH_PATH_SEPARATOR, date))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Rotating log file path to %s\n", path);

				dir_status = SWITCH_STATUS_SUCCESS;
				if (switch_directory_exists(path, globals.pool) != SWITCH_STATUS_SUCCESS) {
					dir_status = switch_dir_make(path, SWITCH_FPROT_OS_DEFAULT, globals.pool);
				}

				if (dir_status == SWITCH_STATUS_SUCCESS) {
					switch_thread_rwlock_wrlock(globals.log_path_lock);
					switch_safe_free(globals.log_dir);
					globals.log_dir = path;
					switch_thread_rwlock_unlock(globals.log_path_lock);
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new mod_json_cdr log_dir path\n");
					switch_safe_free(path);
					status = SWITCH_STATUS_FALSE;
				}
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to generate new mod_json_cdr log_dir path\n");
				status = SWITCH_STATUS_FALSE;
			}
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Setting log file path to %s\n", globals.base_log_dir);
			if ((path = switch_safe_strdup(globals.base_log_dir))) {
				switch_thread_rwlock_wrlock(globals.log_path_lock);
				switch_safe_free(globals.log_dir);
				switch_dir_make_recursive(path, SWITCH_DEFAULT_DIR_PERMS, globals.pool);
				globals.log_dir = path;
				switch_thread_rwlock_unlock(globals.log_path_lock);
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set log_dir path\n");
				status = SWITCH_STATUS_FALSE;
			}
		}
	}

	for (err_dir_index = 0; err_dir_index < globals.err_dir_count; err_dir_index++) {
		if (globals.rotate) {
			if ((path = switch_mprintf("%s%s%s", globals.base_err_log_dir[err_dir_index], SWITCH_PATH_SEPARATOR, date))) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Rotating err log file path to %s\n", path);

				dir_status = SWITCH_STATUS_SUCCESS;
				if (switch_directory_exists(path, globals.pool) != SWITCH_STATUS_SUCCESS) {
					dir_status = switch_dir_make(path, SWITCH_FPROT_OS_DEFAULT, globals.pool);
				}

				if (dir_status == SWITCH_STATUS_SUCCESS) {
					switch_thread_rwlock_wrlock(globals.log_path_lock);
					switch_safe_free(globals.err_log_dir[err_dir_index]);
					globals.err_log_dir[err_dir_index] = path;
					switch_thread_rwlock_unlock(globals.log_path_lock);
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new mod_json_cdr err_log_dir path\n");
					switch_safe_free(path);
					status = SWITCH_STATUS_FALSE;
				}
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to generate new mod_json_cdr err_log_dir path\n");
				status = SWITCH_STATUS_FALSE;
			}
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Setting err log file path to %s\n", globals.base_err_log_dir[err_dir_index]);
			if ((path = switch_safe_strdup(globals.base_err_log_dir[err_dir_index]))) {
				switch_thread_rwlock_wrlock(globals.log_path_lock);
				switch_safe_free(globals.err_log_dir[err_dir_index]);
				switch_dir_make_recursive(path, SWITCH_DEFAULT_DIR_PERMS, globals.pool);
				globals.err_log_dir[err_dir_index] = path;
				switch_thread_rwlock_unlock(globals.log_path_lock);
			} else {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set err_log_dir path\n");
				status = SWITCH_STATUS_FALSE;
			}
		}
	}

	return status;
}
static switch_status_t switch_sangoma_decode(switch_codec_t *codec,	/* codec session handle */
										  switch_codec_t *other_codec,	/* what is this? */
										  void *encoded_data,	/* data that we must decode into slinear and put it in decoded_data */
										  uint32_t encoded_data_len,	/* length in bytes of the encoded data */
										  uint32_t encoded_rate,	/* at which rate was the data encoded */
										  void *decoded_data,	/* buffer where we must put the decoded data */
										  uint32_t *decoded_data_len,	/* we must set this value to the size of the decoded data */
										  uint32_t *decoded_rate,	/* rate of the decoded data */
										  unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */ )
{
	/* FS core checks the actual samples per second and microseconds per packet to determine the buffer size in the worst case scenario, no need to check
	 * whether the buffer passed in by the core will be enough */
	switch_frame_t encoded_frame;
	switch_frame_t ulaw_frame;
	switch_status_t sres;
	switch_time_t now_time, difftime;
	short *dbuf_linear;
	int i = 0;
	int res = 0;
	struct sangoma_transcoding_session *sess = codec->private_info;

	dbuf_linear = decoded_data;

	/* start assuming we will not decode anything */
	*decoded_data_len = 0;
	if (*flag & SWITCH_CODEC_FLAG_SILENCE) {
		memset(dbuf_linear, 0, codec->implementation->decoded_bytes_per_packet);
		*decoded_data_len = codec->implementation->decoded_bytes_per_packet;
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Returned silence on request\n");
		return SWITCH_STATUS_SUCCESS;
	}

	/* initialize on first use */
	if (!sess->decoder.txrtp) {
		int err = 0;
		switch_mutex_lock(g_sessions_lock);
		err = sngtc_create_transcoding_session(&sess->decoder.request, &sess->decoder.reply, 0);
		if (err) {
			memset(&sess->decoder, 0, sizeof(sess->decoder));
			switch_mutex_unlock(g_sessions_lock);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create Sangoma decoding session.\n");
			return SWITCH_STATUS_FALSE;
		}
		sess->decoder.txrtp = sess->decoder.reply.tx_fd;
		sess->decoder.rxrtp = sess->decoder.reply.rx_fd;
		switch_mutex_unlock(g_sessions_lock);
	}

	/* do the writing */
	memset(&encoded_frame, 0, sizeof(encoded_frame));
	encoded_frame.source = __FUNCTION__;
	encoded_frame.data = encoded_data;
	encoded_frame.datalen = encoded_data_len;
	encoded_frame.payload = codec->implementation->ianacode;

	res = switch_rtp_write_frame(sess->decoder.txrtp, &encoded_frame);
	if (-1 == res) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to write to Sangoma decoder RTP session.\n");
		return SWITCH_STATUS_FALSE;
	}

	if (res < encoded_data_len) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, 
				"Requested to write %d bytes to Sangoma decoder RTP session, but wrote %d bytes.\n",
			       	encoded_data_len, res);
		return SWITCH_STATUS_FALSE;
	}
	sess->decoder.tx++;

	/* do the reading */
	for ( ; ; ) {
		sres = switch_rtp_zerocopy_read_frame(sess->decoder.rxrtp, &ulaw_frame, SWITCH_IO_FLAG_NOBLOCK);
		if (sres == SWITCH_STATUS_GENERR) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma decoder RTP session: %d\n", sres);
			return SWITCH_STATUS_FALSE;
		}

		if (0 == ulaw_frame.datalen) {
			break;
		}

		if (ulaw_frame.payload != IANA_ULAW
		    && ulaw_frame.payload != IANACODE_CN) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma decoder RTP session, expecting %d\n",
					ulaw_frame.payload, IANA_ULAW);
			break;
		}

		if (*decoded_data_len) {
			sess->decoder.rxdiscarded++;
		}

		/* transcode to linear */
		for (i = 0; i < ulaw_frame.datalen; i++) {
			dbuf_linear[i] = ulaw_to_linear(((char *)ulaw_frame.data)[i]);
		}
		*decoded_data_len = i * 2;
	}

	/* update decoding stats */
	sess->decoder.rx++;

	now_time = switch_micro_time_now();
	if (!sess->decoder.last_rx_time) {
		sess->decoder.last_rx_time = now_time;
	} else {
		difftime = now_time - sess->decoder.last_rx_time;
		sess->decoder.avgrxus = sess->decoder.avgrxus ? ((sess->decoder.avgrxus + difftime)/2) : difftime;
		sess->decoder.last_rx_time = now_time;
	}

	/* check sequence and bump lost rx packets count if needed */
	if (sess->decoder.lastrxseqno >= 0) {
		if (ulaw_frame.seq > (sess->decoder.lastrxseqno + 2) ) {
			sess->decoder.rxlost += ulaw_frame.seq - sess->decoder.lastrxseqno - 1;
		}
	}
	sess->decoder.lastrxseqno = ulaw_frame.seq;

	return SWITCH_STATUS_SUCCESS;
}
示例#7
0
static switch_status_t hu_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
{
	int32_t t;
	switch_time_t target = 0, target_now = 0;
	switch_time_exp_t tm, tm_now;
	uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	const char *tz = switch_channel_get_variable(channel, "timezone");

	if (say_args->type == SST_TIME_MEASUREMENT) {
		int64_t hours = 0;
		int64_t minutes = 0;
		int64_t seconds = 0;
		int64_t r = 0;

		if (strchr(tosay, ':')) {
			char *tme = switch_core_session_strdup(session, tosay);
			char *p;

			if ((p = strrchr(tme, ':'))) {
				*p++ = '\0';
				seconds = atoi(p);
				if ((p = strchr(tme, ':'))) {
					*p++ = '\0';
					minutes = atoi(p);
					if (tme) {
						hours = atoi(tme);
					}
				} else {
					minutes = atoi(tme);
				}
			}
		} else {
			if ((seconds = atol(tosay)) <= 0) {
				seconds = (int64_t) switch_epoch_time_now(NULL);
			}

			if (seconds >= 60) {
				minutes = seconds / 60;
				r = seconds % 60;
				seconds = r;
			}

			if (minutes >= 60) {
				hours = minutes / 60;
				r = minutes % 60;
				minutes = r;
			}
		}

		if (hours) {
			say_num(hours, SSM_PRONOUNCED);
			say_file("time/hour.wav");
		} else {
			say_file("digits/0.wav");
			say_file("time/hour.wav");
		}

		if (minutes) {
			say_num(minutes, SSM_PRONOUNCED);
			say_file("time/minute.wav");
		} else {
			say_file("digits/0.wav");
			say_file("time/minute.wav");
		}

		if (seconds) {
			say_num(seconds, SSM_PRONOUNCED);
			say_file("time/second.wav");
		} else {
			say_file("digits/0.wav");
			say_file("time/second.wav");
		}

		return SWITCH_STATUS_SUCCESS;
	}

	if ((t = atol(tosay)) > 0) {
		target = switch_time_make(t, 0);
		target_now = switch_micro_time_now();
	} else {
		target = switch_micro_time_now();
		target_now = switch_micro_time_now();
	}

	if (tz) {
		int check = atoi(tz);
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz);
		if (check) {
			switch_time_exp_tz(&tm, target, check);
			switch_time_exp_tz(&tm_now, target_now, check);
		} else {
			switch_time_exp_tz_name(tz, &tm, target);
			switch_time_exp_tz_name(tz, &tm_now, target_now);
		}
	} else {
		switch_time_exp_lt(&tm, target);
		switch_time_exp_lt(&tm_now, target_now);
	}

	switch (say_args->type) {
	case SST_CURRENT_DATE_TIME:
		say_date = say_time = 1;
		break;
	case SST_CURRENT_DATE:
		say_date = 1;
		break;
	case SST_CURRENT_TIME:
		say_time = 1;
		break;
	case SST_SHORT_DATE_TIME:
		say_time = 1;
		if (tm.tm_year != tm_now.tm_year) {
			say_date = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday) {
			say_today = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday - 1) {
			say_yesterday = 1;
			break;
		}
		if (tm.tm_yday >= tm_now.tm_yday - 5) {
			say_dow = 1;
			break;
		}
		if (tm.tm_mon != tm_now.tm_mon) {
			say_month = say_day = say_dow = 1;
			break;
		}

		say_month = say_day = say_dow = 1;

		break;
	default:
		break;
	}

	if (say_today) {
		say_file("time/today.wav");
	}
	if (say_yesterday) {
		say_file("time/yesterday.wav");
	}
	if (say_dow) {
		say_file("time/day-%d.wav", tm.tm_wday);
	}

	if (say_date) {
		say_year = say_month = say_day = say_dow = 1;
		say_today = say_yesterday = 0;
	}

	if (say_year) {
		say_num(tm.tm_year + 1900, SSM_PRONOUNCED);
	}

	if (say_month) {
		say_file("time/mon-%d.wav", tm.tm_mon);
	}
	if (say_day) {
		say_num(tm.tm_mday, SSM_PRONOUNCED);
	}

	if (say_time) {
		say_num(tm.tm_hour, SSM_PRONOUNCED);
		say_file("time/hour.wav");

		say_num(tm.tm_min, SSM_PRONOUNCED);
		say_file("time/minute.wav");

	}

	return SWITCH_STATUS_SUCCESS;
}
示例#8
0
static switch_status_t ru_say_time(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args,say_opt_t *say_opt)
{
	int32_t t;
	char buf[80];
	switch_time_t target = 0, target_now = 0;
	switch_time_exp_t tm, tm_now;
	uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0;
	const char *tz = NULL;
	tz = switch_say_file_handle_get_variable(sh, "timezone");    

	//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, " ru_say_time %s  type=%d method=%d\n", tosay, say_args->type, say_args->method);

	if (say_args->type == SST_TIME_MEASUREMENT) {
		int64_t hours = 0;
		int64_t minutes = 0;
		int64_t seconds = 0;
		int64_t r = 0;

		if (strchr(tosay, ':')) {
			char *tme = strdup(tosay);
			char *p;

			if ((p = strrchr(tme, ':'))) {
				*p++ = '\0';
				seconds = atoi(p);
				if ((p = strchr(tme, ':'))) {
					*p++ = '\0';
					minutes = atoi(p);
					if (tme) {
						hours = atoi(tme);
					}
				} else {
					minutes = atoi(tme);
				}
			}
			free(tme);
		} else {
			if ((seconds = atol(tosay)) <= 0) {
				seconds = (int64_t) switch_epoch_time_now(NULL);
			}

			if (seconds >= 60) {
				minutes = seconds / 60;
				r = seconds % 60;
			}

			if (minutes >= 60) {
				hours = minutes / 60;
				r = minutes % 60;
				minutes = r;
			}
		}

		switch_snprintf(buf, sizeof(buf), "%u", (unsigned) hours);
		ru_say_count(sh, buf, male, nominativus);

		if (((hours % 10) == 1) && (hours != 11)) {
			/* час */
			switch_say_file(sh, "time/hour");
		} else if (((hours % 10 > 1) && (hours % 10 < 5)) && ((hours < 12) || (hours > 14))) {
			switch_say_file(sh, "time/hours-a");	/* часа */
		} else {
			switch_say_file(sh, "time/hours");	/* часов */
		}

		switch_snprintf(buf, sizeof(buf), "%u", (unsigned) minutes);	//перевести минуты в *char
		ru_say_count(sh, buf, female, nominativus);

		if (((minutes % 10) == 1) && (minutes != 11)) {
			switch_say_file(sh, "time/minute");	//минута
		} else if (((minutes % 10 > 1) && (minutes % 10 < 5)) && ((minutes < 12) || (minutes > 14))) {
			switch_say_file(sh, "time/minutes-i");	// минуты
		} else {
			switch_say_file(sh, "time/minutes");	//минут
		}

		if (seconds != 0) {
			switch_snprintf(buf, sizeof(buf), "%u", (unsigned) seconds);
			ru_say_count(sh, buf, female, nominativus);
			if (((seconds % 10) == 1) && (seconds != 11)) {
				switch_say_file(sh, "time/second");	// секунда
			} else if (((seconds % 10 > 1) && (seconds % 10 < 5)) && ((seconds < 12) || (seconds > 14))) {
				switch_say_file(sh, "time/seconds-i");	// секуны
			} else {
				switch_say_file(sh, "time/seconds");	//секунд
			}
		}
		return SWITCH_STATUS_SUCCESS;
	}

	if ((t = atol(tosay)) > 0) {
		target = switch_time_make(t, 0);
		target_now = switch_micro_time_now();
	} else {
		target = switch_micro_time_now();
		target_now = switch_micro_time_now();
	}

	if (tz) {
		int check = atoi(tz);
		//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz);
		if (check) {
			switch_time_exp_tz(&tm, target, check);
			switch_time_exp_tz(&tm_now, target_now, check);
		} else {
			switch_time_exp_tz_name(tz, &tm, target);
			switch_time_exp_tz_name(tz, &tm_now, target_now);
		}
	} else {
		switch_time_exp_lt(&tm, target);
		switch_time_exp_lt(&tm_now, target_now);
	}

	switch (say_args->type) {
	case SST_CURRENT_DATE_TIME:
		say_date = say_time = 1;
		break;
	case SST_CURRENT_DATE:
		say_date = 1;
		break;
	case SST_CURRENT_TIME:
		say_time = 1;
		break;
	case SST_SHORT_DATE_TIME:
		say_time = 1;
		tm.tm_sec = 0; // В коротком варианте секунды не проговариваем
		if (tm.tm_year != tm_now.tm_year) {
			say_date = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday) {
			say_today = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday - 1) {
			say_yesterday = 1;
			break;
		}
		if (tm.tm_yday >= tm_now.tm_yday - 5) {
			say_dow = 1;
			break;
		}
		if (tm.tm_mon != tm_now.tm_mon) {
			say_month = say_day = say_dow = 1;
			break;
		}

		say_month = say_day = say_dow = 1;

		break;
	default:
		break;
	}

	if (say_today) {
		switch_say_file(sh, "time/today");
	}
	if (say_yesterday) {
		switch_say_file(sh, "time/yesterday");
	}
	if (say_dow) {
		switch_say_file(sh, "time/day-%d", tm.tm_wday);
	}
	if (say_date) {
		say_year = say_month = say_day = say_dow = 1;
		say_today = say_yesterday = 0;
	}
	if (say_day) {
		switch_snprintf(buf, sizeof(buf), "%u", (unsigned) tm.tm_mday);
		ru_say_count(sh, buf, male_h, genitivus);
	}
	if (say_month) {
		switch_say_file(sh, "time/mon-%d", tm.tm_mon);
	}
	if (say_year) {
		switch_snprintf(buf, sizeof(buf), "%u", (unsigned) (tm.tm_year + 1900));
		ru_say_count(sh, buf, male_h, genitivus);
		switch_say_file(sh, "time/h-year");
	}
	if (say_time) {
		if (say_month || say_year || say_date || say_dow) {
			switch_say_file(sh, "time/at");
		}
		switch_snprintf(buf, sizeof(buf), "%d:%d:%d", tm.tm_hour, tm.tm_min, tm.tm_sec);
		say_args->type = SST_TIME_MEASUREMENT;
		ru_say_time(sh, buf, say_args,say_opt);
	}
	return SWITCH_STATUS_SUCCESS;
}
static long do_lookup_url(switch_memory_pool_t *pool, switch_event_t *event, char **response, const char *query, struct curl_httppost *post,
						  switch_curl_slist_t *headers, int timeout)
{
	switch_time_t start_time = switch_micro_time_now();
	switch_time_t time_diff = 0;
	CURL *curl_handle = NULL;
	long httpRes = 0;

	struct http_data http_data;

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

	http_data.max_bytes = 10240;
	SWITCH_STANDARD_STREAM(http_data.stream);

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "url: %s\n", query);
	curl_handle = switch_curl_easy_init();

	switch_curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 0);
	switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);

	if (!strncasecmp(query, "https", 5)) {
		switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
		switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
	}
	if (post) {
		switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPPOST, post);
	} else {
		switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1);
	}
	if (headers) {
		switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
	}
	switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
	switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
	/*
	   TIMEOUT_MS is introduced in 7.16.2, we have 7.16.0 in tree 
	 */
#ifdef CURLOPT_TIMEOUT_MS
	if (timeout > 0) {
		switch_curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, timeout);
	} else {
		switch_curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT_MS, globals.curl_timeout);
	}
#else
	if (timeout > 0) {
		switch_curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, timeout);
	} else {
		switch_curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, globals.curl_timeout / 1000);
	}
#endif
	switch_curl_easy_setopt(curl_handle, CURLOPT_URL, query);
	switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, file_callback);
	switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &http_data);
	switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-cidlookup/1.0");

	switch_curl_easy_perform(curl_handle);
	switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
	switch_curl_easy_cleanup(curl_handle);

	if (http_data.stream.data && !zstr((char *) http_data.stream.data) && strcmp(" ", http_data.stream.data)) {

		/* don't return UNKNOWN */
		if (strcmp("UNKNOWN", http_data.stream.data) || strcmp("UNAVAILABLE", http_data.stream.data)) {
			*response = switch_core_strdup(pool, http_data.stream.data);
		}
	}

	time_diff = (switch_micro_time_now() - start_time);	/* convert to milli from micro */

	if ((time_diff / 1000) >= globals.curl_warnduration) {
		switch_core_time_duration_t duration;
		switch_core_measure_time(time_diff, &duration);
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SLOW LOOKUP ("
						  "%um, " "%us, " "%ums" "): url: %s\n", duration.min, duration.sec, duration.ms, query);
	}

	switch_safe_free(http_data.stream.data);
	return httpRes;
}
int modem_close(modem_t *modem) 
{
	int r = 0;
	switch_status_t was_running = switch_test_flag(modem, MODEM_FLAG_RUNNING);

	switch_clear_flag(modem, MODEM_FLAG_RUNNING);

#ifndef WIN32
	if (modem->master > -1) {
		shutdown(modem->master, 2);
		close(modem->master);
		modem->master = -1;
#else
	if (modem->master) {
		SetEvent(modem->threadAbort);
		CloseHandle(modem->threadAbort);
		CloseHandle(modem->master);
		modem->master = 0;
#endif
		
		r++;
	}

	if (modem->slave > -1) {
		shutdown(modem->slave, 2);
		close(modem->slave);
		modem->slave = -1;
		r++;
	}


   	if (modem->t31_state) {
		t31_free(modem->t31_state);
		modem->t31_state = NULL;
	}

	unlink(modem->devlink);

	if (was_running) {
		switch_mutex_lock(globals.mutex);
		globals.REF_COUNT--;
		switch_mutex_unlock(globals.mutex);
	}

	return r;
}


switch_status_t modem_init(modem_t *modem, modem_control_handler_t control_handler)
{
	switch_status_t status = SWITCH_STATUS_SUCCESS;
#ifdef WIN32
	COMMTIMEOUTS timeouts={0};
#endif
	
	memset(modem, 0, sizeof(*modem));

	modem->master = -1;
	modem->slave = -1;

	/* windows will have to try something like:
	   http://com0com.cvs.sourceforge.net/viewvc/com0com/com0com/ReadMe.txt?revision=RELEASED

	 */

#if USE_OPENPTY
    if (openpty(&modem->master, &modem->slave, NULL, NULL, NULL)) {

	if (modem->master < 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to initialize pty\n");
		status = SWITCH_STATUS_FALSE;
		goto end;
    }

	modem->stty = ttyname(modem->slave);
#else
#if WIN32
	modem->slot = 4+globals.NEXT_ID++; /* need work here we start at COM4 for now*/
	snprintf(modem->devlink, sizeof(modem->devlink), "COM%d", modem->slot);

	modem->master = CreateFile(modem->devlink,
	GENERIC_READ | GENERIC_WRITE,
	0,
	0,
	OPEN_EXISTING,
	FILE_FLAG_OVERLAPPED,
	0);
	if(modem->master==INVALID_HANDLE_VALUE) {
		status = SWITCH_STATUS_FALSE;
		if(GetLastError()==ERROR_FILE_NOT_FOUND) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: Serial port does not exist\n");
			goto end;
		}
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: Serial port open error\n");
		goto end;
	}
#elif !defined(HAVE_POSIX_OPENPT)
    modem->master = open("/dev/ptmx", O_RDWR);
#else
    modem->master = posix_openpt(O_RDWR | O_NOCTTY);
#endif

#ifndef WIN32
    if (modem->master < 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to initialize UNIX98 master pty\n");
		
    }

    if (grantpt(modem->master) < 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to grant access to slave pty\n");
		
    }

    if (unlockpt(modem->master) < 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to unlock slave pty\n");
		
    }

    modem->stty = ptsname(modem->master);

    if (modem->stty == NULL) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to obtain slave pty filename\n");
		
    }

    modem->slave = open(modem->stty, O_RDWR);

    if (modem->slave < 0) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to open slave pty %s\n", modem->stty);
    }
#endif

#ifdef SOLARIS
    ioctl(modem->slave, I_PUSH, "ptem");  /* push ptem */
    ioctl(modem->slave, I_PUSH, "ldterm");    /* push ldterm*/
#endif
#endif

#ifndef WIN32
	modem->slot = globals.NEXT_ID++;
	snprintf(modem->devlink, sizeof(modem->devlink), "/dev/FS%d", modem->slot);
	
    unlink(modem->devlink);

    if (symlink(modem->stty, modem->devlink)) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Fatal error: failed to create %s symbolic link\n", modem->devlink);
		modem_close(modem);
		status = SWITCH_STATUS_FALSE;
		goto end;
    }

    if (fcntl(modem->master, F_SETFL, fcntl(modem->master, F_GETFL, 0) | O_NONBLOCK)) {
	    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot set up non-blocking read on %s\n", ttyname(modem->master));
	    modem_close(modem);
	    status = SWITCH_STATUS_FALSE;
	    goto end;
    }
#else
	timeouts.ReadIntervalTimeout=50;
	timeouts.ReadTotalTimeoutConstant=50;
	timeouts.ReadTotalTimeoutMultiplier=10;

	timeouts.WriteTotalTimeoutConstant=50;
	timeouts.WriteTotalTimeoutMultiplier=10;

	SetCommMask(modem->master, EV_RXCHAR);

	if(!SetCommTimeouts(modem->master, &timeouts)){
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot set up non-blocking read on %s\n", modem->devlink);
		modem_close(modem);
		status = SWITCH_STATUS_FALSE;
		goto end;
	}
	modem->threadAbort = CreateEvent(NULL, TRUE, FALSE, NULL);
#endif
	
	if (!(modem->t31_state = t31_init(NULL, t31_at_tx_handler, modem, t31_call_control_handler, modem, NULL, NULL))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot initialize the T.31 modem\n");
		modem_close(modem);
		status = SWITCH_STATUS_FALSE;
		goto end;
	}

	if (spandsp_globals.modem_verbose) {
		span_log_set_message_handler(&modem->t31_state->logging, spanfax_log_message, NULL);
		span_log_set_message_handler(&modem->t31_state->audio.modems.fast_modems.v17_rx.logging, spanfax_log_message, NULL);
		span_log_set_message_handler(&modem->t31_state->audio.modems.fast_modems.v29_rx.logging, spanfax_log_message, NULL);
		span_log_set_message_handler(&modem->t31_state->audio.modems.fast_modems.v27ter_rx.logging, spanfax_log_message, NULL);

		modem->t31_state->logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW;
		modem->t31_state->audio.modems.fast_modems.v17_rx.logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW;
		modem->t31_state->audio.modems.fast_modems.v29_rx.logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW;
		modem->t31_state->audio.modems.fast_modems.v27ter_rx.logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW;
	}

	modem->control_handler = control_handler;
	modem->flags = 0;
	switch_set_flag(modem, MODEM_FLAG_RUNNING);

	switch_mutex_init(&modem->mutex, SWITCH_MUTEX_NESTED, globals.pool);
	switch_mutex_init(&modem->cond_mutex, SWITCH_MUTEX_NESTED, globals.pool);
	switch_thread_cond_create(&modem->cond, globals.pool);

	modem_set_state(modem, MODEM_STATE_INIT);

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Modem [%s]->[%s] Ready\n", modem->devlink, modem->stty);

	switch_mutex_lock(globals.mutex);
	globals.REF_COUNT++;
	switch_mutex_unlock(globals.mutex);

end:
	return status;
}

static switch_endpoint_interface_t *modem_endpoint_interface = NULL;

struct private_object {
	switch_mutex_t *mutex;
	switch_core_session_t *session;
	switch_channel_t *channel;
	switch_codec_t read_codec;
	switch_codec_t write_codec;
	switch_frame_t read_frame;
	unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
	switch_timer_t timer;
	modem_t *modem;
	switch_caller_profile_t *caller_profile;
	int dead;
};

typedef struct private_object private_t;

static switch_status_t channel_on_init(switch_core_session_t *session);
static switch_status_t channel_on_hangup(switch_core_session_t *session);
static switch_status_t channel_on_destroy(switch_core_session_t *session);
static switch_status_t channel_on_routing(switch_core_session_t *session);
static switch_status_t channel_on_exchange_media(switch_core_session_t *session);
static switch_status_t channel_on_soft_execute(switch_core_session_t *session);
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
													switch_caller_profile_t *outbound_profile,
													switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
													switch_call_cause_t *cancel_cause);
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);


/* 
   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;
	private_t *tech_pvt = NULL;
	int to_ticks = 60, ring_ticks = 10, rt = ring_ticks;
	int rest = 500000;
	
	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_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
#ifndef WIN32
		int tioflags;
#endif
		char call_time[16];
		char call_date[16];
		switch_size_t retsize;
		switch_time_exp_t tm;

		switch_time_exp_lt(&tm, switch_micro_time_now());
		switch_strftime(call_date, &retsize, sizeof(call_date), "%m%d", &tm);
		switch_strftime(call_time, &retsize, sizeof(call_time), "%H%M", &tm);

#ifndef WIN32
		ioctl(tech_pvt->modem->slave, TIOCMGET, &tioflags);
		tioflags |= TIOCM_RI;
		ioctl(tech_pvt->modem->slave, TIOCMSET, &tioflags);
#endif

		at_reset_call_info(&tech_pvt->modem->t31_state->at_state);
		at_set_call_info(&tech_pvt->modem->t31_state->at_state, "DATE", call_date);
		at_set_call_info(&tech_pvt->modem->t31_state->at_state, "TIME", call_time);
		at_set_call_info(&tech_pvt->modem->t31_state->at_state, "NAME", tech_pvt->caller_profile->caller_id_name);
		at_set_call_info(&tech_pvt->modem->t31_state->at_state, "NMBR", tech_pvt->caller_profile->caller_id_number);
		at_set_call_info(&tech_pvt->modem->t31_state->at_state, "ANID", tech_pvt->caller_profile->ani);
		at_set_call_info(&tech_pvt->modem->t31_state->at_state, "USER", tech_pvt->caller_profile->username);
		at_set_call_info(&tech_pvt->modem->t31_state->at_state, "CDID", tech_pvt->caller_profile->context);
		at_set_call_info(&tech_pvt->modem->t31_state->at_state, "NDID", tech_pvt->caller_profile->destination_number);

		modem_set_state(tech_pvt->modem, MODEM_STATE_RINGING);
		t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_ALERTING);
		
		while(to_ticks > 0 && switch_channel_up(channel) && modem_get_state(tech_pvt->modem) == MODEM_STATE_RINGING) {
			if (--rt <= 0) {
				t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_ALERTING);
				rt = ring_ticks;
			}
			
			switch_yield(rest);
			to_ticks--;
		}
		
		if (to_ticks < 1 || modem_get_state(tech_pvt->modem) != MODEM_STATE_ANSWERED) {
			t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_NO_ANSWER);
			switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER);
		} else {
			t31_call_event(tech_pvt->modem->t31_state, AT_CALL_EVENT_ANSWERED);
			modem_set_state(tech_pvt->modem, MODEM_STATE_CONNECTED);
			switch_channel_mark_answered(channel);
		}
	}

	switch_channel_set_state(channel, CS_ROUTING);
	
	return SWITCH_STATUS_SUCCESS;
}
示例#11
0
static switch_status_t sin_say_time(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args)
{
	int32_t t;
	switch_time_t target = 0, target_now = 0;
	switch_time_exp_t tm, tm_now;
	uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0;
	const char *tz = NULL;

	tz = switch_say_file_handle_get_variable(sh, "timezone");		

	if (say_args->type == SST_TIME_MEASUREMENT) {
		int64_t hours = 0;
		int64_t minutes = 0;
		int64_t seconds = 0;
		int64_t r = 0;

		if (strchr(tosay, ':')) {
			char *tme = strdup(tosay);
			char *p;

			if ((p = strrchr(tme, ':'))) {
				*p++ = '\0';
				seconds = atoi(p);
				if ((p = strchr(tme, ':'))) {
					*p++ = '\0';
					minutes = atoi(p);
					if (tme) {
						hours = atoi(tme);
					}
				} else {
					minutes = atoi(tme);
				}
			}
			free(tme);
		} else {
			if ((seconds = atol(tosay)) <= 0) {
				seconds = (int64_t) switch_epoch_time_now(NULL);
			}

			if (seconds >= 60) {
				minutes = seconds / 60;
				r = seconds % 60;
				seconds = r;
			}

			if (minutes >= 60) {
				hours = minutes / 60;
				r = minutes % 60;
				minutes = r;
			}
		}

		if (hours) {
			
			if (hours == 1) {
				switch_say_file(sh, "time/payai");
			} else {
				switch_say_file(sh, "time/paya");
				say_num(sh, hours, SSM_PRONOUNCED);
			}
			
		} else {
			/*switch_say_file(sh, "time/s_hours");
			switch_say_file(sh, "digits/s_i-0");
	*/		
		}

		if (minutes) {
			
			if (minutes == 1) {
				switch_say_file(sh, "time/winadiyai");
			} else {
				switch_say_file(sh, "time/winadi");
				say_num(sh, minutes, SSM_PRONOUNCED);
			}
			
		} else {
			/*switch_say_file(sh, "time/s_minutes");
			switch_say_file(sh, "digits/s_i-0");*/
			
		}

		if (seconds) {
			
			if (seconds == 1) {
				switch_say_file(sh, "time/thathparayai");
			} else {
				switch_say_file(sh, "time/thathpara");
				say_num(sh, seconds, SSM_PRONOUNCED);
			}
			
		} else {
			
		/*	switch_say_file(sh, "time/s_seconds");
			switch_say_file(sh, "digits/s_i-0");*/
		}

		return SWITCH_STATUS_SUCCESS;
	}

	if ((t = atol(tosay)) > 0) {
		target = switch_time_make(t, 0);
		target_now = switch_micro_time_now();
	} else {
		target = switch_micro_time_now();
		target_now = switch_micro_time_now();
	}

	if (tz) {
		int check = atoi(tz);
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz);
		if (check) {
			switch_time_exp_tz(&tm, target, check);
			switch_time_exp_tz(&tm_now, target_now, check);
		} else {
			switch_time_exp_tz_name(tz, &tm, target);
			switch_time_exp_tz_name(tz, &tm_now, target_now);
		}
	} else {
		switch_time_exp_lt(&tm, target);
		switch_time_exp_lt(&tm_now, target_now);
	}

	switch (say_args->type) {
	case SST_CURRENT_DATE_TIME:
		say_date = say_time = 1;
		break;
	case SST_CURRENT_DATE:
		say_date = 1;
		break;
	case SST_CURRENT_TIME:
		say_time = 1;
		break;
	case SST_SHORT_DATE_TIME:
		say_time = 1;
		if (tm.tm_year != tm_now.tm_year) {
			say_date = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday) {
			say_today = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday - 1) {
			say_yesterday = 1;
			break;
		}
		if (tm.tm_yday >= tm_now.tm_yday - 5) {
			say_dow = 1;
			break;
		}
		if (tm.tm_mon != tm_now.tm_mon) {
			say_month = say_day = say_dow = 1;
			break;
		}

		say_month = say_day = say_dow = 1;

		break;
	default:
		break;
	}

	if (say_today) {
		switch_say_file(sh, "time/today");
	}
	if (say_yesterday) {
		switch_say_file(sh, "time/yesterday");
	}
	if (say_dow) {
		switch_say_file(sh, "time/day-s_%d", tm.tm_wday);
	}

	if (say_date) {
		say_year = say_month = say_day = say_dow = 1;
		say_today = say_yesterday = 0;
	}

	if (say_month) {
		switch_say_file(sh, "time/mon-s_%d", tm.tm_mon);
	}
	if (say_day) {
		say_num(sh, tm.tm_mday, SSM_COUNTED);
	}
	if (say_year) {
		say_num(sh, tm.tm_year + 1900, SSM_PRONOUNCED_YEAR);
	}

	if (say_time) {
		int32_t hour = tm.tm_hour, pm = 0;

		if (say_date || say_today || say_yesterday || say_dow) {
			switch_say_file(sh, "time/at");
		}

		if (hour > 12) {
			hour -= 12;
			pm = 1;
		} else if (hour == 12) {
			pm = 1;
		} else if (hour == 0) {
			hour = 12;
			pm = 0;
		}

		say_num(sh, hour, SSM_PRONOUNCED);

		if (tm.tm_min > 9) {
			say_num(sh, tm.tm_min, SSM_PRONOUNCED);
		} else if (tm.tm_min) {
			switch_say_file(sh, "time/oh");
			say_num(sh, tm.tm_min, SSM_PRONOUNCED);
		} else {
			switch_say_file(sh, "time/oclock");
		}

		switch_say_file(sh, "time/%s", pm ? "p-m" : "a-m");
	}

	return SWITCH_STATUS_SUCCESS;
}
示例#12
0
static switch_status_t fa_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
{
	int32_t t;
	switch_time_t target = 0, target_now = 0;
	switch_time_exp_t tm, tm_now;
	uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	const char *tz = switch_channel_get_variable(channel, "timezone");
	int jalali_year = 1, jalali_month = 0, jalali_day = 0;

	if (say_args->type == SST_TIME_MEASUREMENT) {
		int64_t hours = 0;
		int64_t minutes = 0;
		int64_t seconds = 0;
		int64_t r = 0;

		if (strchr(tosay, ':')) {
			char *tme = switch_core_session_strdup(session, tosay);
			char *p;

			if ((p = strrchr(tme, ':'))) {
				*p++ = '\0';
				seconds = atoi(p);
				if ((p = strchr(tme, ':'))) {
					*p++ = '\0';
					minutes = atoi(p);
					if (tme) {
						hours = atoi(tme);
					}
				} else {
					minutes = atoi(tme);
				}
			}
		} else {
			if ((seconds = atol(tosay)) <= 0) {
				seconds = (int64_t) switch_epoch_time_now(NULL);
			}

			if (seconds >= 60) {
				minutes = seconds / 60;
				r = seconds % 60;
				seconds = r;
			}

			if (minutes >= 60) {
				hours = minutes / 60;
				r = minutes % 60;
				minutes = r;
			}
		}

		if (hours) {
			say_num(hours, SSM_PRONOUNCED);
			if(minutes || seconds)
			{
				say_file("time/hour+.wav");
			}
			else
				say_file("time/hour.wav");
		}

		if (minutes) {
			say_num(minutes, SSM_PRONOUNCED);
			if( seconds )
			{
				say_file("time/minutes+.wav");
			}
			else
				say_file("time/minutes.wav");
		}

		if (seconds) {
			say_num(seconds, SSM_PRONOUNCED);
			say_file("time/seconds.wav");
		}

		return SWITCH_STATUS_SUCCESS;
	}

	if ((t = atol(tosay)) > 0) {
		target = switch_time_make(t, 0);
		target_now = switch_micro_time_now();
	} else {
		target = switch_micro_time_now();
		target_now = switch_micro_time_now();
	}

	if (tz) {
		int check = atoi(tz);
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz);
		if (check) {
			switch_time_exp_tz(&tm, target, check);
			switch_time_exp_tz(&tm_now, target_now, check);
		} else {
			switch_time_exp_tz_name(tz, &tm, target);
			switch_time_exp_tz_name(tz, &tm_now, target_now);
		}
	} else {
		switch_time_exp_lt(&tm, target);
		switch_time_exp_lt(&tm_now, target_now);
	}

	switch (say_args->type) {
	case SST_CURRENT_DATE_TIME:
		say_date = say_time = 1;
		break;
	case SST_CURRENT_DATE:
		say_date = 1;
		break;
	case SST_CURRENT_TIME:
		say_time = 1;
		break;
	case SST_SHORT_DATE_TIME:
		say_time = 1;
		if (tm.tm_year != tm_now.tm_year) {
			say_date = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday) {
			say_today = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday - 1) {
			say_yesterday = 1;
			break;
		}
		if (tm.tm_yday >= tm_now.tm_yday - 5) {
			say_dow = 1;
			break;
		}
		if (tm.tm_mon != tm_now.tm_mon) {
			say_month = say_day = say_dow = 1;
			break;
		}

		say_month = say_day = say_dow = 1;

		break;
	default:
		break;
	}

	if (say_today) {
		say_file("time/today.wav");
	}
	if (say_yesterday) {
		say_file("time/yesterday.wav");
	}
	if (say_dow) {
		say_file("time/day-%d.wav", tm.tm_wday);
	}

	if (say_date) {
		say_year = say_month = say_day = say_dow = 1;
		say_today = say_yesterday = 0;
	}

	gregorian_to_jalali(&jalali_year,&jalali_month,&jalali_day,tm.tm_year + 1900,tm.tm_mon + 1,tm.tm_mday);

	if (say_day) {
		if(jalali_day > 20 && jalali_day != 30)
		{
			say_file("digits/%d+.wav", (jalali_day - jalali_day % 10));
			say_file("digits/%de.wav", jalali_day % 10);
		}
		else
			say_file("digits/%de.wav", jalali_day);
	}

	if (say_month) {
		say_file("time/mon-%d.wav", jalali_month - 1);
	}

	if (say_year) {
		say_num(jalali_year, SSM_PRONOUNCED);
	}

	if (say_time) {
		int32_t hour = tm.tm_hour, pm = 0;

		if (say_date || say_today || say_yesterday || say_dow) {
			say_file("time/at.wav");
		}

		if (hour > 12) {
			hour -= 12;
			pm = 1;
		} else if (hour == 12) {
			pm = 1;
		} else if (hour == 0) {
			hour = 12;
			pm = 0;
		}

		say_file("time/hour-e.wav");
		say_file("digits/%do.wav",hour);
		play_group(SSM_PRONOUNCED, 0, (tm.tm_min - tm.tm_min % 10) / 10, tm.tm_min % 10, "time/minutes-e.wav", session, args);
		say_file("time/%s.wav", pm ? "p-m" : "a-m");
	}

	return SWITCH_STATUS_SUCCESS;
}
示例#13
0
static switch_status_t hr_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
{
	int32_t t;
	switch_time_t target = 0, target_now = 0;
	switch_time_exp_t tm, tm_now;
	uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	const char *tz = switch_channel_get_variable(channel, "timezone");
	
	int sat_desetinka = 0;
	int sat_jedinica = 0;
	int minuta_desetinka = 0;
	int minuta_jedinica = 0;
	int sekunda_desetinka = 0;
	int sekunda_jedinica = 0;

	if (say_args->type == SST_TIME_MEASUREMENT) {
		int64_t hours = 0;
		int64_t minutes = 0;
		int64_t seconds = 0;
		int64_t r = 0;

		if (strchr(tosay, ':')) {
			char *tme = switch_core_session_strdup(session, tosay);
			char *p;

			if ((p = strrchr(tme, ':'))) {
				*p++ = '\0';
				seconds = atoi(p);
				if ((p = strchr(tme, ':'))) {
					*p++ = '\0';
					minutes = atoi(p);
					if (tme) {
						hours = atoi(tme);
					}
				} else {
					minutes = atoi(tme);
				}
			}
		} else {
			if ((seconds = atol(tosay)) <= 0) {
				seconds = (int64_t) switch_epoch_time_now(NULL);
			}

			if (seconds >= 60) {
				minutes = seconds / 60;
				r = seconds % 60;
				seconds = r;
			}

			if (minutes >= 60) {
				hours = minutes / 60;
				r = minutes % 60;
				minutes = r;
			}
		}

		sat_jedinica = hours % 10;
		
		if (hours > 10)
			sat_desetinka = (int) (hours / 10);
	
		if (hours) 
		{
			say_num(hours, SSM_PRONOUNCED, "");
			
			if (sat_desetinka == 0 && sat_jedinica == 0)
			{
				nop;
			}
			else if (sat_desetinka == 1)
			{
				say_file("time/sati.wav");
			}
			else
			{
				switch(sat_jedinica)
				{
					case 1:
						say_file("time/sat.wav");
						break;
						
					case 2:
					case 3:
					case 4:
						say_file("time/sata.wav");
						break;
						
					case 0:
					case 5:
					case 6:
					case 7:
					case 8:
					case 9:
						say_file("time/sati.wav");
						break;
				}
			}
		} 

		minuta_jedinica = minutes % 10;
		
		if (minutes > 10)
			minuta_desetinka = (int) (minutes / 10);
			
		if (minutes) 
		{
			
			
			if (minuta_desetinka == 1)
			{
				say_num(minutes, SSM_PRONOUNCED, "");
				say_file("time/minuta.wav");
			}
			else
			{
				switch(minuta_jedinica)
				{
					case 2:
						say_num(minutes, SSM_PRONOUNCED, "je");
						say_file("time/minute.wav");
						break;
						
					case 3:
					case 4:
						say_num(minutes, SSM_PRONOUNCED, "");
						say_file("time/minute.wav");
						break;
					
					case 1:
							say_num(minutes, SSM_PRONOUNCED, "a");
							say_file("time/minuta.wav");
						break;
						
					case 0:
					case 5:
					case 6:
					case 7:
					case 8:
					case 9:
						say_num(minutes, SSM_PRONOUNCED, "");
						say_file("time/minuta.wav");
						break;
				}
			}
		} 

		sekunda_jedinica = seconds % 10;
		
		if (seconds > 10)
			sekunda_desetinka = (int) (seconds / 10);
			
		if (seconds) 
		{
			if (sekunda_desetinka == 1)
			{
				say_num(seconds, SSM_PRONOUNCED, "");
				say_file("time/sekundi.wav");
			}
			else if (sekunda_desetinka == 0)
			{
				switch(sekunda_jedinica)
				{
					case 1:
						say_num(seconds, SSM_PRONOUNCED, "a");
						say_file("time/sekunda.wav");
						break;
						
					case 2:
						say_num(seconds, SSM_PRONOUNCED, "je");
						say_file("time/sekunde.wav");
						break;
						
					case 3:
					case 4:
						say_num(seconds, SSM_PRONOUNCED, "");
						say_file("time/sekunde.wav");
						break;
						
					case 0:
					case 5:
					case 6:
					case 7:
					case 8:
					case 9:
						say_file("time/sekundi.wav");
						break;
				}
			}
			else
			{
				switch(sekunda_jedinica)
				{
					case 1:
						say_num(seconds, SSM_PRONOUNCED, "a");
						say_file("time/sekunda.wav");
						break;
						
					case 2:
						say_num(seconds, SSM_PRONOUNCED, "je");
						say_file("time/sekunde.wav");
						break;
						
					case 3:
					case 4:
						say_num(seconds, SSM_PRONOUNCED, "");
						say_file("time/sekunde.wav");
						break;
						
					case 0:
					case 5:
					case 6:
					case 7:
					case 8:
					case 9:
						say_num(seconds, SSM_PRONOUNCED, "");
						say_file("time/sekundi.wav");
						break;
				}
			}
		} 

		return SWITCH_STATUS_SUCCESS;
	}

	if ((t = atol(tosay)) > 0) {
		target = switch_time_make(t, 0);
		target_now = switch_micro_time_now();
	} else {
		target = switch_micro_time_now();
		target_now = switch_micro_time_now();
	}

	if (tz) {
		int check = atoi(tz);
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz);
		if (check) {
			switch_time_exp_tz(&tm, target, check);
			switch_time_exp_tz(&tm_now, target_now, check);
		} else {
			switch_time_exp_tz_name(tz, &tm, target);
			switch_time_exp_tz_name(tz, &tm_now, target_now);
		}
	} else {
		switch_time_exp_lt(&tm, target);
		switch_time_exp_lt(&tm_now, target_now);
	}

	switch (say_args->type) {
	case SST_CURRENT_DATE_TIME:
		say_date = say_time = 1;
		break;
	case SST_CURRENT_DATE:
		say_date = 1;
		break;
	case SST_CURRENT_TIME:
		say_time = 1;
		break;
	case SST_SHORT_DATE_TIME:
		say_time = 1;
		if (tm.tm_year != tm_now.tm_year) {
			say_date = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday) {
			say_today = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday - 1) {
			say_yesterday = 1;
			break;
		}
		if (tm.tm_yday >= tm_now.tm_yday - 5) {
			say_dow = 1;
			break;
		}
		if (tm.tm_mon != tm_now.tm_mon) {
			say_month = say_day = say_dow = 1;
			break;
		}

		say_month = say_day = say_dow = 1;

		break;
	default:
		break;
	}

	if (say_today) {
		say_file("time/today.wav");
	}
	if (say_yesterday) {
		say_file("time/yesterday.wav");
	}
	if (say_dow) {
		say_file("time/day-%d.wav", tm.tm_wday);
	}

	if (say_date) {
		say_year = say_month = say_day = say_dow = 1;
		say_today = say_yesterday = 0;
	}

	if (say_day) {
		say_num(tm.tm_mday, SSM_COUNTED, "");
	}
	
	if (say_month) {
		say_file("time/mon-%d.wav", tm.tm_mon);
	}
	
	if (say_year) {
		int y = tm.tm_year + 1900;
		int tis = 0;
		
		//say_num(tm.tm_year + 1900, SSM_PRONOUNCED, "");
		//1 - 99 => h-1a.wav - h-99a.wav
		if (y >= 1 && y <= 99)
		{
			say_file("digits/h-%da.wav", y);
		}
		// [1-9]00            =>     h-[1-9]00a.wav
		else if (y >= 100 && y <= 900 && y % 100 == 0)
		{
			say_file("digits/h-%da.wav", y);
		}
		//[1-9]01 - [1-9]99    =>     [1-9]00.wav  + (h-1a.wav - h-99a.wav)
		else if (y >= 100 && y <= 900 && y % 100 != 0)
		{
			say_file("digits/h-%da.wav", (int) y - (y % 100));
			say_file("digits/h-%da.wav", (int) y % 100);
		}
		// 1000 => thousand-ta.wav
		else if (y == 1000)
		{
			say_file("digits/thousand-ta.wav");
		}
		// 1001 - 1999 => thousand-u.wav + [1-9]00.wav + (h-1a.wav - h-99a.wav)
		else if (y >= 1001 && y <= 1999)
		{
			say_file("digits/thousand-u.wav");
			if (0 != (int) ((y - 1000) - ((y - 1000) % 100)))
				say_file("digits/h-%da.wav", (int) ((y - 1000) - ((y - 1000) % 100)));
				
			say_file("digits/h-%da.wav", (int) y % 100);
		}
		//2000  => 2je.wav + thousand-ta.wav
		else if (y == 2000)
		{
			say_file("digits/2je.wav");
			say_file("digits/thousand-ta.wav");
		}
		// 2001 - 2999 => 2je.wav + thousands-e.wav + [1-9]00.wav + (h-1a.wav - h-99a.wav)
		else if (y >= 2001 && y <= 2999)
		{
			say_file("digits/2je.wav");
			say_file("digits/thousands-e.wav");
			if (0 != (int) ((y - 2000) - ((y - 2000) % 100)))
				say_file("digits/h-%da.wav", (int) ((y - 2000) - ((y - 2000) % 100)));
				
			say_file("digits/h-%da.wav", (int) y % 100);
		}
		// 3000 => [3-9].wav + thousand-ta.wav
		else if (y >= 3000 && y <= 9000 && y % 1000 == 0)
		{
			say_file("digits/%d.wav", (int) (y / 1000));
			say_file("digits/thousand-ta.wav");
		}
		// [3-9]001 - [3-9]999 => [3-9].wav + thousands-e.wav + [1-9]00.wav + (h-1a.wav - h-99a.wav)
		else if (y >= 3000 && y <= 9000 && y % 1000 != 0)
		{
			say_file("digits/%d.wav", (int) (y / 1000));
			say_file("digits/thousands-e.wav");
			tis = y  - (y % 1000);
			if (0 != (int) ((y - tis) - ((y - tis) % 100)))
				say_file("digits/h-%da.wav",  (int) ((y - tis) - ((y - tis) % 100)));
				
			say_file("digits/h-%da.wav", (int) y % 100);
		}
		
		//say_num(tm.tm_year + 1900, SSM_COUNTED, "a");
	}

	
	if (say_time) 
	{
		say_num(tm.tm_hour, SSM_PRONOUNCED, "");
		
		sat_jedinica = tm.tm_hour % 10;
		
		if (tm.tm_hour >= 10)
			sat_desetinka = (int) (tm.tm_hour / 10);
			
	
		if (tm.tm_hour) 
		{
			if (sat_desetinka == 0 && sat_jedinica == 0)
			{
				nop;
			}
			else if (sat_desetinka == 1)
			{
				say_file("time/sati.wav");
			}
			else
			{
				switch(sat_jedinica)
				{
					case 1:
						say_file("time/sat.wav");
						break;
						
					case 2:
					case 3:
					case 4:
						say_file("time/sata.wav");
						break;
						
					case 0:
					case 5:
					case 6:
					case 7:
					case 8:
					case 9:
						say_file("time/sati.wav");
						break;
					
				}
			}
		} 
		
		minuta_jedinica = tm.tm_min % 10;
		
		if (tm.tm_min >= 10)
			minuta_desetinka = (int) (tm.tm_min / 10);
			
		if (tm.tm_min) 
		{
			if (minuta_desetinka == 1)
			{
				say_num(tm.tm_min, SSM_PRONOUNCED, "");
				say_file("time/minuta.wav");
			}
			else
			{
				switch(minuta_jedinica)
				{
					case 2:
						say_num(tm.tm_min, SSM_PRONOUNCED, "je");
						say_file("time/minute.wav");
						break;
						
					case 3:
					case 4:
						say_num(tm.tm_min, SSM_PRONOUNCED, "");
						say_file("time/minute.wav");
						break;
					
					case 1:
						say_num(tm.tm_min, SSM_PRONOUNCED, "a");
						say_file("time/minuta.wav");
						break;
						
					case 0:
					case 5:
					case 6:
					case 7:
					case 8:
					case 9:
						say_num(tm.tm_min, SSM_PRONOUNCED, "");
						say_file("time/minuta.wav");
						break;
				}
			}
		} 
		
		sekunda_jedinica = tm.tm_sec % 10;
		
		if (tm.tm_sec >= 10)
			sekunda_desetinka = (int) (tm.tm_sec / 10);
			
		if (tm.tm_sec) 
		{
			if (sekunda_desetinka == 1)
			{
				say_num(tm.tm_sec, SSM_PRONOUNCED, "");
				say_file("time/sekundi.wav");
			}
			else if (sekunda_desetinka == 0)
			{
				switch(sekunda_jedinica)
				{
					case 1:
						say_num(tm.tm_sec, SSM_PRONOUNCED, "a");
						say_file("time/sekunda.wav");
						break;
						
					case 2:
						say_num(tm.tm_sec, SSM_PRONOUNCED, "je");
						say_file("time/sekunde.wav");
						break;
						
					case 3:
					case 4:
						say_num(tm.tm_sec, SSM_PRONOUNCED, "");
						say_file("time/sekunde.wav");
						break;
						
					case 0:
					case 5:
					case 6:
					case 7:
					case 8:
					case 9:
						say_file("time/sekundi.wav");
						break;
				}
			}
			else
			{
				switch(sekunda_jedinica)
				{
					case 1:
						say_num(tm.tm_sec, SSM_PRONOUNCED, "a");
						say_file("time/sekunda.wav");
						break;
						
					case 2:
						say_num(tm.tm_sec, SSM_PRONOUNCED, "je");
						say_file("time/sekunde.wav");
						break;
						
					case 3:
					case 4:
						say_num(tm.tm_sec, SSM_PRONOUNCED, "");
						say_file("time/sekunde.wav");
						break;
						
					case 0:
					case 5:
					case 6:
					case 7:
					case 8:
					case 9:
						say_num(tm.tm_sec, SSM_PRONOUNCED, "");
						say_file("time/sekundi.wav");
						break;
				}
			}
		} 
	}

	return SWITCH_STATUS_SUCCESS;
}
static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle, switch_frame_t *frame, switch_video_read_flag_t flags)
{
	void *pop;
	local_stream_context_t *context = handle->private_info;
	switch_status_t status;
	switch_time_t now;

	if (!(context->ready && context->source->ready)) {
		return SWITCH_STATUS_FALSE;
	}

	if (!context->source->has_video) {
		if (frame) {
			switch_image_t *src_img = context->source->cover_art;

			if (!src_img) {
				src_img = context->source->blank_img;
			}

			if (src_img) {
				switch_image_t *img = NULL;
			
				if (context->sent_png && --context->sent_png > 0) {
					return SWITCH_STATUS_BREAK;
				}

				context->sent_png = 50;
				switch_img_copy(src_img, &img);

				if (context->last_w && context->last_h) {
					switch_img_fit(&img, context->last_w, context->last_h, SWITCH_FIT_SIZE);
				}

				frame->img = img;
				goto got_img;
			}
		}
		return SWITCH_STATUS_IGNORE;
	}

	if ((flags & SVR_CHECK)) {
		return SWITCH_STATUS_BREAK;
	}

	while(context->ready && context->source->ready && (flags & SVR_FLUSH) && switch_queue_size(context->video_q) > 1) {
		if (switch_queue_trypop(context->video_q, &pop) == SWITCH_STATUS_SUCCESS) {
			switch_image_t *img = (switch_image_t *) pop;
			switch_img_free(&img);
		}
	}

	if (!(context->ready && context->source->ready)) {
		return SWITCH_STATUS_FALSE;
	}
	
	if ((flags & SVR_BLOCK)) {
		status = switch_queue_pop(context->video_q, &pop);
	} else {
		status = switch_queue_trypop(context->video_q, &pop);
	}

	if (status == SWITCH_STATUS_SUCCESS) {
		if (!pop) {
			return SWITCH_STATUS_FALSE;
		}

		frame->img = (switch_image_t *) pop;
		context->sent_png = 0;
		context->last_w = frame->img->d_w;
		context->last_h = frame->img->d_h;
		goto got_img;
	}

	return (flags & SVR_FLUSH) ? SWITCH_STATUS_BREAK : status;

 got_img:

	if (context->pop_count > 0) {
		switch_rgb_color_t bgcolor = { 0 };
		switch_color_set_rgb(&bgcolor, "#000000");
		switch_img_fill(frame->img, 0, 0, frame->img->d_w, frame->img->d_h, &bgcolor);
		context->pop_count--;
	}
	
	now = switch_micro_time_now();

	if (context->banner_img) {
		if (now >= context->banner_timeout) {
			switch_img_free(&context->banner_img);
		}
	}

	if (context->serno != context->source->serno) {
		switch_img_free(&context->banner_img);
		context->banner_timeout = 0;
		context->serno = context->source->serno;
		context->pop_count = 5;
	}
	
	if (context->source->banner_txt) {
		if ((!context->banner_timeout || context->banner_timeout >= now)) {
			if (!context->banner_img) {
				context->banner_img = switch_img_write_text_img(context->last_w, context->last_h, SWITCH_TRUE, context->source->banner_txt);
				context->banner_timeout = now + 5000000;
			}
		}
	} else {
		if (context->banner_img) {
			switch_img_free(&context->banner_img);
		}
		context->banner_timeout = 0;
	}

	if (frame->img && context->banner_img && frame->img->d_w >= context->banner_img->d_w) {
		//switch_img_overlay(frame->img, context->banner_img, 0, frame->img->d_h - context->banner_img->d_h, 100);
		switch_img_patch(frame->img, context->banner_img, 0, frame->img->d_h - context->banner_img->d_h);
	}
	
	return SWITCH_STATUS_SUCCESS;
}
示例#15
0
static switch_bool_t stop_detect(pocketsphinx_t *ps, int16_t *data, unsigned int samples)
{
	uint32_t score, count = 0, j = 0;
	double energy = 0;

	if (ps->countdown) {
		if (!--ps->countdown) {
			ps->silence_hits = ps->org_silence_hits;
			ps->listening = 0;
			return SWITCH_TRUE;
		}
		return SWITCH_FALSE;
	}

	/* Do simple energy threshold for VAD */
	for (count = 0; count < samples; count++) {
		energy += abs(data[j]);
	}

	score = (uint32_t) (energy / samples);

	if (score >= ps->thresh) {
		if (++ps->listening == 1) {
			switch_mutex_lock(ps->flag_mutex);
			switch_set_flag(ps, PSFLAG_BARGE);
			switch_set_flag(ps, PSFLAG_START_OF_SPEECH);
			switch_mutex_unlock(ps->flag_mutex);
		}
		ps->silence_time = 0;
	} else if (!ps->silence_time) {
		ps->silence_time = switch_micro_time_now();
	}

	/* Check silence timeouts */
	if (ps->silence_time && switch_test_flag(ps, PSFLAG_INPUT_TIMERS)) {
		int elapsed_ms = (switch_micro_time_now() - ps->silence_time) / 1000;
		if (switch_test_flag(ps, PSFLAG_START_OF_SPEECH)) {
			if (ps->speech_timeout > 0 && !switch_test_flag(ps, PSFLAG_SPEECH_TIMEOUT) && elapsed_ms >= ps->speech_timeout) {
				switch_set_flag_locked(ps, PSFLAG_SPEECH_TIMEOUT);
				ps->listening = 0;
				return SWITCH_TRUE;
			}
		} else {
			if (ps->no_input_timeout > 0 && !switch_test_flag(ps, PSFLAG_NOINPUT_TIMEOUT) && elapsed_ms >= ps->no_input_timeout) {
				switch_mutex_lock(ps->flag_mutex);
				switch_set_flag(ps, PSFLAG_NOINPUT_TIMEOUT);
				switch_set_flag(ps, PSFLAG_NOINPUT);
				switch_mutex_unlock(ps->flag_mutex);
				ps->listening = 0;
				return SWITCH_TRUE;
			}
		}
	}

	if (ps->listening > ps->listen_hits && score < ps->thresh) {
		if (!--ps->silence_hits) {
			ps->countdown = 12;
		}
	} else {
		ps->silence_hits = ps->org_silence_hits;
	}

	return SWITCH_FALSE;
}
示例#16
0
static switch_status_t de_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
{
    int32_t t;
    switch_time_t target = 0;
    switch_time_exp_t tm;
    uint8_t say_date = 0, say_time = 0;

    if (say_args->type == SST_TIME_MEASUREMENT) {
        int64_t hours = 0;
        int64_t minutes = 0;
        int64_t seconds = 0;
        int64_t r = 0;

        if (strchr(tosay, ':')) {
            char *tme = switch_core_session_strdup(session, tosay);
            char *p;

            if ((p = strrchr(tme, ':'))) {
                *p++ = '\0';
                seconds = atoi(p);
                if ((p = strchr(tme, ':'))) {
                    *p++ = '\0';
                    minutes = atoi(p);
                    if (tme) {
                        hours = atoi(tme);
                    }
                } else {
                    minutes = atoi(tme);
                }
            }
        } else {
            if ((seconds = atoi(tosay)) <= 0) {
                seconds = (int64_t) switch_epoch_time_now(NULL);
            }

            if (seconds >= 60) {
                minutes = seconds / 60;
                r = seconds % 60;
                seconds = r;
            }

            if (minutes >= 60) {
                hours = minutes / 60;
                r = minutes % 60;
                minutes = r;
            }
        }

        if (hours) {
            say_num(hours, SSM_PRONOUNCED);
            if (hours == 1) {
                say_file("time/hour.wav");
            } else {
                say_file("time/hours.wav");
            }
        } else {
            say_file("digits/0.wav");
            say_file("time/hours.wav");
        }

        if (minutes) {
            say_num(minutes, SSM_PRONOUNCED);
            if (minutes == 1) {
                say_file("time/minute.wav");
            } else {
                say_file("time/minutes.wav");
            }
        } else {
            say_file("digits/0.wav");
            say_file("time/minutes.wav");
        }

        if (seconds) {
            say_num(seconds, SSM_PRONOUNCED);
            if (seconds == 1) {
                say_file("time/second.wav");
            } else {
                say_file("time/seconds.wav");
            }
        } else {
            say_file("digits/0.wav");
            say_file("time/seconds.wav");
        }

        return SWITCH_STATUS_SUCCESS;
    }

    if ((t = atoi(tosay)) > 0) {
        target = switch_time_make(t, 0);
    } else {
        target = switch_micro_time_now();
    }
    switch_time_exp_lt(&tm, target);

    switch (say_args->type) {
    case SST_CURRENT_DATE_TIME:
        say_date = say_time = 1;
        break;
    case SST_CURRENT_DATE:
        say_date = 1;
        break;
    case SST_CURRENT_TIME:
        say_time = 1;
        break;
    default:
        break;
    }

    if (say_date) {
        say_file("time/day-%d.wav", tm.tm_wday);
        say_file("time/mon-%d.wav", tm.tm_mon);
        say_num(tm.tm_mday, SSM_COUNTED);
        say_num(tm.tm_year + 1900, SSM_PRONOUNCED);
    }

    if (say_time) {
        int32_t hour = tm.tm_hour, pm = 0;

        if (hour > 12) {
            hour -= 12;
            pm = 1;
        } else if (hour == 12) {
            pm = 1;
        } else if (hour == 0) {
            hour = 12;
            pm = 0;
        }

        say_num(hour, SSM_PRONOUNCED);
        say_file("time/oclock.wav");

        if (tm.tm_min > 9) {
            say_num(tm.tm_min, SSM_PRONOUNCED);
        } else if (tm.tm_min) {
            say_file("time/oh.wav");
            say_num(tm.tm_min, SSM_PRONOUNCED);
        }

        say_file("time/%s.wav", pm ? "p-m" : "a-m");
    }

    return SWITCH_STATUS_SUCCESS;
}
示例#17
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;
}
示例#18
0
static switch_status_t pl_say_time(switch_say_file_handle_t *sh, char *tosay, switch_say_args_t *say_args)
{
	int32_t t;
	switch_time_t target = 0, target_now = 0;
	switch_time_exp_t tm, tm_now;
	uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0;
	const char *tz = NULL;

	tz = switch_say_file_handle_get_variable(sh, "timezone");

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "SAY: %s\n", tosay);

	if (say_args->type == SST_TIME_MEASUREMENT) {
		int64_t hours = 0;
		int64_t minutes = 0;
		int64_t seconds = 0;
		int64_t r = 0;

		if (strchr(tosay, ':')) {
			char *tme = strdup(tosay);
			char *p;

			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse time string!\n");
			if ((p = strrchr(tme, ':'))) {
				*p++ = '\0';
				seconds = atoi(p);
				if ((p = strchr(tme, ':'))) {
					*p++ = '\0';
					minutes = atoi(p);
					if (tme) {
						hours = atoi(tme);
					}
				} else {
					minutes = atoi(tme);
				}
			}
			free(tme);
		} else {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse time in seconds!\n");
			if ((seconds = atol(tosay)) <= 0) {
				seconds = (int64_t) switch_epoch_time_now(NULL);
			}

			if (seconds >= 60) {
				minutes = seconds / 60;
				r = seconds % 60;
				seconds = r;
			}

			if (minutes >= 60) {
				hours = minutes / 60;
				r = minutes % 60;
				minutes = r;
			}
		}

		if (hours) {
			int hd = 0, hj = 0;
			say_num(sh, hours, SSM_PRONOUNCED, SSG_FEMININE);
			hj = hours % 10;
			hd = (hours/10) % 10;
			if (hours == 1) {
				switch_say_file(sh, "time/t_godzina");
			}else if (hd != 1 && ( hj == 2 || hj == 3 || hj == 4)) {
				switch_say_file(sh, "time/t_godziny");
			} else {
				switch_say_file(sh, "time/t_godzin");
			}
		} else {
			switch_say_file(sh, "digits/0");
			switch_say_file(sh, "time/t_godzin");
		}

		if (minutes) {
			int md = 0, mj = 0;
			say_num(sh, minutes, SSM_PRONOUNCED, SSG_FEMININE);
			mj = minutes % 10;
			md = (minutes/10) % 10;
			if (minutes == 1) {
				switch_say_file(sh, "time/minuta");
			}else if (md != 1 && ( mj == 2 || mj == 3 || mj == 4)) {
				switch_say_file(sh, "time/t_minuty");
			} else {
				switch_say_file(sh, "time/t_minut");
			}
		} else {
			switch_say_file(sh, "digits/0");
			switch_say_file(sh, "time/t_minut");
		}

		if (seconds) {
			int sd = 0, sj = 0;
			say_num(sh, seconds, SSM_PRONOUNCED, SSG_FEMININE);
			sj = seconds % 10;
			sd = (seconds/10) % 10;
			if (seconds == 1) {
				switch_say_file(sh, "time/t_sekunda");
			}else if (sd != 1 && ( sj == 2 || sj == 3 || sj == 4)) {
				switch_say_file(sh, "time/t_sekundy");
			} else {
				switch_say_file(sh, "time/t_sekund");
			}
		} else {
			switch_say_file(sh, "digits/0");
			switch_say_file(sh, "time/t_sekund");
		}

		return SWITCH_STATUS_SUCCESS;
	}

	if ((t = atol(tosay)) > 0) {
			target = switch_time_make(t, 0);
			target_now = switch_micro_time_now();
	} else {
			target = switch_micro_time_now();
			target_now = switch_micro_time_now();
	}

 	if (tz) {
		int check = atoi(tz);
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Timezone is [%s]\n", tz);
		if (check) {
			switch_time_exp_tz(&tm, target, check);
			switch_time_exp_tz(&tm_now, target_now, check);
		} else {
			switch_time_exp_tz_name(tz, &tm, target);
			switch_time_exp_tz_name(tz, &tm_now, target_now);
		}
	} else {
		switch_time_exp_lt(&tm, target);
		switch_time_exp_lt(&tm_now, target_now);
	}

	switch (say_args->type) {
	case SST_CURRENT_DATE_TIME:
		say_date = say_time = 1;
		break;
	case SST_CURRENT_DATE:
		say_date = 1;
		break;
	case SST_CURRENT_TIME:
		say_time = 1;
		break;
	case SST_SHORT_DATE_TIME:
		say_time = 1;
		if (tm.tm_year != tm_now.tm_year) {
			say_date = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday) {
			say_today = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday - 1) {
			say_yesterday = 1;
			break;
		}
		if (tm.tm_yday >= tm_now.tm_yday - 5) {
			say_dow = 1;
			break;
		}
		if (tm.tm_mon != tm_now.tm_mon) {
			say_month = say_day = say_dow = 1;
			break;
		}

		say_month = say_day = say_dow = 1;

		break;
	default:
		break;
	}

	if (say_today) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: today\n");
		switch_say_file(sh, "time/t_dzisiaj");
	}
	if (say_yesterday) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: yesterday\n");
		switch_say_file(sh, "time/t_wczoraj");
	}
	if (say_dow) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: dow\n");
		switch_say_file(sh, "time/day-%d", tm.tm_wday);
	}

	if (say_date) {
		say_year = say_month = say_day = say_dow = 1;
		say_today = say_yesterday = 0;
	}

	if (say_day) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SAY: day\n");
		//say_num(sh, tm.tm_mday, SSM_COUNTED, SSG_MASCULINE);
		switch_say_file(sh, "digits/%02d_pm", tm.tm_mday);
	}
	if (say_month) {
		switch_say_file(sh, "time/mon-%d_D", tm.tm_mon);
	}
	if (say_year) {
		say_num(sh, tm.tm_year + 1900, SSM_COUNTED, SSG_MASCULINE);
		//switch_say_file(sh, "time/t_roku");
	}

	if (say_time) {
		switch_say_file(sh, "time/t_godzina");
		say_num(sh, tm.tm_hour, SSM_COUNTED, SSG_FEMININE);
		//switch_say_file(sh, "digits/%da", tm.tm_hour);

		say_num(sh, tm.tm_min, SSM_PRONOUNCED, SSG_FEMININE);
		/* switch_say_file(sh, "digits/t_minut");*/
	}

	return SWITCH_STATUS_SUCCESS;
}
示例#19
0
static switch_status_t fr_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
{
	int32_t t;
	switch_time_t target = 0, target_now = 0;
	switch_time_exp_t tm, tm_now;
	uint8_t say_date = 0, say_time = 0, say_year = 0, say_month = 0, say_dow = 0, say_day = 0, say_yesterday = 0, say_today = 0;
	switch_channel_t *channel = switch_core_session_get_channel(session);
	const char *tz = switch_channel_get_variable(channel, "timezone");

	if (say_args->type == SST_TIME_MEASUREMENT) {
		int64_t hours = 0;
		int64_t minutes = 0;
		int64_t seconds = 0;
		int64_t r = 0;

		if (strchr(tosay, ':')) {
			char *tme = switch_core_session_strdup(session, tosay);
			char *p;

			if ((p = strrchr(tme, ':'))) {
				*p++ = '\0';
				seconds = atoi(p);
				if ((p = strchr(tme, ':'))) {
					*p++ = '\0';
					minutes = atoi(p);
					if (tme) {
						hours = atoi(tme);
					}
				} else {
					minutes = atoi(tme);
				}
			}
		} else {
			if ((seconds = atol(tosay)) <= 0) {
				seconds = (int64_t) switch_epoch_time_now(NULL);
			}

			if (seconds >= 60) {
				minutes = seconds / 60;
				r = seconds % 60;
				seconds = r;
			}

			if (minutes >= 60) {
				hours = minutes / 60;
				r = minutes % 60;
				minutes = r;
			}
		}

		say_args->gender = SSG_FEMININE;

		if (hours) {
			say_num(hours, SSM_PRONOUNCED);
			say_file("time/hour.wav");
		} else {
			/* TODO MINUIT */
			say_file("digits/0.wav");
			say_file("time/hour.wav");
		}

		if (minutes) {
			say_num(minutes, SSM_PRONOUNCED);
			say_file("time/minute.wav");
		} else {
			/* TODO Aucune idee quoi faire jouer icit */
			say_file("digits/0.wav");
			say_file("time/minute.wav");
		}

		if (seconds) {
			say_num(seconds, SSM_PRONOUNCED);
			say_file("time/second.wav");
		} else {
			/* TODO Aucune idee quoi faire jouer icit */
			say_file("digits/0.wav");
			say_file("time/second.wav");
		}

		return SWITCH_STATUS_SUCCESS;
	}

	if ((t = atol(tosay)) > 0) {
		target = switch_time_make(t, 0);
		target_now = switch_micro_time_now();
	} else {
		target = switch_micro_time_now();
		target_now = switch_micro_time_now();
	}

	if (tz) {
		int check = atoi(tz);
		if (check) {
			switch_time_exp_tz(&tm, target, check);
			switch_time_exp_tz(&tm_now, target_now, check);
		} else {
			switch_time_exp_tz_name(tz, &tm, target);
			switch_time_exp_tz_name(tz, &tm_now, target_now);
		}
	} else {
		switch_time_exp_lt(&tm, target);
		switch_time_exp_lt(&tm_now, target_now);
	}

	switch (say_args->type) {
	case SST_CURRENT_DATE_TIME:
		say_date = say_time = 1;
		break;
	case SST_CURRENT_DATE:
		say_date = 1;
		break;
	case SST_CURRENT_TIME:
		say_time = 1;
		break;
	case SST_SHORT_DATE_TIME:
		say_time = 1;
		if (tm.tm_year != tm_now.tm_year) {
			say_date = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday) {
			say_today = 1;
			break;
		}
		if (tm.tm_yday == tm_now.tm_yday - 1) {
			say_yesterday = 1;
			break;
		}
		if (tm.tm_yday >= tm_now.tm_yday - 5) {
			say_dow = 1;
			break;
		}
		if (tm.tm_mon != tm_now.tm_mon) {
			say_month = say_day = say_dow = 1;
			break;
		}

		say_month = say_day = say_dow = 1;

		break;

	default:
		break;
	}

	if (say_today) {
		say_file("time/today.wav");
	}
	if (say_yesterday) {
		say_file("time/yesterday.wav");
	}
	if (say_dow) {
		say_file("time/day-%d.wav", tm.tm_wday);
	}

	if (say_date) {
		say_year = say_month = say_day = say_dow = 1;
		say_today = say_yesterday = 0;
	}

        if (say_day) {
		if (tm.tm_mday == 1) { /* 1 er Janvier,... 2 feb, 23 dec... */
			say_args->gender = SSG_MASCULINE;
	                say_num(tm.tm_mday, SSM_COUNTED);
		} else {
			say_args->gender = SSG_FEMININE;
			say_num(tm.tm_mday, SSM_PRONOUNCED);
		}
        }
	if (say_month) {
		say_file("time/mon-%d.wav", tm.tm_mon);
	}
	if (say_year) {
		say_args->gender = SSG_MASCULINE;
		say_num(tm.tm_year + 1900, SSM_PRONOUNCED);
	}

	if (say_time) {
		if (say_date || say_today || say_yesterday || say_dow) {
			say_file("time/at.wav");
		}
		say_args->gender = SSG_FEMININE;
		say_num(tm.tm_hour, SSM_PRONOUNCED);

		say_file("time/hour.wav");

		if (tm.tm_min) {
			say_num(tm.tm_min, SSM_PRONOUNCED);
		}

	}

	return SWITCH_STATUS_SUCCESS;
}
示例#20
0
static switch_status_t th_say_time(switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
{
	int32_t t;
	switch_time_t target = 0;
	switch_time_exp_t tm;
#if 0
	switch_time_t this_morning;
	switch_time_exp_t tm2;
#endif
	uint8_t say_date = 0;
	uint8_t say_time = 0;

	if (say_args->type == SST_TIME_MEASUREMENT) {
		int64_t hours = 0;
		int64_t minutes = 0;
		int64_t seconds = 0;
		int64_t r = 0;

		if (strchr(tosay, ':')) {
			char *tme = switch_core_session_strdup(session, tosay);
			char *p;

			if ((p = strrchr(tme, ':'))) {
				*p++ = '\0';
				seconds = atoi(p);
				if ((p = strchr(tme, ':'))) {
					*p++ = '\0';
					minutes = atoi(p);
					if (tme) {
						hours = atoi(tme);
					}
				} else {
					minutes = atoi(tme);
				}
			}
		} else {
			if ((seconds = atoi(tosay)) <= 0) {
				seconds = (int64_t) switch_epoch_time_now(NULL);
			}

			if (seconds >= 60) {
				minutes = seconds / 60;
				r = seconds % 60;
				seconds = r;
			}

			if (minutes >= 60) {
				hours = minutes / 60;
				r = minutes % 60;
				minutes = r;
			}
		}

		if (hours) {
			if (hours == 2) {
				say_file("time/2s.wav");
			} else {
				say_num(hours, SSM_PRONOUNCED);
			}
			say_file("time/hours.wav");
		}
		if (minutes) {
			if (minutes == 2) {
				say_file("time/2s.wav");
			} else {
				say_num(minutes, SSM_PRONOUNCED);
			}
			say_file("time/minute.wav");
		} else {
			if (hours) {
				say_file("digits/0.wav");
				say_file("time/minute.wav");
			}
		}

		if (seconds) {
			if (seconds == 2) {
				say_file("time/2s.wav");
			} else {
				say_num(hours, SSM_PRONOUNCED);
			}
			say_file("time/seconds.wav");
		} else {
			if (hours || minutes) {
				say_file("digits/0.wav");
				say_file("time/second.wav");
			}
		}

		return SWITCH_STATUS_SUCCESS;
	}

	if ((t = atoi(tosay)) > 0)
		target = switch_time_make(t, 0);
	else
		target = switch_micro_time_now();
	switch_time_exp_lt(&tm, target);

	switch (say_args->type) {
	case SST_CURRENT_DATE_TIME:
		say_date = say_time = 1;
		break;
	case SST_CURRENT_DATE:
		say_date = 1;
		break;
	case SST_CURRENT_TIME:
		say_time = 1;
		break;
	default:
		break;
	}

	if (say_date) {
		say_num(tm.tm_year + 1900, SSM_ITERATED);
		say_file("time/year.wav");
		say_num(tm.tm_mon + 1, SSM_PRONOUNCED);
		say_file("time/month.wav");
		say_num(tm.tm_mday, SSM_PRONOUNCED);
		say_file("time/day.wav");
		say_file("time/day-%d.wav", tm.tm_wday);

#if 0
		tm = *localtime(&then);

		this_morning = switch_micro_time_now();
		switch_time_exp_lt(&tm2, this_morning);
		tm2->tm_hour = 0;
		tm2->tm_min = 0;
		tm2->tm_sec = 0;
		this_morning = mktime(tm2);

		if (this_morning <= then && then < (this_morning + 86400L)) {
			say_file("time/today.wav");
		} else if ((this_morning - 86400L) <= then && then < this_morning) {
			say_file("time/yesterday.wav");
		} else if ((this_morning + 86400L) <= then && then < (this_morning + 2 * 86400L)) {
			say_file("time/tomorrow.wav");
		} else if ((this_morning - 7 * 86400L) <= then && then < this_morning) {
			say_file("time/day-%d.wav", tm.tm_wday);
		} else {
			if (tm2->tm_year != tm.tm_year) {
				say_num(tm.tm_year + 1900, SSM_ITERATED);
				say_file("time/year.wav");
			}
			/*endif */
			if (tm2->tm_year != tm.tm_year || tm2->tm_mon != tm.tm_mon) {
				say_num(tm.tm_mon + 1, SSM_PRONOUNCED);
				say_file("time/month.wav");
			}
			/*endif */
			/* Always say the day and the day of the week */
			say_num(tm.tm_mday, SSM_PRONOUNCED);
			say_file("time/day.wav");
			say_file("time/day-%d.wav", tm.tm_wday);
		}
#endif
	}

	if (say_time) {
		int32_t hour = tm.tm_hour;

		if (hour < 6) {
			say_file("time/morning.wav");
		} else if (hour < 12) {
			say_file("time/am.wav");
		} else if (tm.tm_hour < 18) {
			say_file("time/pm.wav");
		} else {
			say_file("time/evening.wav");
		}
		if (hour > 12)
			hour -= 12;
		if (hour == 0)
			hour = 12;

		if (hour == 2) {
			say_file("time/2s.wav");
		} else {
			say_num(hour, SSM_PRONOUNCED);
		}
		say_file("time/hour.wav");
		if (tm.tm_min == 2) {
			say_file("time/2s.wav");
		} else {
			say_num(tm.tm_min, SSM_PRONOUNCED);
		}
		say_file("time/minute.wav");
	}
	return SWITCH_STATUS_SUCCESS;
}
/**
 * Start recording call
 * @param session the session to record
 * @param record the record component
 */
static int start_call_record(switch_core_session_t *session, struct rayo_component *component)
{
	struct record_component *record_component = RECORD_COMPONENT(component);
	switch_channel_t *channel = switch_core_session_get_channel(session);
	int max_duration_sec = 0;

	switch_channel_set_variable(channel, "RECORD_HANGUP_ON_ERROR", "false");
	switch_channel_set_variable(channel, "RECORD_TOGGLE_ON_REPEAT", "");
	switch_channel_set_variable(channel, "RECORD_CHECK_BRIDGE", "");
	switch_channel_set_variable(channel, "RECORD_MIN_SEC", "0");
	switch_channel_set_variable(channel, "RECORD_STEREO", "");
	switch_channel_set_variable(channel, "RECORD_READ_ONLY", "");
	switch_channel_set_variable(channel, "RECORD_WRITE_ONLY", "");
	switch_channel_set_variable(channel, "RECORD_APPEND", "");
	switch_channel_set_variable(channel, "RECORD_WRITE_OVER", "true");
	switch_channel_set_variable(channel, "RECORD_ANSWER_REQ", "");
	switch_channel_set_variable(channel, "RECORD_SILENCE_THRESHOLD", "200");
	if (record_component->initial_timeout > 0) {
		switch_channel_set_variable_printf(channel, "RECORD_INITIAL_TIMEOUT_MS", "%i", record_component->initial_timeout);
	} else {
		switch_channel_set_variable(channel, "RECORD_INITIAL_TIMEOUT_MS", "");
	}
	if (record_component->final_timeout > 0) {
		switch_channel_set_variable_printf(channel, "RECORD_FINAL_TIMEOUT_MS", "%i", record_component->final_timeout);
	} else {
		switch_channel_set_variable(channel, "RECORD_FINAL_TIMEOUT_MS", "");
	}
	/* allow dialplan override for these variables */
	//switch_channel_set_variable(channel, "RECORD_PRE_BUFFER_FRAMES", "");
	//switch_channel_set_variable(channel, "record_sample_rate", "");
	//switch_channel_set_variable(channel, "enable_file_write_buffering", "");

	/* max duration attribute is in milliseconds- convert to seconds */
	if (record_component->max_duration > 0) {
		max_duration_sec = ceil((double)(record_component->max_duration - record_component->duration_ms) / 1000.0);
	}

	if (!strcmp(record_component->direction, "duplex")) {
		if (!record_component->mix) {
			/* STEREO */
			switch_channel_set_variable(channel, "RECORD_STEREO", "true");
		} /* else MONO (default) */
	} else if (!strcmp(record_component->direction, "send")) {
		/* record audio sent from the caller */
		switch_channel_set_variable(channel, "RECORD_READ_ONLY", "true");
	} else if (!strcmp(record_component->direction, "recv")) {
		/* record audio received by the caller */
		switch_channel_set_variable(channel, "RECORD_WRITE_ONLY", "true");
	};

	if (record_component->start_beep) {
		switch_ivr_displace_session(session, RECORD_BEEP, 0, "");
		record_component->start_time = switch_micro_time_now();
	}

	if (switch_ivr_record_session(session, (char *)RAYO_ID(component), max_duration_sec, NULL) == SWITCH_STATUS_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Recording started: file = %s\n", RAYO_ID(component));
		return 1;
	}

	return 0;
}
示例#22
0
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsql_handle_t *handle, switch_pgsql_result_t **result_out, int msec)
{
#ifdef SWITCH_HAVE_PGSQL
	switch_pgsql_result_t *res;
	switch_time_t start;
	switch_time_t ctime;
	unsigned int usec = msec * 1000;
	char *err_str;
	struct pollfd fds[2] = { {0} };
	int poll_res = 0;
	
	if(!handle) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "**BUG** Null handle passed to switch_pgsql_next_result.\n");
		return SWITCH_PGSQL_FAIL;
	}

	/* Try to consume input that might be waiting right away */
	if (PQconsumeInput(handle->con)) {
		/* And check to see if we have a full result ready for reading */
		if (PQisBusy(handle->con)) {

			/* Wait for a result to become available, up to msec milliseconds */
			start = switch_time_now();
			while((ctime = switch_micro_time_now()) - start <= usec) {
				int wait_time = (usec - (ctime - start)) / 1000;
				fds[0].fd = handle->sock;
				fds[0].events |= POLLIN;
				fds[0].events |= POLLERR;

				/* Wait for the PostgreSQL socket to be ready for data reads. */
				if ((poll_res = poll(&fds[0], 1, wait_time)) > -1 ) {
					if (fds[0].revents & POLLIN) {
						/* Then try to consume any input waiting. */
						if (PQconsumeInput(handle->con)) {
							/* And check to see if we have a full result ready for reading */
							if (!PQisBusy(handle->con)) {
								/* If we can pull a full result without blocking, then break this loop */
								break;
							}
						} else {
							/* If we had an error trying to consume input, report it and cancel the query. */
							err_str = switch_pgsql_handle_get_error(handle);
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
							switch_safe_free(err_str);
							switch_pgsql_cancel(handle);
							goto error;
						}
					} else if (fds[0].revents & POLLERR) {
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql);
						goto error;
					}
				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql);
					goto error;
				}
			}

			/* If we broke the loop above because of a timeout, report that and cancel the query. */
			if (ctime - start > usec) {
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql);
				switch_pgsql_cancel(handle);
				goto error;
			}



		}
	} else {
		/* If we had an error trying to consume input, report it and cancel the query. */
		err_str = switch_pgsql_handle_get_error(handle);
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
		switch_safe_free(err_str);
		switch_pgsql_cancel(handle);
		goto error;
	}


	/* At this point, we know we can read a full result without blocking. */
	if(!(res = malloc(sizeof(switch_pgsql_result_t)))) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Malloc failed!\n");
		goto error;
	}
	memset(res, 0, sizeof(switch_pgsql_result_t));

	
	res->result = PQgetResult(handle->con);
	if (res->result) {
		*result_out = res;
		res->status = PQresultStatus(res->result);
		switch(res->status) {
		case PGRES_TUPLES_OK:
			{
				res->rows = PQntuples(res->result);
				handle->affected_rows = res->rows;
				res->cols = PQnfields(res->result);
			}
			break;
		case PGRES_COPY_OUT:
		case PGRES_COPY_IN:
		case PGRES_COMMAND_OK:
			break;
		case PGRES_EMPTY_QUERY:
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_EMPTY_QUERY\n", handle->sql);
		case PGRES_BAD_RESPONSE:
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_BAD_RESPONSE\n", handle->sql);
		case PGRES_NONFATAL_ERROR:
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_NONFATAL_ERROR\n", handle->sql);
		case PGRES_FATAL_ERROR:
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_FATAL_ERROR\n", handle->sql);
			res->err = PQresultErrorMessage(res->result);
			goto error;
			break;
		}
	} else {
		free(res);
		res = NULL;
		*result_out = NULL;
		goto error;
	}

	return SWITCH_PGSQL_SUCCESS;
 error:
#endif
	return SWITCH_PGSQL_FAIL;
}
static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec_t *other_codec,	/* codec that was used by the other side */
										  void *decoded_data,	/* decoded data that we must encode */
										  uint32_t decoded_data_len /* decoded data length */ ,
										  uint32_t decoded_rate /* rate of the decoded data */ ,
										  void *encoded_data,	/* here we will store the encoded data */
										  uint32_t *encoded_data_len,	/* here we will set the length of the encoded data */
										  uint32_t *encoded_rate /* here we will set the rate of the encoded data */ ,
										  unsigned int *flag /* frame flag, see switch_frame_flag_enum_t */ )
{
	/* FS core checks the actual samples per second and microseconds per packet to determine the buffer size in the worst case scenario, no need to check
	 * whether the buffer passed in by the core (encoded_data) will be big enough */
	switch_frame_t ulaw_frame;
	switch_frame_t encoded_frame;
	switch_status_t sres;
	switch_time_t now_time, difftime;
	unsigned char ebuf_ulaw[decoded_data_len / 2];
	short *dbuf_linear;
	int i = 0;
	int res = 0;
	struct sangoma_transcoding_session *sess = codec->private_info;

	/* start assuming we will not encode anything */
	*encoded_data_len = 0;

	/* initialize on first use */
	if (!sess->encoder.txrtp) {
		int err = 0;
		switch_mutex_lock(g_sessions_lock);
		err = sngtc_create_transcoding_session(&sess->encoder.request, &sess->encoder.reply, 0);
		if (err) {
			memset(&sess->encoder, 0, sizeof(sess->encoder));
			switch_mutex_unlock(g_sessions_lock);
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create Sangoma encoding session.\n");
			return SWITCH_STATUS_FALSE;
		}
		sess->encoder.txrtp = sess->encoder.reply.tx_fd;
		sess->encoder.rxrtp = sess->encoder.reply.rx_fd;
		switch_mutex_unlock(g_sessions_lock);
	}

	/* transcode to ulaw first */
	dbuf_linear = decoded_data;

	for (i = 0; i < decoded_data_len / sizeof(short); i++) {
		ebuf_ulaw[i] = linear_to_ulaw(dbuf_linear[i]);
	}
	
	/* do the writing */
	memset(&ulaw_frame, 0, sizeof(ulaw_frame));	
	ulaw_frame.source = __FUNCTION__;
	ulaw_frame.data = ebuf_ulaw;
	ulaw_frame.datalen = i;
	ulaw_frame.payload = IANA_ULAW;

	res = switch_rtp_write_frame(sess->encoder.txrtp, &ulaw_frame);
	if (-1 == res) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to write to Sangoma encoder RTP session.\n");
		return SWITCH_STATUS_FALSE;
	}

	if (res < i) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, 
				"Requested to write %d bytes to Sangoma encoder RTP session, but wrote %d bytes.\n", i, res);
		return SWITCH_STATUS_FALSE;
	}
	sess->encoder.tx++;

	/* do the reading */
	for ( ; ; ) {
		sres = switch_rtp_zerocopy_read_frame(sess->encoder.rxrtp, &encoded_frame, SWITCH_IO_FLAG_NOBLOCK);
		if (sres == SWITCH_STATUS_GENERR) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to read on Sangoma encoder RTP session: %d\n", sres);
			return SWITCH_STATUS_FALSE;
		}

		if (0 == encoded_frame.datalen) {
			break;
		}

		if (encoded_frame.payload != codec->implementation->ianacode
		    && encoded_frame.payload != IANACODE_CN) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Read unexpected payload %d in Sangoma encoder RTP session, expecting %d\n",
					encoded_frame.payload, codec->implementation->ianacode);
			break;
		}

		if (*encoded_data_len) {
			sess->encoder.rxdiscarded++;
		}

		memcpy(encoded_data, encoded_frame.data, encoded_frame.datalen);
		*encoded_data_len = encoded_frame.datalen;
	}

	/* update encoding stats */
	sess->encoder.rx++;

	now_time = switch_micro_time_now();
	if (!sess->encoder.last_rx_time) {
		sess->encoder.last_rx_time = now_time;
	} else {
		difftime = now_time - sess->encoder.last_rx_time;
		sess->encoder.avgrxus = sess->encoder.avgrxus ? ((sess->encoder.avgrxus + difftime)/2) : difftime;
		sess->encoder.last_rx_time  = now_time;
	}

	/* check sequence and bump lost rx packets count if needed */
	if (sess->encoder.lastrxseqno >= 0) {
		if (encoded_frame.seq > (sess->encoder.lastrxseqno + 2) ) {
			sess->encoder.rxlost += encoded_frame.seq - sess->encoder.lastrxseqno - 1;
		}
	}
	sess->encoder.lastrxseqno = encoded_frame.seq;

	return SWITCH_STATUS_SUCCESS;
}
示例#24
0
/* we have to do this as a string because swig and languages can't find an embedded way to pass a big int */
SWITCH_DECLARE(char *) API::getTime(void)
{
	switch_time_t now = switch_micro_time_now() / 1000;
	snprintf(time_buf, sizeof(time_buf), "%" SWITCH_TIME_T_FMT, now);
	return time_buf;
}
SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_request_port(switch_core_port_allocator_t *alloc, switch_port_t *port_ptr)
{
	switch_port_t port = 0;
	switch_status_t status = SWITCH_STATUS_FALSE;
	int even = switch_test_flag(alloc, SPF_EVEN);
	int odd = switch_test_flag(alloc, SPF_ODD);

	switch_mutex_lock(alloc->mutex);
	srand((unsigned) ((unsigned) (intptr_t) port_ptr + (unsigned) (intptr_t) switch_thread_self() + switch_micro_time_now()));

	while (alloc->track_used < alloc->track_len) {
		uint32_t index;
		uint32_t tries = 0;

		/* randomly pick a port */
		index = rand() % alloc->track_len;

		/* if it is used walk up the list to find a free one */
		while (alloc->track[index] && tries < alloc->track_len) {
			tries++;
			if (alloc->track[index] < 0) {
				alloc->track[index]++;
			}
			if (++index >= alloc->track_len) {
				index = 0;
			}
		}

		if (tries < alloc->track_len) {
			alloc->track[index] = 1;
			alloc->track_used++;
			status = SWITCH_STATUS_SUCCESS;

			if ((even && odd)) {
				port = (switch_port_t) (index + alloc->start);
			} else {
				port = (switch_port_t) (index + (alloc->start / 2));
				port *= 2;
			}
			goto end;
		}
	}


  end:

	switch_mutex_unlock(alloc->mutex);

	if (status == SWITCH_STATUS_SUCCESS) {
		*port_ptr = port;
	} else {
		*port_ptr = 0;
	}


	return status;

}
示例#26
0
SWITCH_DECLARE(void) switch_log_vprintf(switch_text_channel_t channel, const char *file, const char *func, int line,
										const char *userdata, switch_log_level_t level, const char *fmt, va_list ap)
{
	char *data = NULL;
	char *new_fmt = NULL;
	int ret = 0;
	FILE *handle;
	const char *filep = (file ? switch_cut_path(file) : "");
	const char *funcp = (func ? func : "");
	char *content = NULL;
	switch_time_t now = switch_micro_time_now();
	uint32_t len;
#ifdef SWITCH_FUNC_IN_LOG
	const char *extra_fmt = "%s [%s] %s:%d %s()%c%s";
#else
	const char *extra_fmt = "%s [%s] %s:%d%c%s";
#endif
	switch_log_level_t limit_level = runtime.hard_log_level;

	if (channel == SWITCH_CHANNEL_ID_SESSION && userdata) {
		switch_core_session_t *session = (switch_core_session_t *) userdata;
		if (limit_level < session->loglevel) {
			limit_level = session->loglevel;
		}
	}

	if (level > 100) {
		if ((uint32_t) (level - 100) > runtime.debug_level) {
			return;
		}

		level = 7;
	}

	if (level > limit_level) {
		return;
	}

	switch_assert(level < SWITCH_LOG_INVALID);

	handle = switch_core_data_channel(channel);

	if (channel != SWITCH_CHANNEL_ID_LOG_CLEAN) {
		char date[80] = "";
		//switch_size_t retsize;
		switch_time_exp_t tm;

		switch_time_exp_lt(&tm, now);
		switch_snprintf(date, sizeof(date), "%0.4d-%0.2d-%0.2d %0.2d:%0.2d:%0.2d.%0.6d",
						tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec);

		//switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);

#ifdef SWITCH_FUNC_IN_LOG
		len = (uint32_t) (strlen(extra_fmt) + strlen(date) + strlen(filep) + 32 + strlen(funcp) + strlen(fmt));
#else
		len = (uint32_t) (strlen(extra_fmt) + strlen(date) + strlen(filep) + 32 + strlen(fmt));
#endif
		new_fmt = malloc(len + 1);
		switch_assert(new_fmt);
#ifdef SWITCH_FUNC_IN_LOG
		switch_snprintf(new_fmt, len, extra_fmt, date, switch_log_level2str(level), filep, line, funcp, 128, fmt);
#else
		switch_snprintf(new_fmt, len, extra_fmt, date, switch_log_level2str(level), filep, line, 128, fmt);
#endif

		fmt = new_fmt;
	}

	ret = switch_vasprintf(&data, fmt, ap);

	if (ret == -1) {
		fprintf(stderr, "Memory Error\n");
		goto end;
	}

	if (channel == SWITCH_CHANNEL_ID_LOG_CLEAN) {
		content = data;
	} else {
		if ((content = strchr(data, 128))) {
			*content = ' ';
		}
	}

	if (channel == SWITCH_CHANNEL_ID_EVENT) {
		switch_event_t *event;
		if (switch_event_running() == SWITCH_STATUS_SUCCESS && switch_event_create(&event, SWITCH_EVENT_LOG) == SWITCH_STATUS_SUCCESS) {
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Log-Data", data);
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Log-File", filep);
			switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Log-Function", funcp);
			switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Line", "%d", line);
			switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Level", "%d", (int) level);
			if (!zstr(userdata)) {
				switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "User-Data", userdata);
			}
			switch_event_fire(&event);
			data = NULL;
		}

		goto end;
	}

	if (console_mods_loaded == 0 || !do_mods) {
		if (handle) {
			int aok = 1;
#ifndef WIN32

			fd_set can_write;
			int fd;
			struct timeval to;

			fd = fileno(handle);
			memset(&to, 0, sizeof(to));
			FD_ZERO(&can_write);
			FD_SET(fd, &can_write);
			to.tv_sec = 0;
			to.tv_usec = 100000;
			if (select(fd + 1, NULL, &can_write, NULL, &to) > 0) {
				aok = FD_ISSET(fd, &can_write);
			} else {
				aok = 0;
			}
#endif
			if (aok) {
				if (COLORIZE) {

#ifdef WIN32
					SetConsoleTextAttribute(hStdout, COLORS[level]);
					WriteFile(hStdout, data, (DWORD) strlen(data), NULL, NULL);
					SetConsoleTextAttribute(hStdout, wOldColorAttrs);
#else
					fprintf(handle, "%s%s%s", COLORS[level], data, SWITCH_SEQ_DEFAULT_COLOR);
#endif
				} else {
					fprintf(handle, "%s", data);
				}
			}
		}
	}

	if (do_mods && level <= MAX_LEVEL) {
		switch_log_node_t *node = switch_log_node_alloc();

		node->data = data;
		data = NULL;
		switch_set_string(node->file, filep);
		switch_set_string(node->func, funcp);
		node->line = line;
		node->level = level;
		node->content = content;
		node->timestamp = now;
		node->channel = channel;
		if (channel == SWITCH_CHANNEL_ID_SESSION) {
			node->userdata = userdata ? strdup(switch_core_session_get_uuid((switch_core_session_t *) userdata)) : NULL;
		} else {
			node->userdata = !zstr(userdata) ? strdup(userdata) : NULL;
		}

		if (switch_queue_trypush(LOG_QUEUE, node) != SWITCH_STATUS_SUCCESS) {
			switch_log_node_free(&node);
		}
	}

  end:

	switch_safe_free(data);
	switch_safe_free(new_fmt);

}
示例#27
0
/* This is where we actually charge the guy 
  This can be called anytime a call is in progress or at the end of a call before the session is destroyed */
static switch_status_t do_billing(switch_core_session_t *session)
{
	/* FS vars we will use */
	switch_channel_t *channel;
	switch_caller_profile_t *profile;

	/* Local vars */
	nibble_data_t *nibble_data;
	switch_time_t ts = switch_micro_time_now();
	double billamount;
	char date[80] = "";
	char *uuid;
	switch_size_t retsize;
	switch_time_exp_t tm;
	const char *billrate;
	const char *billincrement;
	const char *billaccount;
	double nobal_amt = globals.nobal_amt;
	double lowbal_amt = globals.lowbal_amt;
	double balance;

	if (!session) {
		/* Why are we here? */
		return SWITCH_STATUS_SUCCESS;
	}

	uuid = switch_core_session_get_uuid(session);

	/* Get channel var */
	if (!(channel = switch_core_session_get_channel(session))) {
		return SWITCH_STATUS_SUCCESS;
	}

	/* Variables kept in FS but relevant only to this module */
	billrate = switch_channel_get_variable(channel, "nibble_rate");
	billincrement = switch_channel_get_variable(channel, "nibble_increment");
	billaccount = switch_channel_get_variable(channel, "nibble_account");
	
	if (!zstr(switch_channel_get_variable(channel, "nobal_amt"))) {
		nobal_amt = atof(switch_channel_get_variable(channel, "nobal_amt"));
	}
	
	if (!zstr(switch_channel_get_variable(channel, "lowbal_amt"))) {
		lowbal_amt = atof(switch_channel_get_variable(channel, "lowbal_amt"));
	}
	
	/* Return if there's no billing information on this session */
	if (!billrate || !billaccount) {
		return SWITCH_STATUS_SUCCESS;
	}

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Attempting to bill at $%s per minute to account %s\n", billrate,
					  billaccount);

	/* Get caller profile info from channel */
	profile = switch_channel_get_caller_profile(channel);

	if (!profile || !profile->times) {
		/* No caller profile (why would this happen?) */
		return SWITCH_STATUS_SUCCESS;
	}

	if (profile->times->answered < 1) {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Not billing %s - call is not in answered state\n", billaccount);

		/* See if this person has enough money left to continue the call */
		balance = get_balance(billaccount, channel);
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Comparing %f to hangup balance of %f\n", balance, nobal_amt);
		if (balance <= nobal_amt) {
			/* Not enough money - reroute call to nobal location */
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below allowed amount of %f! (Account %s)\n",
							  balance, nobal_amt, billaccount);

			transfer_call(session, globals.nobal_action);
		}

		return SWITCH_STATUS_SUCCESS;
	}

	/* Lock this session's data for this module while we tinker with it */
	if (globals.mutex) {
		switch_mutex_lock(globals.mutex);
	}

	/* Get our nibble data var. This will be NULL if it's our first call here for this session */
	nibble_data = (nibble_data_t *) switch_channel_get_private(channel, "_nibble_data_");

	/* Are we in paused mode? If so, we don't do anything here - go back! */
	if (nibble_data && (nibble_data->pausets > 0)) {
		if (globals.mutex) {
			switch_mutex_unlock(globals.mutex);
		}
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Received heartbeat, but we're paused - ignoring\n");
		return SWITCH_STATUS_SUCCESS;
	}

	/* Have we done any billing on this channel yet? If no, set up vars for doing so */
	if (!nibble_data) {
		nibble_data = switch_core_session_alloc(session, sizeof(*nibble_data));
		memset(nibble_data, 0, sizeof(*nibble_data));

		/* Setup new billing data (based on call answer time, in case this module started late with active calls) */
		nibble_data->lastts = profile->times->answered;	/* Set the initial answer time to match when the call was really answered */
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Beginning new billing on %s\n", uuid);
	}

	switch_time_exp_lt(&tm, nibble_data->lastts);
	switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);

	switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%d seconds passed since last bill time of %s\n",
					  (int) ((ts - nibble_data->lastts) / 1000000), date);

	if ((ts - nibble_data->lastts) >= 0) {
		/* If billincrement is set we bill by it and not by time elapsed */
		if (!(switch_strlen_zero(billincrement))) {
			switch_time_t chargedunits = (ts - nibble_data->lastts) / 1000000 <= atol(billincrement) ? atol(billincrement) * 1000000 : (switch_time_t)(ceil((ts - nibble_data->lastts) / (atol(billincrement) * 1000000.0))) * atol(billincrement) * 1000000;
			billamount = (atof(billrate) / 1000000 / 60) * chargedunits - nibble_data->bill_adjustments;
			/* Account for the prepaid amount */
			nibble_data->lastts += chargedunits;
		} else {		
			/* Convert billrate into microseconds and multiply by # of microseconds that have passed since last *successful* bill */
			billamount = (atof(billrate) / 1000000 / 60) * ((ts - nibble_data->lastts)) - nibble_data->bill_adjustments;
			/* Update the last time we billed */
			nibble_data->lastts = ts;
		}

		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Billing $%f to %s (Call: %s / %f so far)\n", billamount, billaccount,
						  uuid, nibble_data->total);

		/* DO ODBC BILLING HERE and reset counters if it's successful! */
		if (bill_event(billamount, billaccount, channel) == SWITCH_STATUS_SUCCESS) {
			/* Increment total cost */
			nibble_data->total += billamount;

			/* Reset manual billing adjustments from pausing */
			nibble_data->bill_adjustments = 0;

			/* Update channel variable with current billing */
			switch_channel_set_variable_printf(channel, "nibble_total_billed", "%f", nibble_data->total);
		} else {
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failed to log to database!\n");
		}
	} else {
		if (switch_strlen_zero(billincrement))
			switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Just tried to bill %s negative minutes! That should be impossible.\n", uuid);
	}

	/* Save this location */
	if (channel) {
		switch_channel_set_private(channel, "_nibble_data_", nibble_data);

		/* don't verify balance and transfer to nobal if we're done with call */
		if (switch_channel_get_state(channel) != CS_REPORTING && switch_channel_get_state(channel) != CS_HANGUP) {
			
			balance = get_balance(billaccount, channel);
			
			/* See if we've achieved low balance */
			if (!nibble_data->lowbal_action_executed && balance <= lowbal_amt) {
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Balance of %f fell below low balance amount of %f! (Account %s)\n",
								  balance, lowbal_amt, billaccount);

				if (exec_app(session, globals.lowbal_action) != SWITCH_STATUS_SUCCESS)
					switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Low balance action didn't execute\n");
				else
					nibble_data->lowbal_action_executed = 1;
			}

			/* See if this person has enough money left to continue the call */
			if (balance <= nobal_amt) {
				/* Not enough money - reroute call to nobal location */
				switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Balance of %f fell below allowed amount of %f! (Account %s)\n",
								  balance, nobal_amt, billaccount);

				/* IMPORTANT: Billing must be paused before the transfer occurs! This prevents infinite loops, since the transfer will result */
				/* in nibblebill checking the call again in the routing process for an allowed balance! */
				/* If you intend to give the user the option to re-up their balance, you must clear & resume billing once the balance is updated! */
				nibblebill_pause(session);
				transfer_call(session, globals.nobal_action);
			}
		}
	}


	/* Done changing - release lock */
	if (globals.mutex) {
		switch_mutex_unlock(globals.mutex);
	}

	/* Go check if this call is allowed to continue */

	return SWITCH_STATUS_SUCCESS;
}
示例#28
0
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_next_result_timed(switch_pgsql_handle_t *handle, switch_pgsql_result_t **result_out, int msec)
{
#ifdef SWITCH_HAVE_PGSQL
    switch_pgsql_result_t *res;
    switch_time_t start;
    switch_time_t ctime;
    unsigned int usec = msec * 1000;
    char *err_str;
    struct pollfd fds[2] = { {0} };
    int poll_res = 0;

    if(!handle) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "**BUG** Null handle passed to switch_pgsql_next_result.\n");
        return SWITCH_PGSQL_FAIL;
    }

    /* Try to consume input that might be waiting right away */
    if (PQconsumeInput(handle->con)) {
        /* And check to see if we have a full result ready for reading */
        if (PQisBusy(handle->con)) {

            /* Wait for a result to become available, up to msec milliseconds */
            start = switch_micro_time_now();
            while((ctime = switch_micro_time_now()) - start <= usec) {
                int wait_time = (usec - (ctime - start)) / 1000;
                fds[0].fd = handle->sock;
                fds[0].events |= POLLIN;
                fds[0].events |= POLLERR;
                fds[0].events |= POLLNVAL;
                fds[0].events |= POLLHUP;
                fds[0].events |= POLLPRI;
                fds[0].events |= POLLRDNORM;
                fds[0].events |= POLLRDBAND;

                /* Wait for the PostgreSQL socket to be ready for data reads. */
                if ((poll_res = poll(&fds[0], 1, wait_time)) > 0 ) {
                    if (fds[0].revents & POLLHUP || fds[0].revents & POLLNVAL) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PGSQL socket closed or invalid while waiting for result for query (%s)\n", handle->sql);
                        goto error;
                    } else if (fds[0].revents & POLLERR) {
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql);
                        goto error;
                    } else if (fds[0].revents & POLLIN || fds[0].revents & POLLPRI || fds[0].revents & POLLRDNORM || fds[0].revents & POLLRDBAND) {
                        /* Then try to consume any input waiting. */
                        if (PQconsumeInput(handle->con)) {
                            if (PQstatus(handle->con) == CONNECTION_BAD) {
                                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection terminated while waiting for result.\n");
                                handle->state = SWITCH_PGSQL_STATE_ERROR;
                                goto error;
                            }

                            /* And check to see if we have a full result ready for reading */
                            if (!PQisBusy(handle->con)) {
                                /* If we can pull a full result without blocking, then break this loop */
                                break;
                            }
                        } else {
                            /* If we had an error trying to consume input, report it and cancel the query. */
                            err_str = switch_pgsql_handle_get_error(handle);
                            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
                            switch_safe_free(err_str);
                            switch_pgsql_cancel(handle);
                            goto error;
                        }
                    }
                } else if (poll_res == -1) {
                    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql);
                    goto error;
                }
            }

            /* If we broke the loop above because of a timeout, report that and cancel the query. */
            if (ctime - start > usec) {
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql);
                switch_pgsql_cancel(handle);
                goto error;
            }

        }
    } else {
        /* If we had an error trying to consume input, report it and cancel the query. */
        err_str = switch_pgsql_handle_get_error(handle);
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
        switch_safe_free(err_str);
        /* switch_pgsql_cancel(handle); */
        goto error;
    }


    /* At this point, we know we can read a full result without blocking. */
    if(!(res = malloc(sizeof(switch_pgsql_result_t)))) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Malloc failed!\n");
        goto error;
    }
    memset(res, 0, sizeof(switch_pgsql_result_t));


    res->result = PQgetResult(handle->con);
    if (res->result) {
        *result_out = res;
        res->status = PQresultStatus(res->result);
        switch(res->status) {
#if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 2
        case PGRES_SINGLE_TUPLE:
            /* Added in PostgreSQL 9.2 */
#endif
        case PGRES_TUPLES_OK:
        {
            res->rows = PQntuples(res->result);
            handle->affected_rows = res->rows;
            res->cols = PQnfields(res->result);
        }
        break;
#if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 1
        case PGRES_COPY_BOTH:
            /* Added in PostgreSQL 9.1 */
#endif
        case PGRES_COPY_OUT:
        case PGRES_COPY_IN:
        case PGRES_COMMAND_OK:
            break;
        case PGRES_EMPTY_QUERY:
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_EMPTY_QUERY\n", handle->sql);
        case PGRES_BAD_RESPONSE:
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_BAD_RESPONSE\n", handle->sql);
        case PGRES_NONFATAL_ERROR:
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_NONFATAL_ERROR\n", handle->sql);
        case PGRES_FATAL_ERROR:
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_FATAL_ERROR\n", handle->sql);
            res->err = PQresultErrorMessage(res->result);
            goto error;
            break;
        }
    } else {
        free(res);
        res = NULL;
        *result_out = NULL;
    }

    return SWITCH_PGSQL_SUCCESS;
error:

    /* Make sure the failed connection does not have any transactions marked as in progress */
    switch_pgsql_flush(handle);

    /* Try to reconnect to the DB if we were dropped */
    db_is_up(handle);

#endif
    return SWITCH_PGSQL_FAIL;
}
示例#29
0
/* 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;
}
示例#30
0
/* detect if should stop */
static switch_bool_t stop_detect(pocketsphinx_t *ps, int16_t *data, unsigned int samples)
{
	uint32_t score, count = 0, j = 0;
	double energy = 0;
    


	if (ps->countdown) {
		if (!--ps->countdown) {
            /* when countdown ==0 */
			ps->silence_hits = ps->org_silence_hits;
			ps->listening = 0;
            
            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, ">>>>>>>>stop_detect:stop by countdown=0<<<<<<<<<\n");
            ps->ifly_wait_result = SWITCH_TRUE;

			return SWITCH_TRUE;
		}
		return SWITCH_FALSE;
	}

	/* Do simple energy threshold for VAD */
	for (count = 0; count < samples; count++) {
		energy += abs(data[j]);
	}

	score = (uint32_t) (energy / samples);
    
    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
     ">>>>>>>>detect score = %d listening=%d status=%d ep=%d<<<<<<<<<\n",
     (int)score,
     ps->listening,
     ps->ifly_rec_stat,
     ps->ifly_ep_stat);


	if (score >= ps->thresh) {
		if (++ps->listening == 1) {
			switch_mutex_lock(ps->flag_mutex);
			switch_set_flag(ps, PSFLAG_BARGE);
			switch_set_flag(ps, PSFLAG_START_OF_SPEECH);
			switch_mutex_unlock(ps->flag_mutex);
		}
		ps->silence_time = 0;
	} else if (!ps->silence_time) {
		ps->silence_time = switch_micro_time_now();
	}

	/* Check silence timeouts */
	if (ps->silence_time && switch_test_flag(ps, PSFLAG_INPUT_TIMERS)) {
		switch_time_t elapsed_ms = (switch_micro_time_now() - ps->silence_time) / 1000;
		if (switch_test_flag(ps, PSFLAG_START_OF_SPEECH)) {
			if (ps->speech_timeout > 0 && !switch_test_flag(ps, PSFLAG_SPEECH_TIMEOUT) && elapsed_ms >= ps->speech_timeout) {
				switch_set_flag_locked(ps, PSFLAG_SPEECH_TIMEOUT);
				ps->listening = 0;
                
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, ">>>>>>>>stop_detect:stop by speech_timeout<<<<<<<<<\n");

				return SWITCH_TRUE;
			}
		} else {
			if (ps->no_input_timeout > 0 && !switch_test_flag(ps, PSFLAG_NOINPUT_TIMEOUT) && elapsed_ms >= ps->no_input_timeout) {
				switch_mutex_lock(ps->flag_mutex);
				switch_set_flag(ps, PSFLAG_NOINPUT_TIMEOUT);
				switch_set_flag(ps, PSFLAG_NOINPUT);
				switch_mutex_unlock(ps->flag_mutex);
				ps->listening = 0;
                
                switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, ">>>>>>>>stop_detect:stop by no_input_timeout<<<<<<<<<\n");

				return SWITCH_TRUE;
			}
		}
	}

	if (ps->listening > ps->listen_hits && score < ps->thresh) {
		if (!--ps->silence_hits) {
			ps->countdown = 12;
		}
	} else {
		ps->silence_hits = ps->org_silence_hits;
	}

	return SWITCH_FALSE;
}