Merge pull request #1641 in FS/freeswitch from FSA/freeswitch-advantage:test-sync to master

* commit 'ffc4a6e32ac94aa41c65b89cce53154e4f939d5c': (23 commits)
  FS-11487 convert tests to Makefile.am
  FS-11569 add rate to null endpoint
  FS-11505: [core] System call with output capture on Linux and Windows without fork. Add switch_core test.
  FS-11455 add switch_utils test
  FS-11442 [test] enable module runtime when loading it
  FS-11442 [test] add fst_check_extension_apps to compare dialplan apps with expected.
  FS-11442 [test] Fix double-free on test suite cleanup.
  FS-11487 #resolve convert to Makefile.am
  missing comma
  FS-11461: [mod_av] Add test code, improve tests on Windows.
  FS-11461: [core] Fix mod_av test code on Windows.
  FS-11453 [core] remove dependency to libtap for unit tests                 move all core unit tests to tests/unit
  FS-11455 #resolve add originate test for state handlers
  FS-11453 [mod_rayo] convert to fst testing
  FS-11453 [mod_rayo] allow text/plain grammar for non-mrcp speech recognizers.  Added direction to output component to assist with testing.  Fix confidence conversion to NLSML.
  FS-11453 [mod_rayo] add support for FS JSON ASR result.
  FS-11442 [mod_test] new module, mod_test - mock ASR interface.
  FS-11442 [core] allow multiple test modules to be loaded in the same test program.
  FS-11442 [core] Add test helpers for wall time measurements and integer/double range checks.  Improve simple test log output to identify which test the failure is in.
  FS-11442 [core] added test helpers for constructing XML objects
  ...
This commit is contained in:
Andrey Volk 2018-12-20 15:54:55 +00:00
commit 972b3a3128
60 changed files with 6059 additions and 4054 deletions

2
.gitignore vendored
View File

@ -155,6 +155,8 @@ Release/
/src/mod/applications/mod_osp/Makefile.in
/src/mod/applications/mod_rss/Makefile
/src/mod/applications/mod_snipe_hunt/Makefile
/src/mod/applications/mod_test/test/Makefile
/src/mod/applications/mod_test/test/Makefile.in
/src/mod/codecs/mod_com_g729/Makefile
/src/mod/codecs/mod_com_g729/Makefile.in
/src/mod/codecs/mod_dahdi_codec/Makefile

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
EXTRA_DIST =
SUBDIRS = . src build
SUBDIRS = . src build tests/unit
AUTOMAKE_OPTIONS = foreign subdir-objects
NAME = freeswitch
@ -865,16 +865,3 @@ support:
@cp support-d/.bashrc ~
@test -f ~/.cc-mode-installed || sh support-d/install-cc-mode.sh && touch ~/.cc-mode-installed
# Using a non-recursive Makefile structure for the automated tests so that the tests have visibility into
# targets in the rest of the FreeSWITCH tree. This greatly simplifies dependency tracking at the expense
# of longer test target names. Since the tests are expected to be run easily and rapidly after minor source
# changes this is the most effective structure.
check_PROGRAMS =
include tests/unit/unit.mk
TESTS = $(check_PROGRAMS)
tests: $(check_PROGRAMS)

View File

@ -1807,6 +1807,7 @@ ac_cv_file_dbd_apr_dbd_mysql_c=no
AC_CONFIG_FILES([Makefile
build/Makefile
tests/unit/Makefile
src/Makefile
src/mod/Makefile
src/mod/applications/mod_abstraction/Makefile
@ -1861,6 +1862,8 @@ AC_CONFIG_FILES([Makefile
src/mod/applications/mod_spandsp/Makefile
src/mod/applications/mod_spy/Makefile
src/mod/applications/mod_stress/Makefile
src/mod/applications/mod_test/Makefile
src/mod/applications/mod_test/test/Makefile
src/mod/applications/mod_translate/Makefile
src/mod/applications/mod_valet_parking/Makefile
src/mod/applications/mod_vmd/Makefile
@ -1927,6 +1930,7 @@ AC_CONFIG_FILES([Makefile
src/mod/event_handlers/mod_radius_cdr/Makefile
src/mod/event_handlers/mod_odbc_cdr/Makefile
src/mod/event_handlers/mod_rayo/Makefile
src/mod/event_handlers/mod_rayo/test/Makefile
src/mod/event_handlers/mod_smpp/Makefile
src/mod/event_handlers/mod_snmp/Makefile
src/mod/event_handlers/mod_event_zmq/Makefile
@ -1980,6 +1984,7 @@ AC_CONFIG_FILES([Makefile
src/mod/xml_int/mod_xml_rpc/Makefile
src/mod/xml_int/mod_xml_scgi/Makefile
src/mod/applications/mod_av/Makefile
src/mod/applications/mod_av/test/Makefile
src/mod/applications/mod_video_filter/Makefile
src/include/switch_am_config.h
build/getsounds.sh

View File

@ -840,6 +840,9 @@ of "checks".
struct _fctchk_t
{
/* The name of the test this condition is in */
char name[FCT_MAX_LOG_LINE];
/* This string that represents the condition. */
char cndtn[FCT_MAX_LOG_LINE];
@ -861,10 +864,12 @@ struct _fctchk_t
#define fctchk__lineno(_CHK_) ((_CHK_)->lineno)
#define fctchk__cndtn(_CHK_) ((_CHK_)->cndtn)
#define fctchk__msg(_CHK_) ((_CHK_)->msg)
#define fctchk__name(_CHK_) ((_CHK_)->name)
static fctchk_t*
fctchk_new(int is_pass,
char const *cndtn,
char const *name,
char const *file,
int lineno,
char const *format,
@ -882,6 +887,7 @@ fctchk_new(int is_pass,
return NULL;
}
fctstr_safe_cpy(chk->name, name ? name : "", FCT_MAX_LOG_LINE);
fctstr_safe_cpy(chk->cndtn, cndtn, FCT_MAX_LOG_LINE);
fctstr_safe_cpy(chk->file, file, FCT_MAX_LOG_LINE);
chk->lineno = lineno;
@ -2689,24 +2695,13 @@ fct_logger__on_warn(fct_logger_i *logger, char const *msg)
/* Common routine to record strings representing failures. The
chk should be a failure before we call this, and the list is a list
of char*'s that will eventually be free'd by the logger. */
of conditions that will eventually be free'd by the logger. */
static void
fct_logger_record_failure(fctchk_t const* chk, fct_nlist_t* fail_list)
{
/* For now we will truncate the string to some set amount, later
we can work out a dynamic string object. */
char *str = (char*)malloc(sizeof(char)*FCT_MAX_LOG_LINE);
FCT_ASSERT( str != NULL );
fct_snprintf(
str,
FCT_MAX_LOG_LINE,
"%s(%d):\n %s",
fctchk__file(chk),
fctchk__lineno(chk),
fctchk__msg(chk)
);
/* Append it to the listing ... */
fct_nlist__append(fail_list, (void*)str);
fctchk_t *dup_chk = (fctchk_t *)malloc(sizeof(*dup_chk));
memcpy(dup_chk, chk, sizeof(*dup_chk));
fct_nlist__append(fail_list, (void *)dup_chk);
}
@ -2714,13 +2709,21 @@ fct_logger_record_failure(fctchk_t const* chk, fct_nlist_t* fail_list)
static void
fct_logger_print_failures(fct_nlist_t const *fail_list)
{
const char *last_test = NULL;
puts(
"\n----------------------------------------------------------------------------\n"
);
puts("FAILED TESTS\n\n");
FCT_NLIST_FOREACH_BGN(char *, cndtn_str, fail_list)
puts("FAILED TESTS\n");
FCT_NLIST_FOREACH_BGN(fctchk_t const *, chk, fail_list)
{
printf("%s\n", cndtn_str);
if (!last_test || strcmp(last_test, fctchk__name(chk))) {
printf("\n%s\n", fctchk__name(chk));
}
last_test = fctchk__name(chk);
printf(" %s(%d):\n %s\n",
fctchk__file(chk),
fctchk__lineno(chk),
fctchk__msg(chk));
}
FCT_NLIST_FOREACH_END();
@ -2794,7 +2797,7 @@ fct_minimal_logger__on_delete(
{
fct_minimal_logger_t *self = (fct_minimal_logger_t*)self_;
fct_unused(e);
fct_nlist__final(&(self->failed_cndtns_list), free);
fct_nlist__final(&(self->failed_cndtns_list), (fct_nlist_on_del_t)fctchk__del);
free(self);
}
@ -2965,7 +2968,7 @@ fct_standard_logger__on_delete(
{
fct_standard_logger_t *logger = (fct_standard_logger_t*)logger_;
fct_unused(e);
fct_nlist__final(&(logger->failed_cndtns_list), free);
fct_nlist__final(&(logger->failed_cndtns_list), (fct_nlist_on_del_t)fctchk__del);
free(logger);
logger_ =NULL;
}
@ -3571,8 +3574,10 @@ _fct_xchk_fn_varg(
{
fctchk_t *chk =NULL;
chk = fctchk_new(
is_pass,
condition,
fct_test__name(fct_xchk_test),
fct_xchk_file,
fct_xchk_lineno,
format,

View File

@ -35,52 +35,98 @@
#include <test/switch_fct.h>
/**
* Get environment variable and save to var
*/
static char *fst_getenv_default(const char *env, char *default_value, switch_bool_t required)
{
char *val = getenv(env);
if (!val) {
if (required) {
fprintf(stderr, "Failed to start test: environment variable \"%s\" is not set!\n", env);
exit(1);
}
return default_value;
}
return val;
}
/**
* Get environment variable and save to var
*/
#define fst_getenv(env, default_value) \
char *env = getenv(#env); \
if (!env) { \
env = (char *)default_value; \
}
char *env = fst_getenv_default(#env, (char *)default_value, SWITCH_FALSE);
/**
* Get mandatory environment variable and save to var. Exit with error if missing.
*/
#define fst_getenv_required(env) \
char *env = getenv(#env); \
if (!env) { \
fprintf(stderr, "Failed to start test: environment variable \"%s\" is not set!\n", #env); \
exit(1); \
}
char *env = fst_getenv_default(#env, NULL, SWITCH_TRUE);
/**
* initialize FS core from optional configuration dir
*/
static void fst_init_core_and_modload(const char *confdir)
static void fst_init_core_and_modload(const char *confdir, const char *basedir, int minimal)
{
const char *err;
if (!zstr(confdir)) {
SWITCH_GLOBAL_dirs.conf_dir = strdup(confdir);
// Let FreeSWITCH core pick these
//SWITCH_GLOBAL_dirs.base_dir = strdup("/usr/local/freeswitch");
//SWITCH_GLOBAL_dirs.mod_dir = strdup("/usr/local/freeswitch/mod");
//SWITCH_GLOBAL_dirs.lib_dir = strdup("/usr/local/freeswitch/lib");
//SWITCH_GLOBAL_dirs.temp_dir = strdup("/tmp");
if (zstr(basedir)) {
basedir = ".";
}
// Allow test to define the runtime dir
if (!zstr(confdir)) {
#ifdef SWITCH_TEST_BASE_DIR_FOR_CONF
SWITCH_GLOBAL_dirs.conf_dir = switch_mprintf("%s%s%s", SWITCH_TEST_BASE_DIR_FOR_CONF, SWITCH_PATH_SEPARATOR, confdir);
#else
if (confdir[0] != '/') {
SWITCH_GLOBAL_dirs.conf_dir = switch_mprintf(".%s%s", SWITCH_PATH_SEPARATOR, confdir);
} else {
SWITCH_GLOBAL_dirs.conf_dir = strdup(confdir);
}
#endif
} else {
SWITCH_GLOBAL_dirs.conf_dir = switch_mprintf("%s%sconf", basedir, SWITCH_PATH_SEPARATOR);
}
SWITCH_GLOBAL_dirs.log_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.run_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.recordings_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.sounds_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.cache_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.db_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.script_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.htdocs_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.grammar_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.fonts_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.images_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.storage_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.data_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
SWITCH_GLOBAL_dirs.localstate_dir = switch_mprintf("%s%s", basedir, SWITCH_PATH_SEPARATOR);
switch_core_set_globals();
if (!minimal) {
switch_core_init_and_modload(0, SWITCH_TRUE, &err);
switch_sleep(1 * 1000000);
switch_core_set_variable("sound_prefix", "." SWITCH_PATH_SEPARATOR);
} else {
switch_core_init(SCF_MINIMAL, SWITCH_TRUE, &err);
}
SWITCH_GLOBAL_dirs.sounds_dir = strdup("./");
switch_core_init_and_modload(0, SWITCH_TRUE, &err);
switch_sleep(1 * 1000000);
switch_core_set_variable("sound_prefix", "");
}
/**
* Park FreeSWITCH session. This is handy when wanting to use switch_core_session_execute_async() on the test session.
* @param session to park
*/
static void fst_session_park(switch_core_session_t *session)
{
switch_ivr_park_session(session);
#define fst_session_park(session) \
switch_ivr_park_session(session); \
switch_channel_wait_for_state(switch_core_session_get_channel(session), NULL, CS_PARK);
}
/**
* check for test requirement - execute teardown on failure
@ -112,6 +158,88 @@ static void fst_session_park(switch_core_session_t *session)
*/
#define fst_check_string_not_equals fct_chk_neq_str
/**
* Mark reference for time measure
*/
#define fst_time_mark() \
fst_time_start = switch_time_now();
/**
* Check a test /w error message
*/
#define fst_xcheck(expr, error_msg) \
fct_xchk(expr, error_msg);
/**
* Fail a test
*/
#define fst_fail(error_msg) \
fct_xchk(0, error_msg);
/**
* Check duration relative to test start, last marked time, or last check.
*/
#define fst_check_duration(duration_ms, precision_ms) \
{ \
int actual_duration_ms = (int)((switch_time_now() - fst_time_start) / 1000); \
fct_xchk( \
abs((actual_duration_ms - duration_ms)) <= precision_ms, \
"fst_check_duration: %d != %d +/- %d", \
(actual_duration_ms), \
(duration_ms), \
(precision_ms) \
); \
}
/**
* Check if integer is in range
*/
#define fst_check_int_range(actual, expected, precision) \
fct_xchk( \
abs((actual - expected)) <= precision, \
"fst_check_int_range: %d != %d +/- %d", \
(actual), \
(expected), \
(precision) \
);
/**
* Check if double-precision number is in range
*/
#define fst_check_double_range(actual, expected, precision) \
fct_xchk( \
fabs((actual - expected)) <= precision, \
"fst_check_double_range: %f != %f +/- %f", \
(actual), \
(expected), \
(precision) \
);
/**
* Run test without loading FS core
*/
#define FST_BEGIN() \
FCT_BGN() \
{ \
int fst_core = 0; \
switch_time_t fst_time_start = 0; \
switch_timer_t fst_timer = { 0 }; \
switch_memory_pool_t *fst_pool = NULL; \
fst_getenv_default("FST_SUPPRESS_UNUSED_STATIC_WARNING", NULL, SWITCH_FALSE); \
if (fst_core) { \
fst_init_core_and_modload(NULL, NULL, 0); /* shuts up compiler */ \
} \
{ \
#define FST_END() \
} \
if (fst_time_start) { \
/* shut up compiler */ \
fst_time_start = 0; \
} \
} \
FCT_END()
/**
* Define the beginning of a freeswitch core test driver. Only one per test application allowed.
@ -120,43 +248,95 @@ static void fst_session_park(switch_core_session_t *session)
#define FST_CORE_BEGIN(confdir) \
FCT_BGN() \
{ \
int fst_core = 2; \
switch_time_t fst_time_start = 0; \
switch_timer_t fst_timer = { 0 }; \
switch_memory_pool_t *fst_pool = NULL; \
fst_init_core_and_modload(confdir);
fst_getenv_default("FST_SUPPRESS_UNUSED_STATIC_WARNING", NULL, SWITCH_FALSE); \
fst_init_core_and_modload(confdir, NULL, 0); \
{
/**
* Define the end of a freeswitch core test driver.
*/
#define FST_CORE_END() \
/*switch_core_destroy();*/ \
} \
if (fst_time_start) { \
/* shut up compiler */ \
fst_time_start = 0; \
} \
} \
FCT_END()
/**
* Minimal FS core load
*/
#define FST_MINCORE_BEGIN() \
FCT_BGN() \
{ \
int fst_core = 1; \
switch_time_t fst_time_start = 0; \
switch_timer_t fst_timer = { 0 }; \
switch_memory_pool_t *fst_pool = NULL; \
fst_getenv_default("FST_SUPPRESS_UNUSED_STATIC_WARNING", NULL, SWITCH_FALSE); \
fst_init_core_and_modload(".", NULL, 1); /* minimal load */ \
{
#define FST_MINCORE_END FST_CORE_END
/**
* Define the beginning of a FreeSWITCH module test suite. Loads the module for test.
* @param modname name of module to load.
* @param suite the name of this test suite
*/
#ifdef WIN32
#define FST_MODULE_BEGIN(modname,suite) \
const char *fst_test_module = #modname; \
if (!zstr(fst_test_module)) { \
const char *err; \
switch_loadable_module_load_module((char *)"../.libs", (char *)fst_test_module, SWITCH_FALSE, &err); \
} \
FCT_FIXTURE_SUITE_BGN(suite)
{ \
const char *fst_test_module = #modname; \
if (fst_core && !zstr(fst_test_module)) { \
const char *err; \
switch_loadable_module_load_module((char *)"./mod", (char *)fst_test_module, SWITCH_TRUE, &err); \
} \
FCT_FIXTURE_SUITE_BGN(suite);
#else
#define FST_MODULE_BEGIN(modname,suite) \
{ \
const char *fst_test_module = #modname; \
if (fst_core && !zstr(fst_test_module)) { \
const char *err; \
switch_loadable_module_load_module((char *)"../.libs", (char *)fst_test_module, SWITCH_TRUE, &err); \
} \
FCT_FIXTURE_SUITE_BGN(suite);
#endif
/**
* Define the end of a FreeSWITCH module test suite.
*/
#define FST_MODULE_END FCT_FIXTURE_SUITE_END
#ifdef WIN32
#define FST_MODULE_END() \
FCT_FIXTURE_SUITE_END(); \
if (!zstr(fst_test_module) && switch_loadable_module_exists(fst_test_module) == SWITCH_STATUS_SUCCESS) { \
const char *err; \
switch_loadable_module_unload_module((char *)"./mod", (char *)fst_test_module, SWITCH_FALSE, &err); \
} \
}
#else
#define FST_MODULE_END() \
FCT_FIXTURE_SUITE_END(); \
if (!zstr(fst_test_module) && switch_loadable_module_exists(fst_test_module) == SWITCH_STATUS_SUCCESS) { \
const char *err; \
switch_loadable_module_unload_module((char *)"../.libs", (char *)fst_test_module, SWITCH_FALSE, &err); \
} \
}
#endif
/**
* Define the beginning of a test suite not associated with a module.
* @param suite the name of this test suite
*/
#define FST_SUITE_BEGIN(suite) FCT_FIXTURE_SUITE_BGN \
#define FST_SUITE_BEGIN(suite) \
const char *fst_test_module = NULL; \
FCT_FIXTURE_SUITE_BGN(suite)
@ -171,9 +351,14 @@ static void fst_session_park(switch_core_session_t *session)
*/
#define FST_SETUP_BEGIN() \
FCT_SETUP_BGN() \
switch_core_new_memory_pool(&fst_pool); \
fst_requires(fst_pool != NULL); \
fst_requires(switch_core_timer_init(&fst_timer, "soft", 20, 160, fst_pool) == SWITCH_STATUS_SUCCESS);
if (fst_core) { \
switch_core_new_memory_pool(&fst_pool); \
fst_requires(fst_pool != NULL); \
if (fst_core > 1) { \
fst_requires(switch_core_timer_init(&fst_timer, "soft", 20, 160, fst_pool) == SWITCH_STATUS_SUCCESS); \
} \
fst_time_mark(); \
}
/**
* Define the end of test suite setup.
@ -186,8 +371,12 @@ static void fst_session_park(switch_core_session_t *session)
*/
#define FST_TEARDOWN_BEGIN() \
FCT_TEARDOWN_BGN() \
switch_core_destroy_memory_pool(&fst_pool); \
switch_core_timer_destroy(&fst_timer);
if (fst_core) { \
switch_core_destroy_memory_pool(&fst_pool); \
if (fst_core > 1) { \
switch_core_timer_destroy(&fst_timer); \
} \
}
/**
* Define the test suite teardown end.
@ -227,13 +416,16 @@ static void fst_session_park(switch_core_session_t *session)
* switch_channel_t *fst_channel; The outbound null session's channel.
*
* @param name the name of this test
* @param rate the rate of the channel
*/
#define FST_SESSION_BEGIN(name) \
#define FST_SESSION_BEGIN_RATE(name, rate) \
FCT_TEST_BGN(name) \
{ \
switch_core_session_t *fst_session = NULL; \
switch_event_t *fst_originate_vars = NULL; \
switch_call_cause_t fst_cause = SWITCH_CAUSE_NORMAL_CLEARING; \
fst_requires(fst_core); \
if (fst_test_module) { \
fst_requires_module(fst_test_module); \
} \
@ -242,6 +434,7 @@ static void fst_session_park(switch_core_session_t *session)
fst_requires(switch_core_running()); \
fst_requires(switch_event_create_plain(&fst_originate_vars, SWITCH_EVENT_CHANNEL_DATA) == SWITCH_STATUS_SUCCESS); \
switch_event_add_header_string(fst_originate_vars, SWITCH_STACK_BOTTOM, "origination_caller_id_number", "+15551112222"); \
switch_event_add_header(fst_originate_vars, SWITCH_STACK_BOTTOM, "rate", "%d", rate); \
if (switch_ivr_originate(NULL, &fst_session, &fst_cause, "null/+15553334444", 2, NULL, NULL, NULL, NULL, fst_originate_vars, SOF_NONE, NULL, NULL) == SWITCH_STATUS_SUCCESS && fst_session) { \
switch_memory_pool_t *fst_session_pool = switch_core_session_get_pool(fst_session); \
switch_channel_t *fst_channel = switch_core_session_get_channel(fst_session); \
@ -252,6 +445,13 @@ static void fst_session_park(switch_core_session_t *session)
switch_ivr_record_session(fst_session, (char *)"/tmp/"#name".wav", 0, NULL); \
for(;;) {
/**
* Define a session test in a test suite. This can be used to test IVR functions.
* See FST_SESSION_BEGIN_RATE
*/
#define FST_SESSION_BEGIN(name) FST_SESSION_BEGIN_RATE(name, 8000)
/* BODY OF TEST CASE HERE */
/**
@ -267,6 +467,9 @@ static void fst_session_park(switch_core_session_t *session)
if (fst_originate_vars) { \
switch_event_destroy(&fst_originate_vars); \
} \
if (fst_session_pool) { \
fst_session_pool = NULL; \
} \
switch_core_session_rwunlock(fst_session); \
switch_sleep(1000000); \
} \
@ -295,6 +498,7 @@ static void fst_session_park(switch_core_session_t *session)
char *fst_asr_result = NULL; \
switch_asr_handle_t ah = { 0 }; \
switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE; \
fst_requires(fst_core > 1); \
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Open recognizer: %s\n", recognizer); \
/* open ASR interface and feed recorded audio into it and collect result */ \
fst_requires(switch_core_asr_open(&ah, recognizer, "L16", 8000, "", &flags, fst_pool) == SWITCH_STATUS_SUCCESS); \
@ -318,28 +522,30 @@ static void fst_session_park(switch_core_session_t *session)
*/
#define fst_test_core_asr(grammar, input_filename) \
{ \
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Test recognizer: input = %s\n", input_filename); \
fst_asr_result = NULL; \
fst_requires(switch_core_asr_load_grammar(&ah, grammar, "") == SWITCH_STATUS_SUCCESS); \
/* feed file into ASR */ \
switch_status_t result; \
switch_file_handle_t file_handle = { 0 }; \
file_handle.channels = 1; \
file_handle.native_rate = 8000; \
fst_requires(switch_core_file_open(&file_handle, input_filename, file_handle.channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS); \
uint8_t *buf = (uint8_t *)switch_core_alloc(fst_pool, sizeof(uint8_t) * 160 * sizeof(uint16_t) * file_handle.channels); \
uint8_t *buf; \
size_t len = 160; \
int got_result = 0; \
fst_asr_result = NULL; \
file_handle.channels = 1; \
file_handle.native_rate = 8000; \
fst_requires(fst_core > 1); \
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Test recognizer: input = %s\n", input_filename); \
fst_requires(switch_core_asr_load_grammar(&ah, grammar, "") == SWITCH_STATUS_SUCCESS); \
fst_requires(switch_core_file_open(&file_handle, input_filename, file_handle.channels, 8000, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS); \
buf = (uint8_t *)switch_core_alloc(fst_pool, sizeof(uint8_t) * 160 * sizeof(uint16_t) * file_handle.channels); \
switch_core_timer_sync(&fst_timer); \
while ((result = switch_core_file_read(&file_handle, buf, &len)) == SWITCH_STATUS_SUCCESS) { \
fst_requires(switch_core_asr_feed(&ah, buf, len * sizeof(int16_t), &flags) == SWITCH_STATUS_SUCCESS); \
switch_core_timer_next(&fst_timer); \
if (switch_core_asr_check_results(&ah, &flags) == SWITCH_STATUS_SUCCESS) { \
char *xmlstr = NULL; \
switch_event_t *headers = NULL; \
flags = SWITCH_ASR_FLAG_NONE; \
/* switch_ivr_detect_speech.. checks one in media bug then again in speech_thread */ \
fst_requires(switch_core_asr_check_results(&ah, &flags) == SWITCH_STATUS_SUCCESS); \
char *xmlstr = NULL; \
switch_event_t *headers = NULL; \
result = switch_core_asr_get_results(&ah, &xmlstr, &flags); \
if (result == SWITCH_STATUS_SUCCESS) { \
got_result++; \
@ -368,6 +574,7 @@ static void fst_session_park(switch_core_session_t *session)
* switch_core_asr_pause(&ah) == SWITCH_STATUS_SUCCESS
*/
#define fst_test_core_asr_pause() \
fst_requires(fst_core > 1); \
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Pause recognizer\n"); \
flags = SWITCH_ASR_FLAG_NONE; \
fst_requires(switch_core_asr_pause(&ah) == SWITCH_STATUS_SUCCESS);
@ -379,6 +586,7 @@ static void fst_session_park(switch_core_session_t *session)
* switch_core_asr_resume(&ah) == SWITCH_STATUS_SUCCESS
*/
#define fst_test_core_asr_resume() \
fst_requires(fst_core > 1); \
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Resume recognizer\n"); \
flags = SWITCH_ASR_FLAG_NONE; \
fst_requires(switch_core_asr_resume(&ah) == SWITCH_STATUS_SUCCESS);
@ -390,6 +598,7 @@ static void fst_session_park(switch_core_session_t *session)
* switch_core_asr_close(&ah, flags) == SWITCH_STATUS_SUCCESS
*/
#define fst_test_core_asr_close() \
fst_requires(fst_core > 1); \
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Close recognizer\n"); \
flags = SWITCH_ASR_FLAG_NONE; \
fst_requires(switch_core_asr_close(&ah, &flags) == SWITCH_STATUS_SUCCESS); \
@ -407,7 +616,8 @@ static void fst_session_park(switch_core_session_t *session)
*/
#define fst_play_and_detect_speech_test_begin() \
{ \
const char *fst_asr_result = NULL;
const char *fst_asr_result = NULL; \
fst_requires(fst_core > 1);
/**
* Use play_and_detect_speech APP to test recognizer
@ -415,6 +625,7 @@ static void fst_session_park(switch_core_session_t *session)
* Test Requires:
* switch_ivr_displace_session(input_filename) == SWITCH_STATUS_SUCCESS
* switch_core_session_execute_application(play_and_detect_speech) == SWITCH_STATUS_SUCCESS
* mod_dptools is loaded
*
* Test Checks:
* fst_asr_result != NULL after recognition completes
@ -427,23 +638,141 @@ static void fst_session_park(switch_core_session_t *session)
* @param prompt_filename name of prompt to play
* @param input_filename name of file containing input audio for the recognizer
*/
#define fst_play_and_detect_speech_test(recognizer, grammar, prompt_filename, input_filename) \
#define fst_play_and_detect_speech_app_test(recognizer, grammar, prompt_filename, input_filename) \
{ \
char *args = NULL; \
fst_requires(fst_core > 1); \
fst_requires_module("mod_dptools"); \
switch_channel_set_variable(fst_channel, "detect_speech_result", ""); \
fst_requires(switch_ivr_displace_session(fst_session, input_filename, 0, "r") == SWITCH_STATUS_SUCCESS); \
fst_requires(switch_ivr_displace_session(fst_session, input_filename, 0, "mr") == SWITCH_STATUS_SUCCESS); \
args = switch_core_session_sprintf(fst_session, "%s detect:%s %s", prompt_filename, recognizer, grammar); \
fst_requires(switch_core_session_execute_application(fst_session, "play_and_detect_speech", args) == SWITCH_STATUS_SUCCESS); \
fst_asr_result = switch_channel_get_variable(fst_channel, "detect_speech_result"); \
fst_check(fst_asr_result != NULL); \
}
/**
* Use play_and_detect_speech core function to test recognizer
*
* Test Requires:
* switch_ivr_displace_session(input_filename) == SWITCH_STATUS_SUCCESS
*
* Test Checks:
* fst_asr_result != NULL after recognition completes
*
* Test Output:
* fst_asr_result has the result from detect_speech_result channel variable.
*
* @param recognizer name of recognizer
* @param grammar recognizer grammar
* @param prompt_filename name of prompt to play
* @param input_filename name of file containing input audio for the recognizer
* @param input_args input callback args
*/
#define fst_play_and_detect_speech_test(recognizer, grammar, prompt_filename, input_filename, input_args) \
{ \
char *args = NULL; \
fst_asr_result = NULL; \
fst_requires(fst_core > 1); \
fst_requires(switch_ivr_displace_session(fst_session, input_filename, 0, "mr") == SWITCH_STATUS_SUCCESS); \
switch_status_t status = switch_ivr_play_and_detect_speech(fst_session, prompt_filename, recognizer, grammar, (char **)&fst_asr_result, 0, input_args); \
fst_check(fst_asr_result != NULL); \
}
/**
* Define end of play_and_detect_speech recognizer test
*/
#define fst_play_and_detect_speech_test_end() \
}
/**
* Compare extension dialplan apps and args with expected apps and args
* @param expected NULL terminated string array of app arg and names.
* const char *expected[] = { "playback", "https://example.com/foo.wav", "park", "", NULL };
* @param extension the switch_caller_extension_t to check
*/
#define fst_check_extension_apps(expected, extension) \
{ \
fst_xcheck(extension != NULL, "Missing extension\n"); \
if (extension) { \
int i; \
switch_caller_application_t *cur_app = extension->applications; \
for (i = 0; ; i += 2, cur_app = cur_app->next) { \
int cur_app_num = i / 2 + 1; \
if (!expected[i]) { \
if (cur_app != NULL) { \
fst_fail(switch_core_sprintf(fst_pool, "Unexpected application #%d \"%s\"\n", cur_app_num, cur_app->application_name)); \
} \
break; \
} \
fst_xcheck(cur_app != NULL, switch_core_sprintf(fst_pool, "Extension application #%d \"%s\" is missing", cur_app_num, expected[i])); \
if (!cur_app) { \
break; \
} \
fst_xcheck(cur_app->application_name && !strcmp(expected[i], cur_app->application_name), switch_core_sprintf(fst_pool, "Expected application #%d name is \"%s\", but is \"%s\"\n", cur_app_num, expected[i], cur_app->application_name)); \
fst_xcheck(cur_app->application_data && !strcmp(expected[i + 1], cur_app->application_data), switch_core_sprintf(fst_pool, "Expected application #%d %s data is \"%s\", but is \"%s\"\n", cur_app_num, expected[i], expected[i + 1], cur_app->application_data)); \
} \
} \
}
/**
* Inject DTMF into the session to be detected.
*
* Test Requires:
* switch_api_execute(sched_api) == SWITCH_STATUS_SUCCESS
* mod_commands is loaded
*
* @param when string describing when to send dtmf
* @param digits to send
*/
#define fst_sched_recv_dtmf(when, digits) \
{ \
switch_stream_handle_t stream = { 0 }; \
SWITCH_STANDARD_STREAM(stream); \
fst_requires(fst_core > 1); \
fst_requires_module("mod_commands"); \
switch_status_t api_result = switch_api_execute("sched_api", switch_core_session_sprintf(fst_session, "%s none uuid_recv_dtmf %s %s", when, switch_core_session_get_uuid(fst_session), digits), NULL, &stream); \
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(fst_session), SWITCH_LOG_INFO, "Injecting DTMF %s at %s\n", digits, when); \
fst_requires(api_result == SWITCH_STATUS_SUCCESS); \
switch_safe_free(stream.data); \
}
#define fst_xml_start() \
switch_stream_handle_t fst_xml_stream = { 0 }; \
SWITCH_STANDARD_STREAM(fst_xml_stream);
int fst_tag_children = 0;
int fst_tag_body = 0;
#define fst_xml_open_tag(tag_name) \
fst_xml_stream.write_function(&fst_xml_stream, "<%s", #tag_name); \
fst_tag_children++;
#define fst_xml_attr(attr) \
if (!zstr(attr)) fst_xml_stream.write_function(&fst_xml_stream, " %s=\"%s\"", #attr, attr);
#define fst_xml_close_tag(tag_name) \
--fst_tag_children; \
if (fst_tag_children > 0 || fst_tag_body) { \
fst_xml_stream.write_function(&fst_xml_stream, "</%s>", #tag_name); \
} else { \
fst_xml_stream.write_function(&fst_xml_stream, "/>"); \
} \
fst_tag_body = 0;
#define fst_xml_body(body) \
if (fst_tag_body) { \
fst_xml_stream.write_function(&fst_xml_stream, "%s", body); \
} else { \
fst_tag_body = 1; \
fst_xml_stream.write_function(&fst_xml_stream, ">%s", body); \
}
#define fst_xml_end() \
switch_xml_parse_str_dynamic((char *)fst_xml_stream.data, SWITCH_FALSE);
/**
* Parse JSON file and save to varname
*

View File

@ -9,6 +9,8 @@ mod_av_la_CFLAGS = $(AM_CFLAGS) $(AVFORMAT_CFLAGS) $(AVCODEC_CFLAGS) $(SWSCALE
mod_av_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(AVFORMAT_LIBS) $(AVCODEC_LIBS) $(SWSCALE_LIBS) $(AVUTIL_LIBS) $(AVRESAMPLE_LIBS)
mod_av_la_LDFLAGS = -avoid-version -module -no-undefined -shared -lm -lz
SUBDIRS=. test
else
install: error
all: error

View File

@ -0,0 +1,4 @@
bin_PROGRAMS = test_mod_av
AM_CFLAGS = $(SWITCH_AM_CFLAGS) -I../ $(AVFORMAT_CFLAGS) $(AVCODEC_CFLAGS) $(SWSCALE_CFLAGS) $(AVUTIL_CFLAGS) $(AVRESAMPLE_CFALGS)
AM_LDFLAGS = $(switch_builddir)/libfreeswitch.la $(AVFORMAT_LIBS) $(AVCODEC_LIBS) $(SWSCALE_LIBS) $(AVUTIL_LIBS) $(AVRESAMPLE_LIBS) -avoid-version -no-undefined $(SWITCH_AM_LDFLAGS) ../mod_av.la
TESTS = $(bin_PROGRAMS)

View File

@ -0,0 +1,40 @@
<?xml version="1.0"?>
<document type="freeswitch/xml">
<section name="configuration" description="Various Configuration">
<configuration name="modules.conf" description="Modules">
<modules>
<load module="mod_console"/>
</modules>
</configuration>
<configuration name="console.conf" description="Console Logger">
<mappings>
<map name="all" value="console,debug,info,notice,warning,err,crit,alert"/>
</mappings>
<settings>
<param name="colorize" value="true"/>
<param name="loglevel" value="debug"/>
</settings>
</configuration>
<configuration name="timezones.conf" description="Timezones">
<timezones>
<zone name="GMT" value="GMT0" />
</timezones>
</configuration>
<X-PRE-PROCESS cmd="include" data="./vpx.conf.xml"/>
<X-PRE-PROCESS cmd="include" data="./av.conf.xml"/>
</section>
<section name="dialplan" description="Regex/XML Dialplan">
<context name="default">
<extension name="sample">
<condition>
<action application="info"/>
</condition>
</extension>
</context>
</section>
</document>

View File

@ -0,0 +1,203 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>test_mod_av</ProjectName>
<RootNamespace>test_mod_av</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<ProjectGuid>{7926CB0D-62CE-4A09-AE94-1DA2BC92D625}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)w32\winlibs.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)w32\winlibs.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)w32\winlibs.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)w32\winlibs.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(PlatformName)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(PlatformName)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SWITCH_TEST_BASE_DIR_FOR_CONF="..\\..\\src\\mod\\applications\\mod_av\\test\\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<BuildLog />
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<EnablePREfast>true</EnablePREfast>
<DisableSpecificWarnings>6031;6340;6246;6011;6387;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<BuildLog />
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<EnablePREfast>true</EnablePREfast>
<DisableSpecificWarnings>6031;6340;6246;6011;6387;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<BuildLog />
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>6031;6340;6246;6011;6387;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<BuildLog />
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>6031;6340;6246;6011;6387;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="test_mod_av.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)w32\Library\FreeSwitchCore.2017.vcxproj">
<Project>{202d7a4e-760d-4d0e-afa1-d7459ced30ff}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,145 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2018, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Seven Du <dujinfang@gmail.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* mod_av_test -- avcodec tests
*
*/
#include <test/switch_test.h>
int loop = 0;
/* Add our command line options. */
static fctcl_init_t my_cl_options[] = {
{"--disable-hw", /* long_opt */
NULL, /* short_opt (optional) */
FCTCL_STORE_TRUE , /* action */
"disable hardware encoder" /* help */
},
{"--loop", /* long_opt */
NULL, /* short_opt (optional) */
FCTCL_STORE_VALUE , /* action */
"loops to encode a picture" /* help */
},
FCTCL_INIT_NULL /* Sentinel */
};
FST_CORE_BEGIN("conf")
{
fctcl_install(my_cl_options);
const char *loop_ = fctcl_val("--loop");
if (loop_) loop = atoi(loop_);
FST_MODULE_BEGIN(mod_av, mod_av_test)
{
FST_SETUP_BEGIN()
{
// fst_requires_module("mod_av");
}
FST_SETUP_END()
FST_TEST_BEGIN(encoder_test)
{
switch_status_t status;
switch_codec_t codec = { 0 };
switch_codec_settings_t codec_settings = { 0 };
// switch_set_string(codec_settings.video.config_profile_name, "conference");
if (!fctcl_is("--disable-hw")) {
codec_settings.video.try_hardware_encoder = 1;
}
status = switch_core_codec_init(&codec,
"H264",
NULL,
NULL,
0,
0,
1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
&codec_settings, fst_pool);
fst_check(status == SWITCH_STATUS_SUCCESS);
switch_image_t *img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, 1280, 720, 1);
fst_requires(img);
uint8_t buf[SWITCH_DEFAULT_VIDEO_SIZE + 12];
switch_frame_t frame = { 0 };
frame.packet = buf;
frame.packetlen = SWITCH_DEFAULT_VIDEO_SIZE + 12;
frame.data = buf + 12;
frame.datalen = SWITCH_DEFAULT_VIDEO_SIZE;
frame.payload = 96;
frame.m = 0;
frame.seq = 0;
frame.timestamp = 0;
frame.img = img;
int packets = 0;
switch_status_t encode_status;
do {
frame.datalen = SWITCH_DEFAULT_VIDEO_SIZE;
encode_status = switch_core_codec_encode_video(&codec, &frame);
if (encode_status == SWITCH_STATUS_SUCCESS || encode_status == SWITCH_STATUS_MORE_DATA) {
fst_requires((encode_status == SWITCH_STATUS_SUCCESS && frame.m) || !frame.m);
if (frame.flags & SFF_PICTURE_RESET) {
frame.flags &= ~SFF_PICTURE_RESET;
fst_check(0);
}
if (frame.datalen == 0) break;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[%d]: %02x %02x | m=%d | %d\n", loop, buf[12], buf[13], frame.m, frame.datalen);
packets++;
}
} while(encode_status == SWITCH_STATUS_MORE_DATA || loop-- > 1);
fst_check(frame.m == 1);
fst_check(packets > 0);
switch_core_codec_destroy(&codec);
}
FST_TEST_END()
FST_TEARDOWN_BEGIN()
{
const char *err = NULL;
switch_sleep(1000000);
fst_check(switch_loadable_module_unload_module(SWITCH_GLOBAL_dirs.mod_dir, (char *)"mod_av", SWITCH_TRUE, &err) == SWITCH_STATUS_SUCCESS);
}
FST_TEARDOWN_END()
}
FST_MODULE_END()
}
FST_CORE_END()

View File

@ -0,0 +1,10 @@
include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_test
mod_LTLIBRARIES = mod_test.la
mod_test_la_SOURCES = mod_test.c
mod_test_la_CFLAGS = $(AM_CFLAGS)
mod_test_la_LIBADD = $(switch_builddir)/libfreeswitch.la
mod_test_la_LDFLAGS = -avoid-version -module -no-undefined -shared
SUBDIRS=. test

View File

@ -0,0 +1,407 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2018, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Rienzo <chris@signalwire.com>
*
*
* mod_test.c -- mock module interfaces for testing
*
*/
#include <switch.h>
SWITCH_MODULE_LOAD_FUNCTION(mod_test_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_test_shutdown);
SWITCH_MODULE_RUNTIME_FUNCTION(mod_test_runtime);
SWITCH_MODULE_DEFINITION(mod_test, mod_test_load, mod_test_shutdown, mod_test_runtime);
typedef enum {
ASRFLAG_READY = (1 << 0),
ASRFLAG_INPUT_TIMERS = (1 << 1),
ASRFLAG_START_OF_SPEECH = (1 << 2),
ASRFLAG_RETURNED_START_OF_SPEECH = (1 << 3),
ASRFLAG_NOINPUT_TIMEOUT = (1 << 4),
ASRFLAG_RESULT = (1 << 5),
ASRFLAG_RETURNED_RESULT = (1 << 6)
} test_asr_flag_t;
typedef struct {
uint32_t flags;
const char *result_text;
double result_confidence;
uint32_t thresh;
uint32_t silence_ms;
uint32_t voice_ms;
int no_input_timeout;
int speech_timeout;
switch_bool_t start_input_timers;
switch_time_t no_input_time;
switch_time_t speech_time;
char *grammar;
char *channel_uuid;
switch_vad_t *vad;
} test_asr_t;
static void test_asr_reset(test_asr_t *context)
{
if (context->vad) {
switch_vad_reset(context->vad);
}
context->flags = 0;
context->result_text = "agent";
context->result_confidence = 87.3;
switch_set_flag(context, ASRFLAG_READY);
context->no_input_time = switch_micro_time_now();
if (context->start_input_timers) {
switch_set_flag(context, ASRFLAG_INPUT_TIMERS);
}
}
static switch_status_t test_asr_open(switch_asr_handle_t *ah, const char *codec, int rate, const char *dest, switch_asr_flag_t *flags)
{
test_asr_t *context;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "asr_open attempt on CLOSED asr handle\n");
return SWITCH_STATUS_FALSE;
}
if (!(context = (test_asr_t *) switch_core_alloc(ah->memory_pool, sizeof(*context)))) {
return SWITCH_STATUS_MEMERR;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "codec = %s, rate = %d, dest = %s\n", codec, rate, dest);
ah->private_info = context;
ah->codec = switch_core_strdup(ah->memory_pool, codec);
if (rate > 16000) {
ah->native_rate = 16000;
}
context->thresh = 400;
context->silence_ms = 700;
context->voice_ms = 60;
context->start_input_timers = 1;
context->no_input_timeout = 5000;
context->speech_timeout = 10000;
context->vad = switch_vad_init(ah->native_rate, 1);
switch_vad_set_mode(context->vad, -1);
switch_vad_set_param(context->vad, "thresh", context->thresh);
switch_vad_set_param(context->vad, "silence_ms", context->silence_ms);
switch_vad_set_param(context->vad, "voice_ms", context->voice_ms);
switch_vad_set_param(context->vad, "debug", 0);
test_asr_reset(context);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t test_asr_load_grammar(switch_asr_handle_t *ah, const char *grammar, const char *name)
{
test_asr_t *context = (test_asr_t *)ah->private_info;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "asr_open attempt on CLOSED asr handle\n");
return SWITCH_STATUS_FALSE;
}
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_INFO, "load grammar %s\n", grammar);
context->grammar = switch_core_strdup(ah->memory_pool, grammar);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t test_asr_unload_grammar(switch_asr_handle_t *ah, const char *name)
{
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t test_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
{
test_asr_t *context = (test_asr_t *)ah->private_info;
switch_status_t status = SWITCH_STATUS_SUCCESS;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Double ASR close!\n");
return SWITCH_STATUS_FALSE;
}
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_NOTICE, "ASR closing ...\n");
if (context->vad) {
switch_vad_destroy(&context->vad);
}
switch_set_flag(ah, SWITCH_ASR_FLAG_CLOSED);
return status;
}
static switch_status_t test_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags)
{
test_asr_t *context = (test_asr_t *) ah->private_info;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_vad_state_t vad_state;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) {
return SWITCH_STATUS_BREAK;
}
if (switch_test_flag(context, ASRFLAG_RETURNED_RESULT) && switch_test_flag(ah, SWITCH_ASR_FLAG_AUTO_RESUME)) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "Auto Resuming\n");
test_asr_reset(context);
}
if (switch_test_flag(context, ASRFLAG_READY)) {
vad_state = switch_vad_process(context->vad, (int16_t *)data, len / sizeof(uint16_t));
if (vad_state == SWITCH_VAD_STATE_STOP_TALKING) {
switch_set_flag(context, ASRFLAG_RESULT);
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_INFO, "Talking stopped, have result.\n");
switch_vad_reset(context->vad);
switch_clear_flag(context, ASRFLAG_READY);
} else if (vad_state == SWITCH_VAD_STATE_START_TALKING) {
switch_set_flag(context, ASRFLAG_START_OF_SPEECH);
context->speech_time = switch_micro_time_now();
}
}
return status;
}
static switch_status_t test_asr_pause(switch_asr_handle_t *ah)
{
test_asr_t *context = (test_asr_t *) ah->private_info;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "asr_pause attempt on CLOSED asr handle\n");
return SWITCH_STATUS_FALSE;
}
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "Pausing\n");
context->flags = 0;
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t test_asr_resume(switch_asr_handle_t *ah)
{
test_asr_t *context = (test_asr_t *) ah->private_info;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "asr_resume attempt on CLOSED asr handle\n");
return SWITCH_STATUS_FALSE;
}
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "Resuming\n");
test_asr_reset(context);
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t test_asr_check_results(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
{
test_asr_t *context = (test_asr_t *) ah->private_info;
if (switch_test_flag(context, ASRFLAG_RETURNED_RESULT) || switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) {
return SWITCH_STATUS_BREAK;
}
if (!switch_test_flag(context, ASRFLAG_RETURNED_START_OF_SPEECH) && switch_test_flag(context, ASRFLAG_START_OF_SPEECH)) {
return SWITCH_STATUS_SUCCESS;
}
if ((!switch_test_flag(context, ASRFLAG_RESULT)) && (!switch_test_flag(context, ASRFLAG_NOINPUT_TIMEOUT))) {
if (switch_test_flag(context, ASRFLAG_INPUT_TIMERS) && !(switch_test_flag(context, ASRFLAG_START_OF_SPEECH)) &&
context->no_input_timeout >= 0 &&
(switch_micro_time_now() - context->no_input_time) / 1000 >= context->no_input_timeout) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "NO INPUT TIMEOUT %" SWITCH_TIME_T_FMT "ms\n", (switch_micro_time_now() - context->no_input_time) / 1000);
switch_set_flag(context, ASRFLAG_NOINPUT_TIMEOUT);
} else if (switch_test_flag(context, ASRFLAG_START_OF_SPEECH) && context->speech_timeout > 0 && (switch_micro_time_now() - context->speech_time) / 1000 >= context->speech_timeout) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "SPEECH TIMEOUT %" SWITCH_TIME_T_FMT "ms\n", (switch_micro_time_now() - context->speech_time) / 1000);
if (switch_test_flag(context, ASRFLAG_START_OF_SPEECH)) {
switch_set_flag(context, ASRFLAG_RESULT);
} else {
switch_set_flag(context, ASRFLAG_NOINPUT_TIMEOUT);
}
}
}
return switch_test_flag(context, ASRFLAG_RESULT) || switch_test_flag(context, ASRFLAG_NOINPUT_TIMEOUT) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_BREAK;
}
static switch_status_t test_asr_get_results(switch_asr_handle_t *ah, char **resultstr, switch_asr_flag_t *flags)
{
test_asr_t *context = (test_asr_t *) ah->private_info;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_stream_handle_t result = { 0 };
SWITCH_STANDARD_STREAM(result);
if (switch_test_flag(context, ASRFLAG_RETURNED_RESULT) || switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) {
return SWITCH_STATUS_FALSE;
}
if (switch_test_flag(context, ASRFLAG_RESULT)) {
*resultstr = switch_mprintf("{\"grammar\": \"%s\", \"text\": \"%s\", \"confidence\": %f}", context->grammar, context->result_text, context->result_confidence);
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_ERROR, "Result: %s\n", *resultstr);
status = SWITCH_STATUS_SUCCESS;
} else if (switch_test_flag(context, ASRFLAG_NOINPUT_TIMEOUT)) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "Result: NO INPUT\n");
*resultstr = switch_mprintf("{\"grammar\": \"%s\", \"text\": \"\", \"confidence\": 0, \"error\": \"no_input\"}", context->grammar);
status = SWITCH_STATUS_SUCCESS;
} else if (!switch_test_flag(context, ASRFLAG_RETURNED_START_OF_SPEECH) && switch_test_flag(context, ASRFLAG_START_OF_SPEECH)) {
switch_set_flag(context, ASRFLAG_RETURNED_START_OF_SPEECH);
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "Result: START OF SPEECH\n");
status = SWITCH_STATUS_BREAK;
} else {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_ERROR, "Unexpected call to asr_get_results - no results to return!\n");
status = SWITCH_STATUS_FALSE;
}
if (status == SWITCH_STATUS_SUCCESS) {
switch_set_flag(context, ASRFLAG_RETURNED_RESULT);
switch_clear_flag(context, ASRFLAG_READY);
}
return status;
}
static switch_status_t test_asr_start_input_timers(switch_asr_handle_t *ah)
{
test_asr_t *context = (test_asr_t *) ah->private_info;
if (switch_test_flag(ah, SWITCH_ASR_FLAG_CLOSED)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "asr_start_input_timers attempt on CLOSED asr handle\n");
return SWITCH_STATUS_FALSE;
}
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "start_input_timers\n");
if (!switch_test_flag(context, ASRFLAG_INPUT_TIMERS)) {
switch_set_flag(context, ASRFLAG_INPUT_TIMERS);
context->no_input_time = switch_micro_time_now();
} else {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_INFO, "Input timers already started\n");
}
return SWITCH_STATUS_SUCCESS;
}
static void test_asr_text_param(switch_asr_handle_t *ah, char *param, const char *val)
{
test_asr_t *context = (test_asr_t *) ah->private_info;
if (!zstr(param) && !zstr(val)) {
int nval = atoi(val);
double fval = atof(val);
if (!strcasecmp("no-input-timeout", param) && switch_is_number(val)) {
context->no_input_timeout = nval;
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "no-input-timeout = %d\n", context->no_input_timeout);
} else if (!strcasecmp("speech-timeout", param) && switch_is_number(val)) {
context->speech_timeout = nval;
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "speech-timeout = %d\n", context->speech_timeout);
} else if (!strcasecmp("start-input-timers", param)) {
context->start_input_timers = switch_true(val);
if (context->start_input_timers) {
switch_set_flag(context, ASRFLAG_INPUT_TIMERS);
} else {
switch_clear_flag(context, ASRFLAG_INPUT_TIMERS);
}
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "start-input-timers = %d\n", context->start_input_timers);
} else if (!strcasecmp("vad-mode", param)) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "vad-mode = %s\n", val);
if (context->vad) switch_vad_set_mode(context->vad, nval);
} else if (!strcasecmp("vad-voice-ms", param) && nval > 0) {
context->voice_ms = nval;
switch_vad_set_param(context->vad, "voice_ms", nval);
} else if (!strcasecmp("vad-silence-ms", param) && nval > 0) {
context->silence_ms = nval;
switch_vad_set_param(context->vad, "silence_ms", nval);
} else if (!strcasecmp("vad-thresh", param) && nval > 0) {
context->thresh = nval;
switch_vad_set_param(context->vad, "thresh", nval);
} else if (!strcasecmp("channel-uuid", param)) {
context->channel_uuid = switch_core_strdup(ah->memory_pool, val);
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "channel-uuid = %s\n", val);
} else if (!strcasecmp("result", param)) {
context->result_text = switch_core_strdup(ah->memory_pool, val);
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "result = %s\n", val);
} else if (!strcasecmp("confidence", param) && fval >= 0.0) {
context->result_confidence = fval;
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->channel_uuid), SWITCH_LOG_DEBUG, "confidence = %f\n", fval);
}
}
}
SWITCH_MODULE_LOAD_FUNCTION(mod_test_load)
{
switch_asr_interface_t *asr_interface;
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
asr_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ASR_INTERFACE);
asr_interface->interface_name = "test";
asr_interface->asr_open = test_asr_open;
asr_interface->asr_load_grammar = test_asr_load_grammar;
asr_interface->asr_unload_grammar = test_asr_unload_grammar;
asr_interface->asr_close = test_asr_close;
asr_interface->asr_feed = test_asr_feed;
asr_interface->asr_resume = test_asr_resume;
asr_interface->asr_pause = test_asr_pause;
asr_interface->asr_check_results = test_asr_check_results;
asr_interface->asr_get_results = test_asr_get_results;
asr_interface->asr_start_input_timers = test_asr_start_input_timers;
asr_interface->asr_text_param = test_asr_text_param;
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_test_shutdown)
{
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_RUNTIME_FUNCTION(mod_test_runtime)
{
return SWITCH_STATUS_TERM;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -0,0 +1,5 @@
include $(top_srcdir)/build/modmake.rulesam
bin_PROGRAMS = test_asr
test_asr_CFLAGS = $(AM_CFLAGS) -I../
test_asr_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) ../mod_test.la $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
TESTS = $(bin_PROGRAMS)

View File

@ -0,0 +1,23 @@
<document type="freeswitch/xml">
<section name="configuration" description="Various Configuration">
<configuration name="modules.conf" description="Modules">
<modules>
<load module="mod_loopback"/>
<load module="mod_tone_stream"/>
<load module="mod_dptools"/>
<load module="mod_sndfile"/>
</modules>
</configuration>
</section>
<section name="dialplan" description="Regex/XML Dialplan">
<context name="default">
<extension name="sample">
<condition>
<action application="info"/>
</condition>
</extension>
</context>
</section>
</document>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,292 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2018, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Rienzo <chris@signalwire.com>
*
*
* test_asr.c -- tests for mock test asr interface
*
*/
#include <switch.h>
#include <test/switch_test.h>
#include <stdlib.h>
static const char *get_query_result_text(switch_memory_pool_t *pool, const char *result)
{
const char *result_text = NULL;
cJSON *result_json = cJSON_Parse(result);
if (result_json) {
const char *text = cJSON_GetObjectCstr(result_json, "text");
if (!zstr(text)) {
result_text = switch_core_strdup(pool, text);
} else {
text = cJSON_GetObjectCstr(result_json, "error");
if (!zstr(text)) {
result_text = switch_core_strdup(pool, text);
}
}
cJSON_Delete(result_json);
}
return result_text;
}
FST_CORE_BEGIN(".")
FST_MODULE_BEGIN(mod_test, test_asr)
FST_SETUP_BEGIN()
{
fst_requires_module("mod_tone_stream");
fst_requires_module("mod_sndfile");
fst_requires_module("mod_dptools");
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
FST_TEST_BEGIN(core_asr)
{
const char* session_id = "123435";
char *grammar = switch_core_sprintf(fst_pool, "{start-input-timers=true,no-input-timeout=5000,speech-timeout=10000,channel-uuid=%s}default", session_id);
fst_test_core_asr_open("test");
fst_test_core_asr(
grammar,
"file_string://silence_stream://3000,0!sounds/agent.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr_resume();
fst_test_core_asr(
grammar,
"silence_stream://30000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "no_input");
fst_test_core_asr_resume();
fst_test_core_asr(
grammar,
"file_string://sounds/agent.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr_resume();
fst_test_core_asr(
grammar,
"silence_stream://30000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "no_input");
fst_test_core_asr_resume();
fst_test_core_asr(
grammar,
"file_string://sounds/agent.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr_pause();
fst_test_core_asr_resume();
fst_test_core_asr(
grammar,
"file_string://sounds/agent.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr_close();
fst_test_core_asr_open("test");
fst_test_core_asr(
grammar,
"file_string://silence_stream://1000,0!sounds/ivr-please_state_your_name_and_reason_for_calling.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr_close();
}
FST_TEST_END()
FST_TEST_BEGIN(core_asr_auto_resume)
{
const char* session_id = "123435";
char *grammar = switch_core_sprintf(fst_pool, "{start-input-timers=true,no-input-timeout=5000,speech-timeout=10000,channel-uuid=%s}default", session_id);
fst_test_core_asr_open("test");
switch_set_flag(&ah, SWITCH_ASR_FLAG_AUTO_RESUME);
fst_test_core_asr(
grammar,
"file_string://silence_stream://3000,0!sounds/agent.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr(
grammar,
"silence_stream://30000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "no_input");
fst_test_core_asr(
grammar,
"file_string://sounds/agent.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr(
grammar,
"silence_stream://30000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "no_input");
fst_test_core_asr_resume();
fst_test_core_asr(
grammar,
"file_string://sounds/agent.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr_resume();
fst_test_core_asr(
grammar,
"file_string://silence_stream://1000,0!sounds/ivr-please_state_your_name_and_reason_for_calling.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr_close();
}
FST_TEST_END()
FST_TEST_BEGIN(core_asr_abuse)
{
const char* session_id = "5351514";
char *grammar = switch_core_sprintf(fst_pool, "{start-input-timers=true,no-input-timeout=5000,speech-timeout=10000,channel-uuid=%s}default", session_id);
fst_test_core_asr_open("test");
fst_test_core_asr(
grammar,
"file_string://silence_stream://3000,0!sounds/agent.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr_resume();
fst_test_core_asr_resume();
fst_test_core_asr_resume();
fst_test_core_asr_pause();
fst_test_core_asr_resume();
fst_test_core_asr(
grammar,
"file_string://sounds/agent.wav!silence_stream://3000,0");
fst_check_string_equals(get_query_result_text(fst_pool, fst_asr_result), "agent");
fst_test_core_asr_resume();
// Tested double-close, but FS core will crash...
fst_test_core_asr_close();
}
FST_TEST_END()
FST_SESSION_BEGIN(play_and_detect_1)
{
const char *result_text = NULL;
char *grammar = switch_core_session_sprintf(fst_session, "{start-input-timers=false,no-input-timeout=5000,speech-timeout=10000,channel-uuid=%s}default", switch_core_session_get_uuid(fst_session));
fst_play_and_detect_speech_test_begin();
/* initial welcome and request */
fst_play_and_detect_speech_app_test("test",
grammar,
"sounds/ivr-please_state_your_name_and_reason_for_calling.wav",
"sounds/agent.wav");
result_text = get_query_result_text(fst_pool, fst_asr_result);
fst_requires(result_text != NULL);
fst_check_string_equals(result_text, "agent");
/* follow up request */
fst_play_and_detect_speech_app_test("test",
grammar,
"sounds/ivr-please_state_your_name_and_reason_for_calling.wav",
"file_string://1000,0!sounds/agent.wav");
result_text = get_query_result_text(fst_pool, fst_asr_result);
fst_requires(result_text != NULL);
fst_check_string_equals(result_text, "agent");
fst_play_and_detect_speech_test_end();
}
FST_SESSION_END()
FST_SESSION_BEGIN(play_and_detect_no_input_follow_up)
{
const char *result_text = NULL;
char *grammar = switch_core_session_sprintf(fst_session, "{start-input-timers=false,no-input-timeout=5000,speech-timeout=10000,channel-uuid=%s}", switch_core_session_get_uuid(fst_session));
switch_ivr_schedule_hangup(switch_epoch_time_now(NULL) + 60, switch_core_session_get_uuid(fst_session), SWITCH_CAUSE_NORMAL_CLEARING, SWITCH_FALSE);
fst_play_and_detect_speech_test_begin();
fst_play_and_detect_speech_app_test("test",
grammar,
"sounds/ivr-please_state_your_name_and_reason_for_calling.wav",
"file_string://silence_stream://4000,0!sounds/agent.wav");
result_text = get_query_result_text(fst_pool, fst_asr_result);
fst_requires(result_text != NULL);
fst_check_string_equals(result_text, "agent");
/* follow up request - no input */
fst_play_and_detect_speech_app_test("test",
grammar,
"sounds/ivr-please_state_your_name_and_reason_for_calling.wav",
"silence_stream://10000,0");
result_text = get_query_result_text(fst_pool, fst_asr_result);
fst_requires(result_text != NULL);
fst_check_string_equals(result_text, "no_input");
fst_play_and_detect_speech_test_end();
}
FST_SESSION_END()
FST_SESSION_BEGIN(play_and_detect_no_input)
{
const char *result_text = NULL;
switch_ivr_schedule_hangup(switch_epoch_time_now(NULL) + 60, switch_core_session_get_uuid(fst_session), SWITCH_CAUSE_NORMAL_CLEARING, SWITCH_FALSE);
fst_play_and_detect_speech_test_begin();
fst_play_and_detect_speech_app_test("test",
switch_core_session_sprintf(fst_session,
"{start-input-timers=false,no-input-timeout=5000,speech-timeout=10000,channel-uuid=%s}default",
switch_core_session_get_uuid(fst_session)),
"sounds/ivr-please_state_your_name_and_reason_for_calling.wav",
"silence_stream://10000,0");
result_text = get_query_result_text(fst_pool, fst_asr_result);
fst_requires(result_text != NULL);
fst_check_string_equals(result_text, "no_input");
fst_play_and_detect_speech_test_end();
}
FST_SESSION_END()
FST_SESSION_BEGIN(play_and_detect_start_input_timers)
{
const char *result_text = NULL;
switch_ivr_schedule_hangup(switch_epoch_time_now(NULL) + 60, switch_core_session_get_uuid(fst_session), SWITCH_CAUSE_NORMAL_CLEARING, SWITCH_FALSE);
fst_play_and_detect_speech_test_begin();
fst_play_and_detect_speech_app_test("test",
switch_core_session_sprintf(fst_session,
"{start-input-timers=true,no-input-timeout=5000,speech-timeout=10000,channel-uuid=%s}default",
switch_core_session_get_uuid(fst_session)),
"sounds/ivr-please_state_your_name_and_reason_for_calling.wav",
"silence_stream://10000,0");
result_text = get_query_result_text(fst_pool, fst_asr_result);
fst_requires(result_text != NULL);
fst_check_string_equals(result_text, "no_input");
fst_play_and_detect_speech_test_end();
fst_check_duration(5000, 500);
}
FST_SESSION_END()
FST_TEST_BEGIN(unload_test)
{
const char *err = NULL;
switch_sleep(1000000);
fst_check(switch_loadable_module_unload_module((char *)"../.libs", (char *)"mod_test", SWITCH_FALSE, &err) == SWITCH_STATUS_SUCCESS);
}
FST_TEST_END()
FST_MODULE_END()
FST_CORE_END()

View File

@ -1220,6 +1220,7 @@ struct null_private_object {
switch_caller_profile_t *caller_profile;
switch_frame_t read_frame;
int16_t *null_buf;
int rate;
};
typedef struct null_private_object null_private_t;
@ -1239,20 +1240,19 @@ static switch_status_t null_channel_kill_channel(switch_core_session_t *session,
static switch_status_t null_tech_init(null_private_t *tech_pvt, switch_core_session_t *session)
{
const char *iananame = "L16";
uint32_t rate = 8000;
uint32_t interval = 20;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_channel_t *channel = switch_core_session_get_channel(session);
const switch_codec_implementation_t *read_impl;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s setup codec %s/%d/%d\n", switch_channel_get_name(channel), iananame, rate,
interval);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s setup codec %s/%d/%d\n",
switch_channel_get_name(channel), iananame, tech_pvt->rate, interval);
status = switch_core_codec_init(&tech_pvt->read_codec,
iananame,
NULL,
NULL,
rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));
tech_pvt->rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));
if (status != SWITCH_STATUS_SUCCESS || !tech_pvt->read_codec.implementation || !switch_core_codec_ready(&tech_pvt->read_codec)) {
goto end;
@ -1262,7 +1262,7 @@ static switch_status_t null_tech_init(null_private_t *tech_pvt, switch_core_sess
iananame,
NULL,
NULL,
rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));
tech_pvt->rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, switch_core_session_get_pool(session));
if (status != SWITCH_STATUS_SUCCESS) {
@ -1494,6 +1494,19 @@ static switch_call_cause_t null_channel_outgoing_channel(switch_core_session_t *
switch_core_session_add_stream(*new_session, NULL);
if ((tech_pvt = (null_private_t *) switch_core_session_alloc(*new_session, sizeof(null_private_t))) != 0) {
const char *rate_ = switch_event_get_header(var_event, "rate");
int rate = 0;
if (rate_) {
rate = atoi(rate_);
}
if (!(rate > 0 && rate % 8000 == 0)) {
rate = 8000;
}
tech_pvt->rate = rate;
channel = switch_core_session_get_channel(*new_session);
switch_snprintf(name, sizeof(name), "null/%s", outbound_profile->destination_number);
switch_channel_set_name(channel, name);

View File

@ -17,3 +17,5 @@ BUILT_SOURCES=$(IKS_LA)
$(IKS_LA): $(IKS_BUILDDIR) $(IKS_DIR) $(IKS_DIR)/.update
@cd $(IKS_BUILDDIR) && $(MAKE)
@$(TOUCH_TARGET)
SUBDIRS=. test

View File

@ -1,6 +1,6 @@
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013, Grasshopper
* Copyright (C) 2013-2018, Grasshopper
*
* Version: MPL 1.1
*
@ -51,50 +51,50 @@ struct xmpp_error {
#undef XMPP_ERROR
#define XMPP_ERROR(def_name, name, type) \
extern const struct xmpp_error def_name##_val; \
extern const struct xmpp_error *def_name;
SWITCH_DECLARE(const struct xmpp_error) def_name##_val; \
SWITCH_DECLARE(const struct xmpp_error *) def_name;
#include "xmpp_errors.def"
/* See RFC-3920 XMPP core for error definitions */
extern iks *iks_new_presence(const char *name, const char *namespace, const char *from, const char *to);
extern iks *iks_new_error(iks *iq, const struct xmpp_error *err);
extern iks *iks_new_error_detailed(iks *iq, const struct xmpp_error *err, const char *detail_text);
extern iks *iks_new_error_detailed_printf(iks *iq, const struct xmpp_error *err, const char *detail_text_format, ...);
extern iks *iks_new_iq_result(iks *iq);
extern const char *iks_find_attrib_soft(iks *xml, const char *attrib);
extern const char *iks_find_attrib_default(iks *xml, const char *attrib, const char *def);
extern int iks_find_bool_attrib(iks *xml, const char *attrib);
extern int iks_find_int_attrib(iks *xml, const char *attrib);
extern char iks_find_char_attrib(iks *xml, const char *attrib);
extern double iks_find_decimal_attrib(iks *xml, const char *attrib);
extern const char *iks_node_type_to_string(int type);
extern const char *iks_net_error_to_string(int err);
extern iks *iks_insert_attrib_printf(iks *xml, const char *name, const char *fmt, ...);
SWITCH_DECLARE(iks *) iks_new_presence(const char *name, const char *namespace, const char *from, const char *to);
SWITCH_DECLARE(iks *) iks_new_error(iks *iq, const struct xmpp_error *err);
SWITCH_DECLARE(iks *) iks_new_error_detailed(iks *iq, const struct xmpp_error *err, const char *detail_text);
SWITCH_DECLARE(iks *) iks_new_error_detailed_printf(iks *iq, const struct xmpp_error *err, const char *detail_text_format, ...);
SWITCH_DECLARE(iks *) iks_new_iq_result(iks *iq);
SWITCH_DECLARE(const char *) iks_find_attrib_soft(iks *xml, const char *attrib);
SWITCH_DECLARE(const char *) iks_find_attrib_default(iks *xml, const char *attrib, const char *def);
SWITCH_DECLARE(int) iks_find_bool_attrib(iks *xml, const char *attrib);
SWITCH_DECLARE(int) iks_find_int_attrib(iks *xml, const char *attrib);
SWITCH_DECLARE(char) iks_find_char_attrib(iks *xml, const char *attrib);
SWITCH_DECLARE(double) iks_find_decimal_attrib(iks *xml, const char *attrib);
SWITCH_DECLARE(const char *) iks_node_type_to_string(int type);
SWITCH_DECLARE(const char *) iks_net_error_to_string(int err);
SWITCH_DECLARE(iks *) iks_insert_attrib_printf(iks *xml, const char *name, const char *fmt, ...);
extern char *iks_server_dialback_key(const char *secret, const char *receiving_server, const char *originating_server, const char *stream_id);
extern void iks_sha_print_base64(iksha *sha, char *buf);
SWITCH_DECLARE(char *) iks_server_dialback_key(const char *secret, const char *receiving_server, const char *originating_server, const char *stream_id);
SWITCH_DECLARE(void) iks_sha_print_base64(iksha *sha, char *buf);
/** A function to validate attribute value */
typedef int (*iks_attrib_validation_function)(const char *);
extern int validate_optional_attrib(iks_attrib_validation_function fn, const char *attrib);
SWITCH_DECLARE(int) validate_optional_attrib(iks_attrib_validation_function fn, const char *attrib);
#define ELEMENT_DECL(name) extern int VALIDATE_##name(iks *node);
#define ELEMENT_DECL(name) SWITCH_DECLARE(int) VALIDATE_##name(iks *node);
#define ELEMENT(name) int VALIDATE_##name(iks *node) { int result = 1; if (!node) return 0;
#define ATTRIB(name, def, rule) result &= iks_attrib_is_##rule(iks_find_attrib_default(node, #name, #def));
#define OPTIONAL_ATTRIB(name, def, rule) result &= validate_optional_attrib(iks_attrib_is_##rule, iks_find_attrib_default(node, #name, #def));
#define STRING_ATTRIB(name, def, rule) result &= value_matches(iks_find_attrib_default(node, #name, #def), rule);
#define ELEMENT_END return result; }
extern int value_matches(const char *value, const char *rule);
SWITCH_DECLARE(int) value_matches(const char *value, const char *rule);
extern int iks_attrib_is_bool(const char *value);
extern int iks_attrib_is_not_negative(const char *value);
extern int iks_attrib_is_positive(const char *value);
extern int iks_attrib_is_positive_or_neg_one(const char *value);
extern int iks_attrib_is_any(const char *value);
extern int iks_attrib_is_decimal_between_zero_and_one(const char *value);
extern int iks_attrib_is_dtmf_digit(const char *value);
SWITCH_DECLARE(int) iks_attrib_is_bool(const char *value);
SWITCH_DECLARE(int) iks_attrib_is_not_negative(const char *value);
SWITCH_DECLARE(int) iks_attrib_is_positive(const char *value);
SWITCH_DECLARE(int) iks_attrib_is_positive_or_neg_one(const char *value);
SWITCH_DECLARE(int) iks_attrib_is_any(const char *value);
SWITCH_DECLARE(int) iks_attrib_is_decimal_between_zero_and_one(const char *value);
SWITCH_DECLARE(int) iks_attrib_is_dtmf_digit(const char *value);
#endif

View File

@ -1,6 +1,6 @@
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013, Grasshopper
* Copyright (C) 2013-2018, Grasshopper
*
* Version: MPL 1.1
*
@ -129,20 +129,20 @@ struct rayo_component {
#define RAYO_CALL(x) ((struct rayo_call *)x)
#define RAYO_MIXER(x) ((struct rayo_mixer *)x)
extern void rayo_message_send(struct rayo_actor *from, const char *to, iks *payload, int dup, int reply, const char *file, int line);
extern void rayo_message_destroy(struct rayo_message *msg);
extern iks *rayo_message_remove_payload(struct rayo_message *msg);
SWITCH_DECLARE(void) rayo_message_send(struct rayo_actor *from, const char *to, iks *payload, int dup, int reply, const char *file, int line);
SWITCH_DECLARE(void) rayo_message_destroy(struct rayo_message *msg);
SWITCH_DECLARE(iks *) rayo_message_remove_payload(struct rayo_message *msg);
#define RAYO_SEND_MESSAGE(from, to, payload) rayo_message_send(RAYO_ACTOR(from), to, payload, 0, 0, __FILE__, __LINE__)
#define RAYO_SEND_MESSAGE_DUP(from, to, payload) rayo_message_send(RAYO_ACTOR(from), to, payload, 1, 0, __FILE__, __LINE__)
#define RAYO_SEND_REPLY(from, to, payload) rayo_message_send(RAYO_ACTOR(from), to, payload, 0, 1, __FILE__, __LINE__)
#define RAYO_SEND_REPLY_DUP(from, to, payload) rayo_message_send(RAYO_ACTOR(from), to, payload, 1, 1, __FILE__, __LINE__)
extern struct rayo_actor *rayo_actor_locate(const char *jid, const char *file, int line);
extern struct rayo_actor *rayo_actor_locate_by_id(const char *id, const char *file, int line);
extern int rayo_actor_seq_next(struct rayo_actor *actor);
extern void rayo_actor_retain(struct rayo_actor *actor, const char *file, int line);
extern void rayo_actor_release(struct rayo_actor *actor, const char *file, int line);
extern void rayo_actor_destroy(struct rayo_actor *actor, const char *file, int line);
SWITCH_DECLARE(struct rayo_actor *) rayo_actor_locate(const char *jid, const char *file, int line);
SWITCH_DECLARE(struct rayo_actor *) rayo_actor_locate_by_id(const char *id, const char *file, int line);
SWITCH_DECLARE(int) rayo_actor_seq_next(struct rayo_actor *actor);
SWITCH_DECLARE(void) rayo_actor_retain(struct rayo_actor *actor, const char *file, int line);
SWITCH_DECLARE(void) rayo_actor_release(struct rayo_actor *actor, const char *file, int line);
SWITCH_DECLARE(void) rayo_actor_destroy(struct rayo_actor *actor, const char *file, int line);
#define RAYO_LOCATE(jid) rayo_actor_locate(jid, __FILE__, __LINE__)
#define RAYO_LOCATE_BY_ID(id) rayo_actor_locate_by_id(id, __FILE__, __LINE__)
@ -156,21 +156,21 @@ extern void rayo_actor_destroy(struct rayo_actor *actor, const char *file, int l
#define RAYO_DESTROY(x) rayo_actor_destroy(RAYO_ACTOR(x), __FILE__, __LINE__)
#define RAYO_SEQ_NEXT(x) rayo_actor_seq_next(RAYO_ACTOR(x))
extern int rayo_call_is_joined(struct rayo_call *call);
extern int rayo_call_is_faxing(struct rayo_call *call);
extern void rayo_call_set_faxing(struct rayo_call *call, int faxing);
extern const char *rayo_call_get_dcp_jid(struct rayo_call *call);
SWITCH_DECLARE(int) rayo_call_is_joined(struct rayo_call *call);
SWITCH_DECLARE(int) rayo_call_is_faxing(struct rayo_call *call);
SWITCH_DECLARE(void) rayo_call_set_faxing(struct rayo_call *call, int faxing);
SWITCH_DECLARE(const char *) rayo_call_get_dcp_jid(struct rayo_call *call);
#define rayo_mixer_get_name(mixer) RAYO_ID(mixer)
#define rayo_component_init(component, pool, type, subtype, id, parent, client_jid) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, NULL, __FILE__, __LINE__)
#define rayo_component_init_cleanup(component, pool, type, subtype, id, parent, client_jid, cleanup) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, cleanup, __FILE__, __LINE__)
extern struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, rayo_actor_cleanup_fn cleanup, const char *file, int line);
extern switch_bool_t is_component_actor(struct rayo_actor *);
SWITCH_DECLARE(struct rayo_component *) _rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, rayo_actor_cleanup_fn cleanup, const char *file, int line);
SWITCH_DECLARE(switch_bool_t) is_component_actor(struct rayo_actor *);
typedef iks *(*rayo_actor_xmpp_handler)(struct rayo_actor *, struct rayo_message *, void *);
extern void rayo_actor_command_handler_add(const char *type, const char *subtype, const char *name, rayo_actor_xmpp_handler fn);
extern void rayo_actor_event_handler_add(const char *from_type, const char *from_subtype, const char *to_type, const char *to_subtype, const char *name, rayo_actor_xmpp_handler fn);
SWITCH_DECLARE(void) rayo_actor_command_handler_add(const char *type, const char *subtype, const char *name, rayo_actor_xmpp_handler fn);
SWITCH_DECLARE(void) rayo_actor_event_handler_add(const char *from_type, const char *from_subtype, const char *to_type, const char *to_subtype, const char *name, rayo_actor_xmpp_handler fn);
#endif

View File

@ -1,6 +1,6 @@
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013-2014, Grasshopper
* Copyright (C) 2013-2018, Grasshopper
*
* Version: MPL 1.1
*
@ -30,6 +30,7 @@
#include <iksemel.h>
#include "nlsml.h"
#include "iks_helpers.h"
struct nlsml_parser;
@ -417,48 +418,60 @@ static int isdtmf(const char digit)
}
/**
* Construct an NLSML result for digit match
* @param digits the matching digits
* Construct an NLSML result for match
* @param match the matching digits or text
* @param interpretation the optional digit interpretation
* @param mode dtmf or speech
* @param confidence 0-100
* @return the NLSML <result>
*/
iks *nlsml_create_match(const char *match, const char *interpretation, const char *mode, int confidence)
{
iks *result = iks_new("result");
iks_insert_attrib(result, "xmlns", NLSML_NS);
iks_insert_attrib(result, "xmlns:xf", "http://www.w3.org/2000/xforms");
if (!zstr(match)) {
iks *interpretation_node = iks_insert(result, "interpretation");
iks *input_node = iks_insert(interpretation_node, "input");
iks *instance_node = iks_insert(interpretation_node, "instance");
iks_insert_attrib(input_node, "mode", mode);
iks_insert_attrib_printf(input_node, "confidence", "%d", confidence);
iks_insert_cdata(input_node, match, strlen(match));
if (zstr(interpretation)) {
iks_insert_cdata(instance_node, match, strlen(match));
} else {
iks_insert_cdata(instance_node, interpretation, strlen(interpretation));
}
}
return result;
}
/**
* Construct an NLSML result for match
* @param match the matching digits or text
* @param interpretation the optional digit interpretation
* @return the NLSML <result>
*/
iks *nlsml_create_dtmf_match(const char *digits, const char *interpretation)
{
iks *result = iks_new("result");
iks_insert_attrib(result, "xmlns", NLSML_NS);
iks_insert_attrib(result, "xmlns:xf", "http://www.w3.org/2000/xforms");
if (!zstr(digits)) {
int first = 1;
int i;
int num_digits = strlen(digits);
switch_stream_handle_t stream = { 0 };
iks *interpretation_node = iks_insert(result, "interpretation");
iks *input_node = iks_insert(interpretation_node, "input");
iks *instance_node = iks_insert(interpretation_node, "instance");
iks_insert_attrib(input_node, "mode", "dtmf");
iks_insert_attrib(input_node, "confidence", "100");
SWITCH_STANDARD_STREAM(stream);
for (i = 0; i < num_digits; i++) {
if (isdtmf(digits[i])) {
if (first) {
stream.write_function(&stream, "%c", digits[i]);
first = 0;
} else {
stream.write_function(&stream, " %c", digits[i]);
}
iks *result = NULL;
int first = 1;
int i;
int num_digits = strlen(digits);
switch_stream_handle_t stream = { 0 };
SWITCH_STANDARD_STREAM(stream);
for (i = 0; i < num_digits; i++) {
if (isdtmf(digits[i])) {
if (first) {
stream.write_function(&stream, "%c", digits[i]);
first = 0;
} else {
stream.write_function(&stream, " %c", digits[i]);
}
}
iks_insert_cdata(input_node, stream.data, strlen(stream.data));
if (zstr(interpretation)) {
iks_insert_cdata(instance_node, stream.data, strlen(stream.data));
} else {
iks_insert_cdata(instance_node, interpretation, strlen(interpretation));
}
switch_safe_free(stream.data);
}
result = nlsml_create_match((const char *)stream.data, interpretation, "dtmf", 100);
switch_safe_free(stream.data);
return result;
}

View File

@ -1,6 +1,6 @@
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013-2014, Grasshopper
* Copyright (C) 2013-2018, Grasshopper
*
* Version: MPL 1.1
*
@ -39,11 +39,12 @@ enum nlsml_match_type {
NMT_NOMATCH
};
extern int nlsml_init(void);
extern void nlsml_destroy(void);
enum nlsml_match_type nlsml_parse(const char *result, const char *uuid);
iks *nlsml_normalize(const char *result);
extern iks *nlsml_create_dtmf_match(const char *digits, const char *interpretation);
SWITCH_DECLARE(int) nlsml_init(void);
SWITCH_DECLARE(void) nlsml_destroy(void);
SWITCH_DECLARE(enum nlsml_match_type) nlsml_parse(const char *result, const char *uuid);
SWITCH_DECLARE(iks *) nlsml_normalize(const char *result);
SWITCH_DECLARE(iks *) nlsml_create_dtmf_match(const char *digits, const char *interpretation);
SWITCH_DECLARE(iks *) nlsml_create_match(const char *digits, const char *interpretation, const char *mode, int confidence);
#endif

View File

@ -60,37 +60,37 @@
#define COMPONENT_COMPLETE_HANGUP "hangup", RAYO_EXT_COMPLETE_NS
#define COMPONENT_COMPLETE_DONE "done", RAYO_EXT_COMPLETE_NS
extern switch_status_t rayo_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern switch_status_t rayo_input_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern switch_status_t rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern switch_status_t rayo_prompt_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern switch_status_t rayo_record_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern switch_status_t rayo_fax_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern switch_status_t rayo_exec_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
SWITCH_DECLARE(switch_status_t) rayo_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
SWITCH_DECLARE(switch_status_t) rayo_input_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
SWITCH_DECLARE(switch_status_t) rayo_output_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
SWITCH_DECLARE(switch_status_t) rayo_prompt_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
SWITCH_DECLARE(switch_status_t) rayo_record_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
SWITCH_DECLARE(switch_status_t) rayo_fax_components_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
SWITCH_DECLARE(switch_status_t) rayo_exec_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern switch_status_t rayo_components_shutdown(void);
extern switch_status_t rayo_input_component_shutdown(void);
extern switch_status_t rayo_output_component_shutdown(void);
extern switch_status_t rayo_prompt_component_shutdown(void);
extern switch_status_t rayo_record_component_shutdown(void);
extern switch_status_t rayo_fax_components_shutdown(void);
extern switch_status_t rayo_exec_component_shutdown(void);
SWITCH_DECLARE(switch_status_t) rayo_components_shutdown(void);
SWITCH_DECLARE(switch_status_t) rayo_input_component_shutdown(void);
SWITCH_DECLARE(switch_status_t) rayo_output_component_shutdown(void);
SWITCH_DECLARE(switch_status_t) rayo_prompt_component_shutdown(void);
SWITCH_DECLARE(switch_status_t) rayo_record_component_shutdown(void);
SWITCH_DECLARE(switch_status_t) rayo_fax_components_shutdown(void);
SWITCH_DECLARE(switch_status_t) rayo_exec_component_shutdown(void);
extern void rayo_component_send_start(struct rayo_component *component, iks *iq);
extern void rayo_component_send_iq_error(struct rayo_component *component, iks *iq, const char *error_name, const char *error_type);
extern void rayo_component_send_iq_error_detailed(struct rayo_component *component, iks *iq, const char *error_name, const char *error_type, const char *detail);
extern void rayo_component_send_complete(struct rayo_component *component, const char *reason, const char *reason_namespace);
extern void rayo_component_send_complete_event(struct rayo_component *component, iks *response);
extern void rayo_component_send_complete_with_metadata(struct rayo_component *component, const char *reason, const char *reason_namespace, iks *meta, int child_of_complete);
extern void rayo_component_send_complete_with_metadata_string(struct rayo_component *component, const char *reason, const char *reason_namespace, const char *meta, int child_of_complete);
SWITCH_DECLARE(void) rayo_component_send_start(struct rayo_component *component, iks *iq);
SWITCH_DECLARE(void) rayo_component_send_iq_error(struct rayo_component *component, iks *iq, const char *error_name, const char *error_type);
SWITCH_DECLARE(void) rayo_component_send_iq_error_detailed(struct rayo_component *component, iks *iq, const char *error_name, const char *error_type, const char *detail);
SWITCH_DECLARE(void) rayo_component_send_complete(struct rayo_component *component, const char *reason, const char *reason_namespace);
SWITCH_DECLARE(void) rayo_component_send_complete_event(struct rayo_component *component, iks *response);
SWITCH_DECLARE(void) rayo_component_send_complete_with_metadata(struct rayo_component *component, const char *reason, const char *reason_namespace, iks *meta, int child_of_complete);
SWITCH_DECLARE(void) rayo_component_send_complete_with_metadata_string(struct rayo_component *component, const char *reason, const char *reason_namespace, const char *meta, int child_of_complete);
extern iks *rayo_component_create_complete_event(struct rayo_component *component, const char *reason, const char *reason_namespace);
extern iks *rayo_component_create_complete_event_with_metadata(struct rayo_component *component, const char *reason, const char *reason_namespace, iks *meta, int child_of_complete);
SWITCH_DECLARE(iks *) rayo_component_create_complete_event(struct rayo_component *component, const char *reason, const char *reason_namespace);
SWITCH_DECLARE(iks *) rayo_component_create_complete_event_with_metadata(struct rayo_component *component, const char *reason, const char *reason_namespace, iks *meta, int child_of_complete);
extern void rayo_component_api_execute_async(struct rayo_component *component, const char *cmd, const char *args);
SWITCH_DECLARE(void) rayo_component_api_execute_async(struct rayo_component *component, const char *cmd, const char *args);
#define RAYO_COMPONENT_LOCATE(id) rayo_component_locate(id, __FILE__, __LINE__)
extern struct rayo_component *rayo_component_locate(const char *id, const char *file, int line);
SWITCH_DECLARE(struct rayo_component *) rayo_component_locate(const char *id, const char *file, int line);
#endif

View File

@ -34,9 +34,9 @@
#include "mod_rayo.h"
extern switch_status_t rayo_cpa_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern void rayo_cpa_component_shutdown(void);
extern iks *rayo_cpa_component_start(struct rayo_actor *call, struct rayo_message *msg, void *session_data);
SWITCH_DECLARE(switch_status_t) rayo_cpa_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
SWITCH_DECLARE(void) rayo_cpa_component_shutdown(void);
SWITCH_DECLARE(iks *) rayo_cpa_component_start(struct rayo_actor *call, struct rayo_message *msg, void *session_data);
#endif

View File

@ -33,10 +33,10 @@
#include "mod_rayo.h"
extern switch_status_t rayo_cpa_detector_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern void rayo_cpa_detector_shutdown(void);
extern int rayo_cpa_detector_start(const char *call_uuid, const char *signal_ns, const char **error_detail);
extern void rayo_cpa_detector_stop(const char *call_uuid, const char *signal_ns);
SWITCH_DECLARE(switch_status_t) rayo_cpa_detector_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
SWITCH_DECLARE(void) rayo_cpa_detector_shutdown(void);
SWITCH_DECLARE(int) rayo_cpa_detector_start(const char *call_uuid, const char *signal_ns, const char **error_detail);
SWITCH_DECLARE(void) rayo_cpa_detector_stop(const char *call_uuid, const char *signal_ns);
#endif

View File

@ -1,6 +1,6 @@
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013, Grasshopper
* Copyright (C) 2013-2018, Grasshopper
*
* Version: MPL 1.1
*
@ -42,7 +42,6 @@ ELEMENT(RAYO_INPUT)
ATTRIB(sensitivity, 0.5, decimal_between_zero_and_one)
ATTRIB(min-confidence, 0, decimal_between_zero_and_one)
ATTRIB(max-silence, -1, positive_or_neg_one)
/* for now, only NLSML */
STRING_ATTRIB(match-content-type, application/nlsml+xml, "application/nlsml+xml")
/* internal attribs for prompt support */
ATTRIB(barge-event, false, bool)
@ -72,6 +71,7 @@ ELEMENT(RAYO_OUTPUT)
ATTRIB(max-time, -1, positive_or_neg_one)
ATTRIB(renderer,, any)
ATTRIB(voice,, any)
STRING_ATTRIB(direction, out, "out,in")
ELEMENT_END
/**

View File

@ -415,7 +415,7 @@ static int validate_call_input(iks *input, const char **error)
if (!zstr(iks_find_attrib(grammar, "url"))) {
*error = "url not allowed with content-type";
return 0;
} else if (strcmp("application/srgs+xml", content_type)) {
} else if (strcmp("application/srgs+xml", content_type) && strcmp("text/plain", content_type)) {
*error = "Unsupported content type";
return 0;
}
@ -876,6 +876,30 @@ static iks *start_timers_call_input_component(struct rayo_actor *component, stru
return iks_new_iq_result(iq);
}
/**
* Get text / error from result
*/
static const char *get_detected_speech_result_text(cJSON *result_json, double *confidence, const char **error_text)
{
const char *result_text = NULL;
const char *text = cJSON_GetObjectCstr(result_json, "text");
if (confidence) {
*confidence = 0.0;
}
if (!zstr(text)) {
cJSON *json_confidence = cJSON_GetObjectItem(result_json, "confidence");
if (json_confidence && json_confidence->valuedouble > 0.0) {
*confidence = json_confidence->valuedouble;
} else {
*confidence = 0.99;
}
result_text = text;
} else if (error_text) {
*error_text = cJSON_GetObjectCstr(result_json, "error");
}
return result_text;
}
/**
* Handle speech detection event
*/
@ -905,7 +929,50 @@ static void on_detected_speech_event(switch_event_t *event)
if (zstr(result)) {
rayo_component_send_complete(component, INPUT_NOMATCH);
} else {
if (strchr(result, '<')) {
if (result[0] == '{') {
// internal FS JSON format
cJSON *json_result = cJSON_Parse(result);
if (json_result) {
// examine result to determine what happened
double confidence = 0.0;
const char *error_text = NULL;
const char *result_text = NULL;
result_text = get_detected_speech_result_text(json_result, &confidence, &error_text);
if (!zstr(result_text)) {
// got result... send as NLSML
iks *result = nlsml_create_match(result_text, NULL, "speech", (int)(confidence * 100.0));
/* notify of match */
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "MATCH = %s\n", result_text);
send_match_event(RAYO_COMPONENT(component), result);
iks_delete(result);
} else if (zstr(error_text)) {
// unknown error
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_WARNING, "No matching text nor error in result: %s!\n", result);
rayo_component_send_complete(component, INPUT_NOMATCH);
} else if (!strcmp(error_text, "no_input")) {
// no input error
rayo_component_send_complete(component, INPUT_NOINPUT);
} else if (!strcmp(error_text, "no_match")) {
// no match error
rayo_component_send_complete(component, INPUT_NOMATCH);
} else {
// generic error
iks *response = rayo_component_create_complete_event(component, COMPONENT_COMPLETE_ERROR);
iks *error = NULL;
if ((error = iks_find(response, "complete"))) {
if ((error = iks_find(error, "error"))) {
iks_insert_cdata(error, error_text, strlen(error_text));
}
}
rayo_component_send_complete_event(component, response);
}
cJSON_Delete(json_result);
} else {
// failed to parse JSON result
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_WARNING, "Failed to parse JSON result: %s!\n", result);
rayo_component_send_complete(component, INPUT_NOMATCH);
}
} else if (strchr(result, '<')) {
/* got an XML result */
enum nlsml_match_type match_type = nlsml_parse(result, uuid);
switch (match_type) {

View File

@ -1,6 +1,6 @@
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013-2016, Grasshopper
* Copyright (C) 2013-2018, Grasshopper
*
* Version: MPL 1.1
*
@ -53,6 +53,8 @@ struct output_component {
const char *renderer;
/** optional headers to pass to renderer */
const char *headers;
/** audio direction */
const char *direction;
};
#define OUTPUT_FINISH "finish", RAYO_OUTPUT_COMPLETE_NS
@ -79,6 +81,7 @@ static struct rayo_component *create_output_component(struct rayo_actor *actor,
output_component->max_time_ms = iks_find_int_attrib(output, "max-time");
output_component->start_paused = iks_find_bool_attrib(output, "start-paused");
output_component->renderer = switch_core_strdup(RAYO_POOL(output_component), iks_find_attrib_soft(output, "renderer"));
output_component->direction = strcmp(iks_find_attrib_soft(output, "direction"), "in") ? "m" : "mr";
output_component->headers = NULL;
/* get custom headers */
{
@ -136,7 +139,7 @@ static iks *start_call_output(struct rayo_component *component, switch_core_sess
}
stream.write_function(&stream, "}fileman://rayo://%s", RAYO_JID(component));
if (switch_ivr_displace_session(session, stream.data, 0, "m") == SWITCH_STATUS_SUCCESS) {
if (switch_ivr_displace_session(session, stream.data, 0, OUTPUT_COMPONENT(component)->direction) == SWITCH_STATUS_SUCCESS) {
RAYO_RELEASE(component);
} else {
if (component->complete) {

View File

@ -1,6 +1,6 @@
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013, Grasshopper
* Copyright (C) 2013-2018, Grasshopper
*
* Version: MPL 1.1
*
@ -29,7 +29,7 @@
#ifndef SASL_H
#define SASL_H
extern void parse_plain_auth_message(const char *message, char **authzid, char **authcid, char **password);
SWITCH_DECLARE(void) parse_plain_auth_message(const char *message, char **authzid, char **authcid, char **password);
#endif

View File

@ -1,6 +1,6 @@
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013-2014, Grasshopper
* Copyright (C) 2013-2018, Grasshopper
*
* Version: MPL 1.1
*
@ -45,15 +45,15 @@ enum srgs_match_type {
SMT_MATCH_END
};
extern int srgs_init(void);
extern void srgs_destroy(void);
extern struct srgs_parser *srgs_parser_new(const char *uuid);
extern struct srgs_grammar *srgs_parse(struct srgs_parser *parser, const char *document);
extern const char *srgs_grammar_to_regex(struct srgs_grammar *grammar);
extern const char *srgs_grammar_to_jsgf(struct srgs_grammar *grammar);
extern const char *srgs_grammar_to_jsgf_file(struct srgs_grammar *grammar, const char *basedir, const char *ext);
extern enum srgs_match_type srgs_grammar_match(struct srgs_grammar *grammar, const char *input, const char **interpretation);
extern void srgs_parser_destroy(struct srgs_parser *parser);
SWITCH_DECLARE(int) srgs_init(void);
SWITCH_DECLARE(void) srgs_destroy(void);
SWITCH_DECLARE(struct srgs_parser *) srgs_parser_new(const char *uuid);
SWITCH_DECLARE(struct srgs_grammar *) srgs_parse(struct srgs_parser *parser, const char *document);
SWITCH_DECLARE(const char *) srgs_grammar_to_regex(struct srgs_grammar *grammar);
SWITCH_DECLARE(const char *) srgs_grammar_to_jsgf(struct srgs_grammar *grammar);
SWITCH_DECLARE(const char *) srgs_grammar_to_jsgf_file(struct srgs_grammar *grammar, const char *basedir, const char *ext);
SWITCH_DECLARE(enum srgs_match_type) srgs_grammar_match(struct srgs_grammar *grammar, const char *input, const char **interpretation);
SWITCH_DECLARE(void) srgs_parser_destroy(struct srgs_parser *parser);
#endif

View File

@ -1,101 +0,0 @@
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013, Grasshopper
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is Grasshopper
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Rienzo <chris.rienzo@grasshopper.com>
*
* test.h -- simple unit testing macros
*
*/
#ifndef TEST_H
#define TEST_H
#define assert_equals(test, expected_str, expected, actual, file, line) \
{ \
int actual_val = actual; \
if (expected != actual_val) { \
printf("TEST\t%s\tFAIL\t%s\t%i\t!=\t%i\t%s:%i\n", test, expected_str, expected, actual_val, file, line); \
exit(1); \
} else { \
printf("TEST\t%s\tPASS\n", test); \
} \
}
#define assert_string_equals(test, expected, actual, file, line) \
{ \
const char *actual_str = actual; \
if (!actual_str || strcmp(expected, actual_str)) { \
printf("TEST\t%s\tFAIL\t\t%s\t!=\t%s\t%s:%i\n", test, expected, actual_str, file, line); \
exit(1); \
} else { \
printf("TEST\t%s\tPASS\n", test); \
} \
}
#define assert_not_null(test, actual, file, line) \
{ \
const void *actual_val = actual; \
if (!actual_val) { \
printf("TEST\t%s\tFAIL\t\t\t\t\t%s:%i\n", test, file, line); \
exit(1); \
} else { \
printf("TEST\t%s\tPASS\n", test); \
} \
}
#define assert_null(test, actual, file, line) \
{ \
const void *actual_val = actual; \
if (actual_val) { \
printf("TEST\t%s\tFAIL\t\t\t\t\t%s:%i\n", test, file, line); \
exit(1); \
} else { \
printf("TEST\t%s\tPASS\n", test); \
} \
}
#define ASSERT_EQUALS(expected, actual) assert_equals(#actual, #expected, expected, actual, __FILE__, __LINE__)
#define ASSERT_STRING_EQUALS(expected, actual) assert_string_equals(#actual, expected, actual, __FILE__, __LINE__)
#define ASSERT_NOT_NULL(actual) assert_not_null(#actual " not null", actual, __FILE__, __LINE__)
#define ASSERT_NULL(actual) assert_null(#actual " is null", actual, __FILE__, __LINE__)
#define SKIP_ASSERT_EQUALS(expected, actual) if (0) { ASSERT_EQUALS(expected, actual); }
#define TEST(name) printf("TEST BEGIN\t" #name "\n"); name(); printf("TEST END\t"#name "\tPASS\n");
#define SKIP_TEST(name) if (0) { TEST(name) };
#define TEST_INIT switch_core_init(0, SWITCH_TRUE, &err);
#endif
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet
*/

View File

@ -0,0 +1,13 @@
include $(top_srcdir)/build/modmake.rulesam
bin_PROGRAMS = test_iks test_nlsml test_srgs
test_iks_CFLAGS = $(AM_CFLAGS) -I../ -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS)
test_iks_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) ../mod_rayo.la $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
test_nlsml_CFLAGS = $(AM_CFLAGS) -I../ -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS)
test_nlsml_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) ../mod_rayo.la $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
test_srgs_CFLAGS = $(AM_CFLAGS) -I../ -I$(switch_builddir)/libs/iksemel/include $(PCRE_CFLAGS)
test_srgs_LDFLAGS = $(AM_LDFLAGS) -avoid-version -no-undefined $(freeswitch_LDFLAGS) ../mod_rayo.la $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
TESTS = $(bin_PROGRAMS)

View File

@ -0,0 +1,204 @@
#include <switch.h>
#include <iksemel.h>
#include <test/switch_test.h>
#include <iks_helpers.h>
static const char *voxeo_grammar =
"<iq id='8847' type='set' from='usera@192.168.1.10/voxeo3' to='e7632f74-8c55-11e2-84b0-e538fa88a1ef@192.168.1.10'><input xmlns='urn:xmpp:rayo:input:1' min-confidence='0.3' mode='DTMF' sensitivity='0.5'><grammar content-type='application/grammar+voxeo'><![CDATA[[1 DIGITS]]]></grammar></input></iq>";
static const char *repeating_bracket =
"<iq id='8847' type='set' from='usera@192.168.1.10/voxeo3' to='e7632f74-8c55-11e2-84b0-e538fa88a1ef@192.168.1.10'><input xmlns='urn:xmpp:rayo:input:1' min-confidence='0.3' mode='DTMF' sensitivity='0.5'><grammar content-type='application/grammar+voxeo'><![CDATA[[1 DIGITS]>]]]]]]]]] ]] ]]></grammar></input></iq>";
static const char *normal_cdata =
"<iq id='8847' type='set' from='usera@192.168.1.10/voxeo3' to='e7632f74-8c55-11e2-84b0-e538fa88a1ef@192.168.1.10'><input xmlns='urn:xmpp:rayo:input:1' min-confidence='0.3' mode='DTMF' sensitivity='0.5'><grammar content-type='application/grammar+voxeo'><![CDATA[1 DIGITS]]></grammar></input></iq>";
static const char *empty_cdata =
"<iq id='8847' type='set' from='usera@192.168.1.10/voxeo3' to='e7632f74-8c55-11e2-84b0-e538fa88a1ef@192.168.1.10'><input xmlns='urn:xmpp:rayo:input:1' min-confidence='0.3' mode='DTMF' sensitivity='0.5'><grammar content-type='application/grammar+voxeo'><![CDATA[]]></grammar></input></iq>";
static const char *rayo_test_srgs =
"<grammar xmlns=\"http://www.w3.org/2001/06/grammar\" root=\"MAINRULE\">\n"
" <rule id=\"MAINRULE\">\n"
" <one-of>\n"
" <item>\n"
" <item repeat=\"0-1\"> need a</item>\n"
" <item repeat=\"0-1\"> i need a</item>\n"
" <one-of>\n"
" <item> clue </item>\n"
" </one-of>\n"
" <tag> out.concept = \"clue\";</tag>\n"
" </item>\n"
" <item>\n"
" <item repeat=\"0-1\"> have an</item>\n"
" <item repeat=\"0-1\"> i have an</item>\n"
" <one-of>\n"
" <item> answer </item>\n"
" </one-of>\n"
" <tag> out.concept = \"answer\";</tag>\n"
" </item>\n"
" </one-of>\n"
" </rule>\n"
"</grammar>";
#define MATCH 1
#define NO_MATCH 0
/**
* main program
*/
FST_BEGIN()
FST_SUITE_BEGIN(iks)
FST_SETUP_BEGIN()
{
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
FST_TEST_BEGIN(iks_cdata_bug)
{
iks *iq = NULL;
iks *input = NULL;
iksparser *p = iks_dom_new(&iq);
const char *cdata;
fst_check(IKS_OK == iks_parse(p, voxeo_grammar, 0, 1));
iks_parser_delete(p);
fst_check((input = iks_find(iq, "input")));
fst_check((cdata = iks_find_cdata(input, "grammar")));
fst_check_string_equals("[1 DIGITS]", cdata);
iks_delete(iq);
}
FST_TEST_END()
FST_TEST_BEGIN(repeating_bracket)
{
iks *iq = NULL;
iks *input = NULL;
iksparser *p = iks_dom_new(&iq);
const char *cdata;
fst_check(IKS_OK == iks_parse(p, repeating_bracket, 0, 1));
iks_parser_delete(p);
fst_check((input = iks_find(iq, "input")));
fst_check((cdata = iks_find_cdata(input, "grammar")));
fst_check_string_equals("[1 DIGITS]>]]]]]]]]] ]] ", cdata);
iks_delete(iq);
}
FST_TEST_END()
FST_TEST_BEGIN(normal_cdata)
{
iks *iq = NULL;
iks *input = NULL;
iksparser *p = iks_dom_new(&iq);
const char *cdata;
fst_check(IKS_OK == iks_parse(p, normal_cdata, 0, 1));
iks_parser_delete(p);
fst_check((input = iks_find(iq, "input")));
fst_check((cdata = iks_find_cdata(input, "grammar")));
fst_check_string_equals("1 DIGITS", cdata);
iks_delete(iq);
}
FST_TEST_END()
FST_TEST_BEGIN(empty_cdata)
{
iks *iq = NULL;
iks *input = NULL;
iksparser *p = iks_dom_new(&iq);
const char *cdata;
fst_check(IKS_OK == iks_parse(p, empty_cdata, 0, 1));
iks_parser_delete(p);
fst_check((input = iks_find(iq, "input")));
fst_check(NULL == (cdata = iks_find_cdata(input, "grammar")));
iks_delete(iq);
}
FST_TEST_END()
FST_TEST_BEGIN(rayo_test_srgs)
{
iks *grammar = NULL;
iksparser *p = iks_dom_new(&grammar);
fst_check(IKS_OK == iks_parse(p, rayo_test_srgs, 0, 1));
iks_parser_delete(p);
iks_delete(grammar);
}
FST_TEST_END()
FST_TEST_BEGIN(iks_helper_value_matches)
{
fst_check(MATCH == value_matches("1", "1,2,3"));
fst_check(MATCH == value_matches("2", "1,2,3"));
fst_check(MATCH == value_matches("3", "1,2,3"));
fst_check(NO_MATCH == value_matches("4", "1,2,3"));
fst_check(NO_MATCH == value_matches("1,2", "1,2,3"));
fst_check(NO_MATCH == value_matches(NULL, "1,2,3"));
fst_check(NO_MATCH == value_matches(NULL, NULL));
fst_check(NO_MATCH == value_matches("1", NULL));
fst_check(NO_MATCH == value_matches("", "1,2,3"));
fst_check(NO_MATCH == value_matches("", ""));
fst_check(NO_MATCH == value_matches("1", ""));
fst_check(MATCH == value_matches("duplex", "duplex,send,recv"));
fst_check(MATCH == value_matches("send", "duplex,send,recv"));
fst_check(MATCH == value_matches("recv", "duplex,send,recv"));
fst_check(NO_MATCH == value_matches("sendrecv", "duplex,send,recv"));
fst_check(MATCH == value_matches("duplex1", "duplex1,duplex2,duplex3"));
fst_check(MATCH == value_matches("duplex2", "duplex1,duplex2,duplex3"));
fst_check(MATCH == value_matches("duplex3", "duplex1,duplex2,duplex3"));
fst_check(NO_MATCH == value_matches("duplex4", "duplex1,duplex2,duplex3"));
fst_check(NO_MATCH == value_matches("duplex", "duplex1,duplex2,duplex3"));
}
FST_TEST_END()
FST_TEST_BEGIN(dialback_key)
{
fst_check_string_equals("37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643", iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "example.org", "D60000229F"));
fst_check(NULL == iks_server_dialback_key("", "xmpp.example.com", "example.org", "D60000229F"));
fst_check(NULL == iks_server_dialback_key("s3cr3tf0rd14lb4ck", "", "example.org", "D60000229F"));
fst_check(NULL == iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "", "D60000229F"));
fst_check(NULL == iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "example.org", ""));
fst_check(NULL == iks_server_dialback_key(NULL, "xmpp.example.com", "example.org", "D60000229F"));
fst_check(NULL == iks_server_dialback_key("s3cr3tf0rd14lb4ck", NULL, "example.org", "D60000229F"));
fst_check(NULL == iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", NULL, "D60000229F"));
fst_check(NULL == iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "example.org", NULL));
}
FST_TEST_END()
FST_TEST_BEGIN(validate_dtmf)
{
fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("1"));
fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("A"));
fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("a"));
fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("D"));
fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("d"));
fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("*"));
fst_check(SWITCH_TRUE == iks_attrib_is_dtmf_digit("#"));
fst_check(SWITCH_FALSE == iks_attrib_is_dtmf_digit("E"));
fst_check(SWITCH_FALSE == iks_attrib_is_dtmf_digit(NULL));
fst_check(SWITCH_FALSE == iks_attrib_is_dtmf_digit(""));
fst_check(SWITCH_FALSE == iks_attrib_is_dtmf_digit("11"));
fst_check(SWITCH_TRUE == validate_optional_attrib(iks_attrib_is_dtmf_digit, "A"));
fst_check(SWITCH_TRUE == validate_optional_attrib(iks_attrib_is_dtmf_digit, "1"));
fst_check(SWITCH_FALSE == validate_optional_attrib(iks_attrib_is_dtmf_digit, "Z"));
fst_check(SWITCH_FALSE == validate_optional_attrib(iks_attrib_is_dtmf_digit, "11"));
fst_check(SWITCH_TRUE == validate_optional_attrib(iks_attrib_is_dtmf_digit, NULL));
fst_check(SWITCH_TRUE == validate_optional_attrib(iks_attrib_is_dtmf_digit, ""));
}
FST_TEST_END()
FST_SUITE_END()
FST_END()

View File

@ -1,8 +1,8 @@
#include <switch.h>
#include "test.h"
#include "nlsml.h"
#include <test/switch_test.h>
#include <nlsml.h>
static const char *nlsml_good =
"<result x-model=\"http://theYesNoModel\""
@ -224,22 +224,6 @@ static const char *nlsml_no_match =
" </interpretation>\n"
"</result>\n";
/**
* Test parsing NLSML example results
*/
static void test_parse_nlsml_examples(void)
{
ASSERT_EQUALS(NMT_MATCH, nlsml_parse(nlsml_good, "1234"));
ASSERT_EQUALS(NMT_BAD_XML, nlsml_parse(nlsml_bad, "1234"));
ASSERT_EQUALS(NMT_MATCH, nlsml_parse(nlsml_match_with_model_instance, "1234"));
ASSERT_EQUALS(NMT_MATCH, nlsml_parse(nlsml_multi_input, "1234"));
ASSERT_EQUALS(NMT_NOINPUT, nlsml_parse(nlsml_no_input, "1234"));
ASSERT_EQUALS(NMT_MATCH, nlsml_parse(nlsml_multi_input_dtmf, "1234"));
ASSERT_EQUALS(NMT_MATCH, nlsml_parse(nlsml_meta, "1234"));
ASSERT_EQUALS(NMT_MATCH, nlsml_parse(nlsml_simple_ambiguity, "1234"));
ASSERT_EQUALS(NMT_MATCH, nlsml_parse(nlsml_mixed_initiative, "1234"));
ASSERT_EQUALS(NMT_NOMATCH, nlsml_parse(nlsml_no_match, "1234"));
}
static const char *nlsml_dtmf_result =
"<result xmlns='http://www.ietf.org/xml/ns/mrcpv2' "
@ -248,38 +232,6 @@ static const char *nlsml_dtmf_result =
"<instance>1 2 3 4</instance>"
"</interpretation></result>";
/**
* Test creating DTMF match result
*/
static void test_create_dtmf_match(void)
{
iks *result = nlsml_create_dtmf_match("1234", NULL);
char *result_str;
ASSERT_NOT_NULL(result);
result_str = iks_string(NULL, result);
ASSERT_STRING_EQUALS(nlsml_dtmf_result, result_str);
iks_free(result_str);
}
static const char *nlsml_dtmf_instance_result =
"<result xmlns='http://www.ietf.org/xml/ns/mrcpv2' "
"xmlns:xf='http://www.w3.org/2000/xforms'><interpretation>"
"<input mode='dtmf' confidence='100'>1</input>"
"<instance>foo</instance>"
"</interpretation></result>";
/**
* Test creating DTMF match result with instance interpretation
*/
static void test_create_dtmf_instance(void)
{
iks *result = nlsml_create_dtmf_match("1", "foo");
char *result_str;
ASSERT_NOT_NULL(result);
result_str = iks_string(NULL, result);
ASSERT_STRING_EQUALS(nlsml_dtmf_instance_result, result_str);
iks_free(result_str);
}
static const char *nlsml_good_normalized =
"<result x-model='http://theYesNoModel'"
@ -296,28 +248,89 @@ static const char *nlsml_good_normalized =
"</interpretation>"
"</result>";
static const char *nlsml_dtmf_instance_result =
"<result xmlns='http://www.ietf.org/xml/ns/mrcpv2' "
"xmlns:xf='http://www.w3.org/2000/xforms'><interpretation>"
"<input mode='dtmf' confidence='100'>1</input>"
"<instance>foo</instance>"
"</interpretation></result>";
FST_BEGIN()
FST_SUITE_BEGIN(nlsml)
FST_SETUP_BEGIN()
{
fst_requires(nlsml_init());
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
/**
* Test parsing NLSML example results
*/
FST_TEST_BEGIN(parse_nlsml_examples)
{
fst_check(NMT_MATCH == nlsml_parse(nlsml_good, "1234"));
fst_check(NMT_BAD_XML == nlsml_parse(nlsml_bad, "1234"));
fst_check(NMT_MATCH == nlsml_parse(nlsml_match_with_model_instance, "1234"));
fst_check(NMT_MATCH == nlsml_parse(nlsml_multi_input, "1234"));
fst_check(NMT_NOINPUT == nlsml_parse(nlsml_no_input, "1234"));
fst_check(NMT_MATCH == nlsml_parse(nlsml_multi_input_dtmf, "1234"));
fst_check(NMT_MATCH == nlsml_parse(nlsml_meta, "1234"));
fst_check(NMT_MATCH == nlsml_parse(nlsml_simple_ambiguity, "1234"));
fst_check(NMT_MATCH == nlsml_parse(nlsml_mixed_initiative, "1234"));
fst_check(NMT_NOMATCH == nlsml_parse(nlsml_no_match, "1234"));
}
FST_TEST_END()
/**
* Test creating DTMF match result
*/
FST_TEST_BEGIN(create_dtmf_match)
{
iks *result = nlsml_create_dtmf_match("1234", NULL);
char *result_str;
fst_requires(result);
result_str = iks_string(NULL, result);
fst_check_string_equals(nlsml_dtmf_result, result_str);
iks_free(result_str);
}
FST_TEST_END()
/**
* Test creating DTMF match result with instance interpretation
*/
FST_TEST_BEGIN(create_dtmf_instance)
{
iks *result = nlsml_create_dtmf_match("1", "foo");
char *result_str;
fst_requires(result);
result_str = iks_string(NULL, result);
fst_check_string_equals(nlsml_dtmf_instance_result, result_str);
iks_free(result_str);
}
FST_TEST_END()
/**
* Test NLSML normalization
*/
static void test_normalize(void)
FST_TEST_BEGIN(normalize)
{
iks *result = nlsml_normalize(nlsml_good);
ASSERT_NOT_NULL(result);
ASSERT_STRING_EQUALS(nlsml_good_normalized, iks_string(NULL, result));
fst_requires(result);
fst_check_string_equals(nlsml_good_normalized, iks_string(NULL, result));
}
FST_TEST_END()
/**
* main program
*/
int main(int argc, char **argv)
{
const char *err;
TEST_INIT
nlsml_init();
TEST(test_parse_nlsml_examples);
TEST(test_create_dtmf_match);
TEST(test_create_dtmf_instance);
TEST(test_normalize);
return 0;
}
FST_SUITE_END()
FST_END()

View File

@ -1,18 +0,0 @@
BASE=../../../../..
IKS_DIR=$(BASE)/libs/iksemel
IKS_LA=$(IKS_DIR)/src/libiksemel.la
LOCAL_CFLAGS += -I../ -I$(BASE)/libs/iksemel/include
LOCAL_OBJS= $(PCRE_LA) $(IKS_LA) main.o ../iks_helpers.o
LOCAL_SOURCES= main.c
include $(BASE)/build/modmake.rules
$(IKS_LA): $(IKS_DIR) $(IKS_DIR)/.update
@cd $(IKS_DIR) && $(MAKE)
@$(TOUCH_TARGET)
local_all:
libtool --mode=link gcc main.o ../iks_helpers.o -o test test_iks.la
local_clean:
-rm test

View File

@ -1,185 +0,0 @@
#include <switch.h>
#include <iksemel.h>
#include "test.h"
#include "iks_helpers.h"
static const char *voxeo_grammar =
"<iq id='8847' type='set' from='usera@192.168.1.10/voxeo3' to='e7632f74-8c55-11e2-84b0-e538fa88a1ef@192.168.1.10'><input xmlns='urn:xmpp:rayo:input:1' min-confidence='0.3' mode='DTMF' sensitivity='0.5'><grammar content-type='application/grammar+voxeo'><![CDATA[[1 DIGITS]]]></grammar></input></iq>";
static void test_iks_cdata_bug(void)
{
iks *iq = NULL;
iks *input = NULL;
iksparser *p = iks_dom_new(&iq);
const char *cdata;
ASSERT_EQUALS(IKS_OK, iks_parse(p, voxeo_grammar, 0, 1));
iks_parser_delete(p);
ASSERT_NOT_NULL((input = iks_find(iq, "input")));
ASSERT_NOT_NULL((cdata = iks_find_cdata(input, "grammar")));
ASSERT_STRING_EQUALS("[1 DIGITS]", cdata);
iks_delete(iq);
}
static const char *repeating_bracket =
"<iq id='8847' type='set' from='usera@192.168.1.10/voxeo3' to='e7632f74-8c55-11e2-84b0-e538fa88a1ef@192.168.1.10'><input xmlns='urn:xmpp:rayo:input:1' min-confidence='0.3' mode='DTMF' sensitivity='0.5'><grammar content-type='application/grammar+voxeo'><![CDATA[[1 DIGITS]>]]]]]]]]] ]] ]]></grammar></input></iq>";
static void test_repeating_bracket(void)
{
iks *iq = NULL;
iks *input = NULL;
iksparser *p = iks_dom_new(&iq);
const char *cdata;
ASSERT_EQUALS(IKS_OK, iks_parse(p, repeating_bracket, 0, 1));
iks_parser_delete(p);
ASSERT_NOT_NULL((input = iks_find(iq, "input")));
ASSERT_NOT_NULL((cdata = iks_find_cdata(input, "grammar")));
ASSERT_STRING_EQUALS("[1 DIGITS]>]]]]]]]]] ]] ", cdata);
iks_delete(iq);
}
static const char *normal_cdata =
"<iq id='8847' type='set' from='usera@192.168.1.10/voxeo3' to='e7632f74-8c55-11e2-84b0-e538fa88a1ef@192.168.1.10'><input xmlns='urn:xmpp:rayo:input:1' min-confidence='0.3' mode='DTMF' sensitivity='0.5'><grammar content-type='application/grammar+voxeo'><![CDATA[1 DIGITS]]></grammar></input></iq>";
static void test_normal_cdata(void)
{
iks *iq = NULL;
iks *input = NULL;
iksparser *p = iks_dom_new(&iq);
const char *cdata;
ASSERT_EQUALS(IKS_OK, iks_parse(p, normal_cdata, 0, 1));
iks_parser_delete(p);
ASSERT_NOT_NULL((input = iks_find(iq, "input")));
ASSERT_NOT_NULL((cdata = iks_find_cdata(input, "grammar")));
ASSERT_STRING_EQUALS("1 DIGITS", cdata);
iks_delete(iq);
}
static const char *empty_cdata =
"<iq id='8847' type='set' from='usera@192.168.1.10/voxeo3' to='e7632f74-8c55-11e2-84b0-e538fa88a1ef@192.168.1.10'><input xmlns='urn:xmpp:rayo:input:1' min-confidence='0.3' mode='DTMF' sensitivity='0.5'><grammar content-type='application/grammar+voxeo'><![CDATA[]]></grammar></input></iq>";
static void test_empty_cdata(void)
{
iks *iq = NULL;
iks *input = NULL;
iksparser *p = iks_dom_new(&iq);
const char *cdata;
ASSERT_EQUALS(IKS_OK, iks_parse(p, empty_cdata, 0, 1));
iks_parser_delete(p);
ASSERT_NOT_NULL((input = iks_find(iq, "input")));
ASSERT_NULL((cdata = iks_find_cdata(input, "grammar")));
iks_delete(iq);
}
static const char *rayo_test_srgs =
"<grammar xmlns=\"http://www.w3.org/2001/06/grammar\" root=\"MAINRULE\">\n"
" <rule id=\"MAINRULE\">\n"
" <one-of>\n"
" <item>\n"
" <item repeat=\"0-1\"> need a</item>\n"
" <item repeat=\"0-1\"> i need a</item>\n"
" <one-of>\n"
" <item> clue </item>\n"
" </one-of>\n"
" <tag> out.concept = \"clue\";</tag>\n"
" </item>\n"
" <item>\n"
" <item repeat=\"0-1\"> have an</item>\n"
" <item repeat=\"0-1\"> i have an</item>\n"
" <one-of>\n"
" <item> answer </item>\n"
" </one-of>\n"
" <tag> out.concept = \"answer\";</tag>\n"
" </item>\n"
" </one-of>\n"
" </rule>\n"
"</grammar>";
static void test_rayo_test_srgs(void)
{
iks *grammar = NULL;
iksparser *p = iks_dom_new(&grammar);
ASSERT_EQUALS(IKS_OK, iks_parse(p, rayo_test_srgs, 0, 1));
iks_parser_delete(p);
iks_delete(grammar);
}
#define MATCH 1
#define NO_MATCH 0
static void test_iks_helper_value_matches(void)
{
ASSERT_EQUALS(MATCH, value_matches("1", "1,2,3"));
ASSERT_EQUALS(MATCH, value_matches("2", "1,2,3"));
ASSERT_EQUALS(MATCH, value_matches("3", "1,2,3"));
ASSERT_EQUALS(NO_MATCH, value_matches("4", "1,2,3"));
ASSERT_EQUALS(NO_MATCH, value_matches("1,2", "1,2,3"));
ASSERT_EQUALS(NO_MATCH, value_matches(NULL, "1,2,3"));
ASSERT_EQUALS(NO_MATCH, value_matches(NULL, NULL));
ASSERT_EQUALS(NO_MATCH, value_matches("1", NULL));
ASSERT_EQUALS(NO_MATCH, value_matches("", "1,2,3"));
ASSERT_EQUALS(NO_MATCH, value_matches("", ""));
ASSERT_EQUALS(NO_MATCH, value_matches("1", ""));
ASSERT_EQUALS(MATCH, value_matches("duplex", "duplex,send,recv"));
ASSERT_EQUALS(MATCH, value_matches("send", "duplex,send,recv"));
ASSERT_EQUALS(MATCH, value_matches("recv", "duplex,send,recv"));
ASSERT_EQUALS(NO_MATCH, value_matches("sendrecv", "duplex,send,recv"));
ASSERT_EQUALS(MATCH, value_matches("duplex1", "duplex1,duplex2,duplex3"));
ASSERT_EQUALS(MATCH, value_matches("duplex2", "duplex1,duplex2,duplex3"));
ASSERT_EQUALS(MATCH, value_matches("duplex3", "duplex1,duplex2,duplex3"));
ASSERT_EQUALS(NO_MATCH, value_matches("duplex4", "duplex1,duplex2,duplex3"));
ASSERT_EQUALS(NO_MATCH, value_matches("duplex", "duplex1,duplex2,duplex3"));
}
static void test_dialback_key(void)
{
ASSERT_STRING_EQUALS("37c69b1cf07a3f67c04a5ef5902fa5114f2c76fe4a2686482ba5b89323075643", iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "example.org", "D60000229F"));
ASSERT_NULL(iks_server_dialback_key("", "xmpp.example.com", "example.org", "D60000229F"));
ASSERT_NULL(iks_server_dialback_key("s3cr3tf0rd14lb4ck", "", "example.org", "D60000229F"));
ASSERT_NULL(iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "", "D60000229F"));
ASSERT_NULL(iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "example.org", ""));
ASSERT_NULL(iks_server_dialback_key(NULL, "xmpp.example.com", "example.org", "D60000229F"));
ASSERT_NULL(iks_server_dialback_key("s3cr3tf0rd14lb4ck", NULL, "example.org", "D60000229F"));
ASSERT_NULL(iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", NULL, "D60000229F"));
ASSERT_NULL(iks_server_dialback_key("s3cr3tf0rd14lb4ck", "xmpp.example.com", "example.org", NULL));
}
static void test_validate_dtmf(void)
{
ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("1"));
ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("A"));
ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("a"));
ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("D"));
ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("d"));
ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("*"));
ASSERT_EQUALS(SWITCH_TRUE, iks_attrib_is_dtmf_digit("#"));
ASSERT_EQUALS(SWITCH_FALSE, iks_attrib_is_dtmf_digit("E"));
ASSERT_EQUALS(SWITCH_FALSE, iks_attrib_is_dtmf_digit(NULL));
ASSERT_EQUALS(SWITCH_FALSE, iks_attrib_is_dtmf_digit(""));
ASSERT_EQUALS(SWITCH_FALSE, iks_attrib_is_dtmf_digit("11"));
ASSERT_EQUALS(SWITCH_TRUE, validate_optional_attrib(iks_attrib_is_dtmf_digit, "A"));
ASSERT_EQUALS(SWITCH_TRUE, validate_optional_attrib(iks_attrib_is_dtmf_digit, "1"));
ASSERT_EQUALS(SWITCH_FALSE, validate_optional_attrib(iks_attrib_is_dtmf_digit, "Z"));
ASSERT_EQUALS(SWITCH_FALSE, validate_optional_attrib(iks_attrib_is_dtmf_digit, "11"));
ASSERT_EQUALS(SWITCH_TRUE, validate_optional_attrib(iks_attrib_is_dtmf_digit, NULL));
ASSERT_EQUALS(SWITCH_TRUE, validate_optional_attrib(iks_attrib_is_dtmf_digit, ""));
}
/**
* main program
*/
int main(int argc, char **argv)
{
const char *err;
TEST_INIT
TEST(test_iks_cdata_bug);
TEST(test_repeating_bracket);
TEST(test_normal_cdata);
TEST(test_empty_cdata);
TEST(test_rayo_test_srgs);
TEST(test_iks_helper_value_matches);
TEST(test_dialback_key);
TEST(test_validate_dtmf);
return 0;
}

View File

@ -1,6 +0,0 @@
int dummy(int i)
{
return 0;
}

View File

@ -1,18 +0,0 @@
BASE=../../../../..
IKS_DIR=$(BASE)/libs/iksemel
IKS_LA=$(IKS_DIR)/src/libiksemel.la
LOCAL_CFLAGS += -I../ -I$(BASE)/libs/iksemel/include
LOCAL_OBJS= $(PCRE_LA) $(IKS_LA) main.o ../nlsml.o
LOCAL_SOURCES= main.c
include $(BASE)/build/modmake.rules
$(IKS_LA): $(IKS_DIR) $(IKS_DIR)/.update
@cd $(IKS_DIR) && $(MAKE)
@$(TOUCH_TARGET)
local_all:
libtool --mode=link gcc main.o ../nlsml.o -o test test_nlsml.la
local_clean:
-rm test

View File

@ -1,6 +0,0 @@
int dummy(int i)
{
return 0;
}

View File

@ -1,18 +0,0 @@
BASE=../../../../..
IKS_DIR=$(BASE)/libs/iksemel
IKS_LA=$(IKS_DIR)/src/libiksemel.la
LOCAL_CFLAGS += -I../ -I$(BASE)/libs/iksemel/include
LOCAL_OBJS= $(PCRE_LA) $(IKS_LA) main.o ../srgs.o
LOCAL_SOURCES= main.c
include $(BASE)/build/modmake.rules
$(IKS_LA): $(IKS_DIR) $(IKS_DIR)/.update
@cd $(IKS_DIR) && $(MAKE)
@$(TOUCH_TARGET)
local_all:
libtool --mode=link gcc main.o ../srgs.o -o test test_srgs.la
local_clean:
-rm test

View File

@ -1,6 +0,0 @@
int dummy(int i)
{
return 0;
}

View File

@ -1,6 +1,6 @@
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2013-2015, Grasshopper
* Copyright (C) 2013-2018, Grasshopper
*
* Version: MPL 1.1
*
@ -37,22 +37,22 @@ typedef int (* xmpp_stream_ready_callback)(struct xmpp_stream *stream);
typedef void (* xmpp_stream_recv_callback)(struct xmpp_stream *stream, iks *stanza);
typedef void (* xmpp_stream_destroy_callback)(struct xmpp_stream *stream);
extern struct xmpp_stream_context *xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_bind_callback bind_cb, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy);
extern void xmpp_stream_context_add_cert(struct xmpp_stream_context *context, const char *cert_pem_file);
extern void xmpp_stream_context_add_key(struct xmpp_stream_context *context, const char *key_pem_file);
extern void xmpp_stream_context_add_user(struct xmpp_stream_context *context, const char *user, const char *password);
extern void xmpp_stream_context_dump(struct xmpp_stream_context *context, switch_stream_handle_t *stream);
extern void xmpp_stream_context_destroy(struct xmpp_stream_context *context);
extern void xmpp_stream_context_send(struct xmpp_stream_context *context, const char *jid, iks *stanza);
SWITCH_DECLARE(struct xmpp_stream_context *) xmpp_stream_context_create(const char *domain, const char *domain_secret, xmpp_stream_bind_callback bind_cb, xmpp_stream_ready_callback ready, xmpp_stream_recv_callback recv, xmpp_stream_destroy_callback destroy);
SWITCH_DECLARE(void) xmpp_stream_context_add_cert(struct xmpp_stream_context *context, const char *cert_pem_file);
SWITCH_DECLARE(void) xmpp_stream_context_add_key(struct xmpp_stream_context *context, const char *key_pem_file);
SWITCH_DECLARE(void) xmpp_stream_context_add_user(struct xmpp_stream_context *context, const char *user, const char *password);
SWITCH_DECLARE(void) xmpp_stream_context_dump(struct xmpp_stream_context *context, switch_stream_handle_t *stream);
SWITCH_DECLARE(void) xmpp_stream_context_destroy(struct xmpp_stream_context *context);
SWITCH_DECLARE(void) xmpp_stream_context_send(struct xmpp_stream_context *context, const char *jid, iks *stanza);
extern switch_status_t xmpp_stream_context_listen(struct xmpp_stream_context *context, const char *addr, int port, int is_s2s, const char *acl);
extern switch_status_t xmpp_stream_context_connect(struct xmpp_stream_context *context, const char *peer_domain, const char *peer_address, int peer_port);
SWITCH_DECLARE(switch_status_t) xmpp_stream_context_listen(struct xmpp_stream_context *context, const char *addr, int port, int is_s2s, const char *acl);
SWITCH_DECLARE(switch_status_t) xmpp_stream_context_connect(struct xmpp_stream_context *context, const char *peer_domain, const char *peer_address, int peer_port);
extern int xmpp_stream_is_s2s(struct xmpp_stream *stream);
extern int xmpp_stream_is_incoming(struct xmpp_stream *stream);
extern const char *xmpp_stream_get_jid(struct xmpp_stream *stream);
extern void xmpp_stream_set_private(struct xmpp_stream *stream, void *user_private);
extern void *xmpp_stream_get_private(struct xmpp_stream *stream);
SWITCH_DECLARE(int) xmpp_stream_is_s2s(struct xmpp_stream *stream);
SWITCH_DECLARE(int) xmpp_stream_is_incoming(struct xmpp_stream *stream);
SWITCH_DECLARE(const char *) xmpp_stream_get_jid(struct xmpp_stream *stream);
SWITCH_DECLARE(void) xmpp_stream_set_private(struct xmpp_stream *stream, void *user_private);
SWITCH_DECLARE(void *) xmpp_stream_get_private(struct xmpp_stream *stream);
#endif

View File

@ -58,6 +58,11 @@
#include <priv.h>
#endif
#ifdef WIN32
#define popen _popen
#define pclose _pclose
#endif
SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs = { 0 };
SWITCH_DECLARE_DATA switch_filenames SWITCH_GLOBAL_filenames = { 0 };
@ -3253,45 +3258,7 @@ SWITCH_DECLARE(int) switch_system(const char *cmd, switch_bool_t wait)
SWITCH_DECLARE(int) switch_stream_system_fork(const char *cmd, switch_stream_handle_t *stream)
{
#ifdef WIN32
return switch_system(cmd, SWITCH_TRUE);
#else
int fds[2], pid = 0;
if (pipe(fds)) {
goto end;
} else { /* good to go */
pid = switch_fork();
if (pid < 0) { /* ok maybe not */
close(fds[0]);
close(fds[1]);
goto end;
} else if (pid) { /* parent */
char buf[1024] = "";
int bytes;
close(fds[1]);
while ((bytes = read(fds[0], buf, sizeof(buf))) > 0) {
stream->raw_write_function(stream, (unsigned char *)buf, bytes);
}
close(fds[0]);
waitpid(pid, NULL, 0);
} else { /* child */
switch_close_extra_files(fds, 2);
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
switch_system(cmd, SWITCH_TRUE);
close(fds[1]);
exit(0);
}
}
end:
return 0;
#endif
return switch_stream_system(cmd, stream);
}
SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max)
@ -3320,13 +3287,26 @@ SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, s
SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t *stream)
{
#ifdef WIN32
stream->write_function(stream, "Capturing output not supported.\n");
return switch_system(cmd, SWITCH_TRUE);
#else
return switch_stream_system_fork(cmd, stream);
#endif
char buffer[128];
size_t bytes;
FILE* pipe = popen(cmd, "r");
if (!pipe) return 1;
while (!feof(pipe)) {
while ((bytes = fread(buffer, 1, 128, pipe)) > 0) {
if (stream != NULL) {
stream->raw_write_function(stream, (unsigned char *)buffer, bytes);
}
}
}
if (ferror(pipe)) {
pclose(pipe);
return 1;
}
pclose(pipe);
return 0;
}
SWITCH_DECLARE(uint16_t) switch_core_get_rtp_port_range_start_port()

View File

@ -124,7 +124,7 @@ static void preprocess_exec_set(char *keyval)
if (key && val) {
switch_stream_handle_t exec_result = { 0 };
SWITCH_STANDARD_STREAM(exec_result);
if (switch_stream_system_fork(val, &exec_result) == 0) {
if (switch_stream_system(val, &exec_result) == 0) {
if (!zstr(exec_result.data)) {
char *tmp = (char *) exec_result.data;
tmp = &tmp[strlen(tmp)-1];

9
tests/unit/Makefile.am Normal file
View File

@ -0,0 +1,9 @@
include $(top_srcdir)/build/modmake.rulesam
bin_PROGRAMS = switch_event switch_hash switch_ivr_originate switch_utils switch_core
AM_LDFLAGS = -avoid-version -no-undefined $(SWITCH_AM_LDFLAGS) $(openssl_LIBS)
AM_LDFLAGS += $(FREESWITCH_LIBS) $(switch_builddir)/libfreeswitch.la $(CORE_LIBS) $(APR_LIBS)
AM_CFLAGS = $(SWITCH_AM_CPPFLAGS)
AM_CPPFLAGS = $(SWITCH_AM_CPPFLAGS)
TESTS = $(bin_PROGRAMS)

View File

@ -3,29 +3,6 @@ benchmarks testing functionality exposed through libfreeswitch.
Requirements for a new unit tests:
1. Tests must use TAP(Test Anything Protocol) output format, and must
print to stderr the summary statistics of the test before exiting.
2. Each test must return 0 on successful completion, or a non-zero
result in case of a failure.
3. Benchmarking stats should be output as a TAP note at the end of the
test in a human and machine(regex) parsable format
Use libtap from https://github.com/zorgnax/libtap
cd /usr/local/src/
git clone https://github.com/zorgnax/libtap.git
make PREFIX=/usr install
1. Tests must use switch_test.h framework
To run a benchmark version of a unit test, update the loops count, and
make sure to uncomment the 'BENCHMARK' define line. Then you can run
the benchmark with:
perf record ./.libs/switch_hash
Once that is completed you can view the results with:
perf report

View File

@ -0,0 +1,39 @@
<?xml version="1.0"?>
<document type="freeswitch/xml">
<X-PRE-PROCESS cmd="exec-set" data="test=echo 1234"/>
<X-PRE-PROCESS cmd="set" data="default_password=$${test}"/>
<section name="configuration" description="Various Configuration">
<configuration name="modules.conf" description="Modules">
<modules>
<load module="mod_console"/>
<load module="mod_loopback"/>
</modules>
</configuration>
<configuration name="console.conf" description="Console Logger">
<mappings>
<map name="all" value="console,debug,info,notice,warning,err,crit,alert"/>
</mappings>
<settings>
<param name="colorize" value="true"/>
<param name="loglevel" value="debug"/>
</settings>
</configuration>
<configuration name="timezones.conf" description="Timezones">
<timezones>
<zone name="GMT" value="GMT0" />
</timezones>
</configuration>
</section>
<section name="dialplan" description="Regex/XML Dialplan">
<context name="default">
<extension name="sample">
<condition>
<action application="info"/>
</condition>
</extension>
</context>
</section>
</document>

88
tests/unit/switch_core.c Normal file
View File

@ -0,0 +1,88 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2018, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Rienzo <chris@signalwire.com>
* Seven Du <dujinfang@gmail.com>
*
*
* switch_core.c -- tests core functions
*
*/
#include <switch.h>
#include <stdlib.h>
#include <test/switch_test.h>
FST_CORE_BEGIN("./conf")
{
FST_SUITE_BEGIN(switch_ivr_originate)
{
FST_SETUP_BEGIN()
{
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
#ifndef WIN32
FST_TEST_BEGIN(test_fork)
{
switch_stream_handle_t exec_result = { 0 };
SWITCH_STANDARD_STREAM(exec_result);
fst_requires(switch_stream_system_fork("ip ad sh", &exec_result) == 0);
fst_requires(!zstr(exec_result.data));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", (char *)exec_result.data);
fst_requires(switch_stream_system_fork("ip ad sh | grep link", &exec_result) == 0);
fst_requires(!zstr(exec_result.data));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s\n", (char *)exec_result.data);
switch_safe_free(exec_result.data);
}
FST_TEST_END()
#endif
FST_TEST_BEGIN(test_non_fork_exec_set)
{
char *var_test = switch_core_get_variable_dup("test");
char *var_default_password = switch_core_get_variable_dup("default_password");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "global_getvar test: %s\n", switch_str_nil(var_test));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "global_getvar default_password: %s\n", switch_str_nil(var_default_password));
fst_check_string_not_equals(var_test, "");
fst_check_string_not_equals(var_default_password, "");
fst_check_string_equals(var_test, var_default_password);
switch_safe_free(var_test);
switch_safe_free(var_default_password);
}
FST_TEST_END()
}
FST_SUITE_END()
}
FST_CORE_END()

View File

@ -1,10 +1,25 @@
#include <stdio.h>
#include <switch.h>
#include <tap.h>
#include <test/switch_test.h>
// #define BENCHMARK 1
int main () {
FST_MINCORE_BEGIN()
FST_SUITE_BEGIN(switch_event)
FST_SETUP_BEGIN()
{
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
FST_TEST_BEGIN(benchmark)
{
switch_event_t *event = NULL;
switch_bool_t verbose = SWITCH_TRUE;
const char *err = NULL;
@ -18,18 +33,8 @@ int main () {
#ifdef BENCHMARK
switch_time_t small_start_ts, small_end_ts;
plan(2);
#else
plan(2 + ( 2 * loops));
#endif
status = switch_core_init(SCF_MINIMAL, verbose, &err);
if ( !ok( status == SWITCH_STATUS_SUCCESS, "Initialize FreeSWITCH core\n")) {
bail_out(0, "Bail due to failure to initialize FreeSWITCH[%s]", err);
}
index = calloc(loops, sizeof(char *));
for ( x = 0; x < loops; x++) {
index[x] = switch_mprintf("%d", x);
@ -39,18 +44,18 @@ int main () {
start_ts = switch_time_now();
status = switch_event_create(&event, SWITCH_EVENT_MESSAGE);
ok( status == SWITCH_STATUS_SUCCESS,"Create Event");
fst_xcheck(status == SWITCH_STATUS_SUCCESS, "Failed to create event");
#ifndef BENCHMARK
for ( x = 0; x < loops; x++) {
status = switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, index[x], index[x]);
ok( status == SWITCH_STATUS_SUCCESS,"Add header to event");
fst_xcheck(status == SWITCH_STATUS_SUCCESS, "Failed to add header to event");
}
#else
small_start_ts = switch_time_now();
for ( x = 0; x < loops; x++) {
if ( switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, index[x], index[x]) != SWITCH_STATUS_SUCCESS) {
fail("Failed to add header to event");
fst_fail("Failed to add header to event");
}
}
small_end_ts = switch_time_now();
@ -58,20 +63,20 @@ int main () {
micro_total = small_end_ts - small_start_ts;
micro_per = micro_total / (double) loops;
rate_per_sec = 1000000 / micro_per;
note("switch_event add_header: Total %ldus / %ld loops, %.2f us per loop, %.0f loops per second\n",
printf("switch_event add_header: Total %ldus / %ld loops, %.2f us per loop, %.0f loops per second\n",
micro_total, loops, micro_per, rate_per_sec);
#endif
#ifndef BENCHMARK
for ( x = 0; x < loops; x++) {
is(switch_event_get_header(event, index[x]), index[x], "correct header value returned");
fst_check_string_equals(switch_event_get_header(event, index[x]), index[x]);
}
#else
small_start_ts = switch_time_now();
for ( x = 0; x < loops; x++) {
if ( !switch_event_get_header(event, index[x])) {
fail("Failed to lookup event header value");
fst_fail("Failed to lookup event header value");
}
}
small_end_ts = switch_time_now();
@ -79,11 +84,10 @@ int main () {
micro_total = small_end_ts - small_start_ts;
micro_per = micro_total / (double) loops;
rate_per_sec = 1000000 / micro_per;
note("switch_event get_header: Total %ldus / %ld loops, %.2f us per loop, %.0f loops per second\n",
printf("switch_event get_header: Total %ldus / %ld loops, %.2f us per loop, %.0f loops per second\n",
micro_total, loops, micro_per, rate_per_sec);
#endif
switch_event_destroy(&event);
/* END LOOPS */
@ -97,10 +101,15 @@ int main () {
micro_total = end_ts - start_ts;
micro_per = micro_total / (double) loops;
rate_per_sec = 1000000 / micro_per;
diag("switch_event Total %ldus / %d loops, %.2f us per loop, %.0f loops per second\n",
printf("switch_event Total %ldus / %d loops, %.2f us per loop, %.0f loops per second\n",
micro_total, loops, micro_per, rate_per_sec);
switch_core_destroy();
done_testing();
}
FST_TEST_END()
FST_SUITE_END()
FST_MINCORE_END()

View File

@ -1,11 +1,25 @@
#include <stdio.h>
#include <switch.h>
#include <tap.h>
#include <test/switch_test.h>
// #define BENCHMARK 1
int main () {
FST_MINCORE_BEGIN()
FST_SUITE_BEGIN(switch_hash)
FST_SETUP_BEGIN()
{
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
FST_TEST_BEGIN(benchmark)
{
switch_event_t *event = NULL;
switch_bool_t verbose = SWITCH_TRUE;
const char *err = NULL;
@ -24,23 +38,7 @@ int main () {
char **index = NULL;
switch_hash_t *hash = NULL;
#ifndef BENCHMARK
plan(2 + ( 5 * loops));
#else
plan(2);
#endif
status = switch_core_init(SCF_MINIMAL, verbose, &err);
if ( !ok( status == SWITCH_STATUS_SUCCESS, "Initialize FreeSWITCH core\n")) {
bail_out(0, "Bail due to failure to initialize FreeSWITCH[%s]", err);
}
status = switch_core_hash_init(&hash);
if ( !ok(status == SWITCH_STATUS_SUCCESS, "Create a new hash")) {
bail_out(0, "Bail due to failure to create hash");
}
fst_requires(switch_core_hash_init(&hash) == SWITCH_STATUS_SUCCESS);
index = calloc(loops, sizeof(char *));
for ( x = 0; x < loops; x++) {
@ -54,7 +52,7 @@ int main () {
#ifndef BENCHMARK
for ( x = 0; x < loops; x++) {
status = switch_core_hash_insert(hash, index[x], (void *) index[x]);
ok(status == SWITCH_STATUS_SUCCESS, "Insert into the hash");
fst_xcheck(status == SWITCH_STATUS_SUCCESS, "Failed to insert into the hash");
}
#else
small_start_ts = switch_time_now();
@ -66,7 +64,7 @@ int main () {
micro_total = small_end_ts - small_start_ts;
micro_per = micro_total / (double) loops;
rate_per_sec = 1000000 / micro_per;
note("switch_hash insert: Total %ldus / %ld loops, %.2f us per loop, %.0f loops per second\n",
printf("switch_hash insert: Total %ldus / %ld loops, %.2f us per loop, %.0f loops per second\n",
micro_total, loops, micro_per, rate_per_sec);
#endif
@ -76,14 +74,14 @@ int main () {
for ( x = 0; x < loops; x++) {
char *data = NULL;
data = switch_core_hash_find(hash, index[x]);
ok(data != NULL, "Successful lookup");
is( index[x], data, "Returned correct data");
fst_xcheck(data != NULL, "Lookup failed");
fst_check_string_equals( index[x], data);
}
#else
small_start_ts = switch_time_now();
for ( x = 0; x < loops; x++) {
if ( ! switch_core_hash_find(hash, index[x])) {
fail("Failed to properly locate one of the values");
fst_fail("Failed to properly locate one of the values");
}
}
small_end_ts = switch_time_now();
@ -91,7 +89,7 @@ int main () {
micro_total = small_end_ts - small_start_ts;
micro_per = micro_total / (double) loops;
rate_per_sec = 1000000 / micro_per;
note("switch_hash find: Total %ldus / %ld loops, %.2f us per loop, %.0f loops per second\n",
printf("switch_hash find: Total %ldus / %ld loops, %.2f us per loop, %.0f loops per second\n",
micro_total, loops, micro_per, rate_per_sec);
#endif
@ -101,14 +99,14 @@ int main () {
for ( x = 0; x < loops; x++) {
char *data = NULL;
data = switch_core_hash_delete(hash, index[x]);
ok(data != NULL, "Create a new hash");
is( index[x], data, "Returned correct data");
fst_xcheck(data != NULL, "Delete from the hash");
fst_check_string_equals( index[x], data );
}
#else
small_start_ts = switch_time_now();
for ( x = 0; x < loops; x++) {
if ( !switch_core_hash_delete(hash, index[x])) {
fail("Failed to delete and return the value");
fst_fail("Failed to delete and return the value");
}
}
small_end_ts = switch_time_now();
@ -116,7 +114,7 @@ int main () {
micro_total = small_end_ts - small_start_ts;
micro_per = micro_total / (double) loops;
rate_per_sec = 1000000 / micro_per;
note("switch_hash delete: Total %ldus / %d loops, %.2f us per loop, %.0f loops per second\n",
printf("switch_hash delete: Total %ldus / %d loops, %.2f us per loop, %.0f loops per second\n",
micro_total, loops, micro_per, rate_per_sec);
#endif
@ -133,10 +131,12 @@ int main () {
micro_total = end_ts - start_ts;
micro_per = micro_total / (double) loops;
rate_per_sec = 1000000 / micro_per;
diag("switch_hash Total %ldus / %d loops, %.2f us per loop, %.0f loops per second\n",
printf("switch_hash Total %ldus / %d loops, %.2f us per loop, %.0f loops per second\n",
micro_total, loops, micro_per, rate_per_sec);
switch_core_destroy();
done_testing();
}
FST_TEST_END()
FST_SUITE_END()
FST_MINCORE_END()

View File

@ -0,0 +1,139 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2018, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Rienzo <chris@signalwire.com>
* Seven Du <dujinfang@gmail.com>
*
*
* switch_ivr_originate.c -- tests originate
*
*/
#include <switch.h>
#include <stdlib.h>
#include <test/switch_test.h>
int reporting = 0;
int destroy = 0;
static switch_status_t my_on_reporting(switch_core_session_t *session)
{
switch_assert(session);
reporting++;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "session reporting %d\n", reporting);
}
static switch_status_t my_on_destroy(switch_core_session_t *session)
{
switch_assert(session);
destroy++;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "session destroy %d\n", destroy);
}
static switch_state_handler_table_t state_handlers = {
/*.on_init */ NULL,
/*.on_routing */ NULL,
/*.on_execute */ NULL,
/*.on_hangup */ NULL,
/*.on_exchange_media */ NULL,
/*.on_soft_execute */ NULL,
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ my_on_reporting,
/*.on_destroy */ my_on_destroy,
SSH_FLAG_STICKY
};
FST_CORE_BEGIN("./conf")
{
FST_SUITE_BEGIN(switch_ivr_originate)
{
FST_SETUP_BEGIN()
{
fst_requires_module("mod_loopback");
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
FST_TEST_BEGIN(originate_test_early_state_handler)
{
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
switch_status_t status;
switch_call_cause_t cause;
status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel = switch_core_session_get_channel(session);
fst_requires(channel);
switch_channel_add_state_handler(channel, &state_handlers);
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
fst_check(!switch_channel_ready(channel));
switch_core_session_rwunlock(session);
switch_sleep(1000000);
fst_check(reporting == 1);
fst_check(destroy == 1);
}
FST_TEST_END()
FST_TEST_BEGIN(originate_test_late_state_handler)
{
switch_core_session_t *session = NULL;
switch_channel_t *channel = NULL;
switch_status_t status;
switch_call_cause_t cause;
status = switch_ivr_originate(NULL, &session, &cause, "null/+15553334444", 2, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, NULL);
fst_requires(session);
fst_check(status == SWITCH_STATUS_SUCCESS);
channel = switch_core_session_get_channel(session);
fst_requires(channel);
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
switch_sleep(1000000);
switch_channel_add_state_handler(channel, &state_handlers);
switch_core_session_rwunlock(session);
switch_sleep(1000000);
fst_check(reporting == 1);
fst_check(destroy == 2);
}
FST_TEST_END()
}
FST_SUITE_END()
}
FST_CORE_END()

79
tests/unit/switch_utils.c Normal file
View File

@ -0,0 +1,79 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2018, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Seven Du <seven@signalwire.com>
*
*
* switch_utils.c -- tests switch_utils
*
*/
#include <stdio.h>
#include <switch.h>
#include <test/switch_test.h>
FST_MINCORE_BEGIN()
FST_SUITE_BEGIN(switch_hash)
FST_SETUP_BEGIN()
{
}
FST_SETUP_END()
FST_TEARDOWN_BEGIN()
{
}
FST_TEARDOWN_END()
FST_TEST_BEGIN(benchmark)
{
char encoded[1024];
char *s = "ABCD";
switch_url_encode(s, encoded, sizeof(encoded));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "encoded: [%s]\n", encoded);
fst_check_string_equals(encoded, "ABCD");
s = "&bryän#!杜金房";
switch_url_encode(s, encoded, sizeof(encoded));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "encoded: [%s]\n", encoded);
fst_check_string_equals(encoded, "%26bry%C3%A4n%23!%E6%9D%9C%E9%87%91%E6%88%BF");
}
FST_TEST_END()
FST_SUITE_END()
FST_MINCORE_END()
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -0,0 +1,203 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>test_switch_core</ProjectName>
<RootNamespace>test_switch_core</RootNamespace>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<ProjectGuid>{EF62B845-A0CE-44FD-B8E6-475FE87D06C3}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)w32\winlibs.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)w32\winlibs.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)w32\winlibs.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(SolutionDir)w32\winlibs.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(PlatformName)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(PlatformName)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(PlatformName)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)src\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>SWITCH_TEST_BASE_DIR_FOR_CONF="..\\..\\tests\\unit\\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<BuildLog />
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<EnablePREfast>true</EnablePREfast>
<DisableSpecificWarnings>6031;6340;6246;6011;6387;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<BuildLog />
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<EnablePREfast>true</EnablePREfast>
<DisableSpecificWarnings>6031;6340;6246;6011;6387;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<BuildLog />
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>6031;6340;6246;6011;6387;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<BuildLog />
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>6031;6340;6246;6011;6387;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="switch_core.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(SolutionDir)w32\Library\FreeSwitchCore.2017.vcxproj">
<Project>{202d7a4e-760d-4d0e-afa1-d7459ced30ff}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,17 +0,0 @@
AUTOMAKE_OPTIONS = foreign
FSLD = $(top_builddir)/libfreeswitch.la $(top_builddir)/libs/apr/libapr-1.la $(top_builddir)/libs/apr-util/libaprutil-1.la
check_PROGRAMS += tests/unit/switch_event
tests_unit_switch_event_SOURCES = tests/unit/switch_event.c
tests_unit_switch_event_CFLAGS = $(SWITCH_AM_CFLAGS)
tests_unit_switch_event_LDADD = $(FSLD)
tests_unit_switch_event_LDFLAGS = $(SWITCH_AM_LDFLAGS) -ltap
check_PROGRAMS += tests/unit/switch_hash
tests_unit_switch_hash_SOURCES = tests/unit/switch_hash.c
tests_unit_switch_hash_CFLAGS = $(SWITCH_AM_CFLAGS)
tests_unit_switch_hash_LDADD = $(FSLD)
tests_unit_switch_hash_LDFLAGS = $(SWITCH_AM_LDFLAGS) -ltap