diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index 9bf1dada2a..44df5bcd81 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -84,6 +84,9 @@ libopenzap_la_LIBADD = $(LIBS) MYLIB=libopenzap.la +core: libopenzap.la +core-install: install-libLTLIBRARIES + noinst_PROGRAMS = testtones detect_tones detect_dtmf testisdn testboost testanalog testapp testcid testapp_SOURCES = $(SRC)/testapp.c testapp_LDADD = libopenzap.la diff --git a/libs/freetdm/mod_openzap/mod_openzap.c b/libs/freetdm/mod_openzap/mod_openzap.c index 6b941616ed..9bb5e5a902 100644 --- a/libs/freetdm/mod_openzap/mod_openzap.c +++ b/libs/freetdm/mod_openzap/mod_openzap.c @@ -2320,7 +2320,14 @@ SWITCH_STANDARD_API(oz_function) } } else { - stream->write_function(stream, "-ERR Usage: %s\n", OZ_SYNTAX); + char *rply = zap_api_execute(cmd, NULL); + + if (rply) { + stream->write_function(stream, "%s", rply); + free(rply); + } else { + stream->write_function(stream, "-ERR Usage: %s\n", OZ_SYNTAX); + } } /*Q931ToPcap enhancement done*/ diff --git a/libs/freetdm/src/include/openzap.h b/libs/freetdm/src/include/openzap.h index 2b078e603e..e35daf1543 100644 --- a/libs/freetdm/src/include/openzap.h +++ b/libs/freetdm/src/include/openzap.h @@ -298,13 +298,14 @@ struct zap_stream_handle { zap_size_t alloc_chunk; }; + zap_status_t zap_console_stream_raw_write(zap_stream_handle_t *handle, uint8_t *data, zap_size_t datalen); zap_status_t zap_console_stream_write(zap_stream_handle_t *handle, const char *fmt, ...); #define ZAP_CMD_CHUNK_LEN 1024 #define ZAP_STANDARD_STREAM(s) memset(&s, 0, sizeof(s)); s.data = malloc(ZAP_CMD_CHUNK_LEN); \ - switch_assert(s.data); \ - memset(s.data, 0, SWITCH_CMD_CHUNK_LEN); \ + assert(s.data); \ + memset(s.data, 0, ZAP_CMD_CHUNK_LEN); \ s.end = s.data; \ s.data_size = ZAP_CMD_CHUNK_LEN; \ s.write_function = zap_console_stream_write; \ @@ -624,6 +625,7 @@ zap_status_t zap_span_start(zap_span_t *span); int zap_load_module(const char *name); int zap_load_module_assume(const char *name); zap_status_t zap_span_find_by_name(const char *name, zap_span_t **span); +char *zap_api_execute(const char *type, const char *cmd); ZIO_CODEC_FUNCTION(zio_slin2ulaw); ZIO_CODEC_FUNCTION(zio_ulaw2slin); diff --git a/libs/freetdm/src/include/zap_types.h b/libs/freetdm/src/include/zap_types.h index 0aca999080..fee42a14c0 100644 --- a/libs/freetdm/src/include/zap_types.h +++ b/libs/freetdm/src/include/zap_types.h @@ -397,10 +397,12 @@ typedef struct zap_sigmsg zap_sigmsg_t; typedef struct zap_span zap_span_t; typedef struct zap_caller_data zap_caller_data_t; typedef struct zap_io_interface zap_io_interface_t; + +struct zap_stream_handle; typedef struct zap_stream_handle zap_stream_handle_t; -typedef zap_status_t (*zap_stream_handle_write_function_t) (zap_stream_handle_t *handle, uint8_t *data, zap_size_t datalen); -typedef zap_status_t (*zap_stream_handle_raw_write_function_t) (zap_stream_handle_t *handle, const char *fmt, ...); +typedef zap_status_t (*zap_stream_handle_raw_write_function_t) (zap_stream_handle_t *handle, uint8_t *data, zap_size_t datalen); +typedef zap_status_t (*zap_stream_handle_write_function_t) (zap_stream_handle_t *handle, const char *fmt, ...); #define ZIO_CHANNEL_REQUEST_ARGS (zap_span_t *span, uint32_t chan_id, zap_direction_t direction, zap_caller_data_t *caller_data, zap_channel_t **zchan) #define ZIO_CHANNEL_OUTGOING_CALL_ARGS (zap_channel_t *zchan) @@ -476,7 +478,7 @@ typedef zap_status_t (*zio_api_t) ZIO_API_ARGS ; #define ZIO_SIG_CONFIGURE_FUNCTION(name) zap_status_t name ZIO_SIG_CONFIGURE_ARGS #define ZIO_IO_UNLOAD_FUNCTION(name) zap_status_t name ZIO_IO_UNLOAD_ARGS #define ZIO_SIG_UNLOAD_FUNCTION(name) zap_status_t name ZIO_SIG_UNLOAD_ARGS -#define ZIP_API_FUNCTION(name) zap_status_t name ZIO_API_ARGS +#define ZIO_API_FUNCTION(name) zap_status_t name ZIO_API_ARGS #include "zap_dso.h" diff --git a/libs/freetdm/src/ozmod/ozmod_libpri/ozmod_libpri.c b/libs/freetdm/src/ozmod/ozmod_libpri/ozmod_libpri.c index 2a1682d02e..853dd97572 100644 --- a/libs/freetdm/src/ozmod/ozmod_libpri/ozmod_libpri.c +++ b/libs/freetdm/src/ozmod/ozmod_libpri/ozmod_libpri.c @@ -76,6 +76,121 @@ static void s_pri_message(struct pri *pri, char *s) } #endif + +static int parse_debug(const char *in) +{ + int flags = 0; + + if (!in) { + return 0; + } + + if (strstr(in, "q921_raw")) { + flags |= PRI_DEBUG_Q921_RAW; + } + + if (strstr(in, "q921_dump")) { + flags |= PRI_DEBUG_Q921_DUMP; + } + + if (strstr(in, "q921_state")) { + flags |= PRI_DEBUG_Q921_STATE; + } + + if (strstr(in, "config")) { + flags |= PRI_DEBUG_CONFIG; + } + + if (strstr(in, "q931_dump")) { + flags |= PRI_DEBUG_Q931_DUMP; + } + + if (strstr(in, "q931_state")) { + flags |= PRI_DEBUG_Q931_STATE; + } + + if (strstr(in, "q931_anomaly")) { + flags |= PRI_DEBUG_Q931_ANOMALY; + } + + if (strstr(in, "q931_anomaly")) { + flags |= PRI_DEBUG_Q931_ANOMALY; + } + + if (strstr(in, "apdu")) { + flags |= PRI_DEBUG_APDU; + } + + if (strstr(in, "aoc")) { + flags |= PRI_DEBUG_AOC; + } + + if (strstr(in, "all")) { + flags |= PRI_DEBUG_ALL; + } + + if (strstr(in, "none")) { + flags = 0; + } + + return flags; +} + + + +static ZIO_API_FUNCTION(zap_libpri_api) +{ + char *mycmd = NULL, *argv[10] = { 0 }; + int argc = 0; + + if (data) { + mycmd = strdup(data); + argc = zap_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + + if (argc > 2) { + if (!strcasecmp(argv[0], "debug")) { + int span_id = atoi(argv[1]); + zap_span_t *span = NULL; + + if (zap_span_find_by_name(argv[1], &span) == ZAP_SUCCESS || zap_span_find(span_id, &span) == ZAP_SUCCESS) { + zap_libpri_data_t *isdn_data = span->signal_data; + pri_set_debug(isdn_data->spri.pri, parse_debug(argv[2])); + stream->write_function(stream, "%s: +OK debug set.\n", __FILE__); + goto done; + } else { + stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__); + goto done; + } + } + } + + stream->write_function(stream, "%s: -ERR invalid command.\n", __FILE__); + + done: + + zap_safe_free(mycmd); + + return ZAP_SUCCESS; +} + + +static zap_io_interface_t zap_libpri_interface; + +static ZIO_IO_LOAD_FUNCTION(zap_libpri_io_init) +{ + assert(zio != NULL); + memset(&zap_libpri_interface, 0, sizeof(zap_libpri_interface)); + + zap_libpri_interface.name = "libpri"; + zap_libpri_interface.api = zap_libpri_api; + + *zio = &zap_libpri_interface; + + return ZAP_SUCCESS; +} + static ZIO_SIG_LOAD_FUNCTION(zap_libpri_init) { pri_set_error(s_pri_error); @@ -671,8 +786,6 @@ static int str2dp(char *dp) return PRI_UNKNOWN; } - - static ZIO_SIG_CONFIGURE_FUNCTION(zap_libpri_configure_span) { uint32_t i, x = 0; @@ -680,6 +793,7 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_libpri_configure_span) zap_libpri_data_t *isdn_data; char *var, *val; int32_t opts = 0; + char *debug = NULL; if (span->trunk_type >= ZAP_TRUNK_NONE) { zap_log(ZAP_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1.\n", zap_trunk_type2str(span->trunk_type)); @@ -741,7 +855,7 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_libpri_configure_span) if (!(val = va_arg(ap, char *))) { break; } - isdn_data->debug = atoi(val); + debug = val; } else { snprintf(span->last_error, sizeof(span->last_error), "Unknown parameter [%s]", var); return ZAP_FAIL; @@ -755,11 +869,8 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_libpri_configure_span) isdn_data->dchans[1] = dchans[1]; isdn_data->dchan = isdn_data->dchans[0]; - - // force debug rm me later - isdn_data->debug = PRI_DEBUG_Q931_DUMP | PRI_DEBUG_Q931_STATE; - - + isdn_data->debug = parse_debug(debug); + if (lpwrap_init_pri(&isdn_data->spri, span->span_id, // span isdn_data->dchan, // dchan @@ -786,7 +897,7 @@ static ZIO_SIG_CONFIGURE_FUNCTION(zap_libpri_configure_span) zap_module_t zap_module = { "libpri", - NULL, + zap_libpri_io_init, zap_libpri_unload, zap_libpri_init, zap_libpri_configure_span, @@ -795,6 +906,8 @@ zap_module_t zap_module = { + + /* For Emacs: * Local Variables: * mode:c diff --git a/libs/freetdm/src/zap_io.c b/libs/freetdm/src/zap_io.c index 50198709d5..1e55a768c7 100644 --- a/libs/freetdm/src/zap_io.c +++ b/libs/freetdm/src/zap_io.c @@ -2081,6 +2081,50 @@ static struct { } interfaces; +char *zap_api_execute(const char *type, const char *cmd) +{ + zap_io_interface_t *zio = NULL; + char *dup = NULL, *p; + char *rval = NULL; + + if (type && !cmd) { + dup = strdup(type); + if ((p = strchr(dup, ' '))) { + *p++ = '\0'; + cmd = p; + } + + type = dup; + } + + zap_mutex_lock(globals.mutex); + if (!(zio = (zap_io_interface_t *) hashtable_search(globals.interface_hash, (void *)type))) { + zap_load_module_assume(type); + if ((zio = (zap_io_interface_t *) hashtable_search(globals.interface_hash, (void *)type))) { + zap_log(ZAP_LOG_INFO, "auto-loaded '%s'\n", type); + } + } + zap_mutex_unlock(globals.mutex); + + if (zio && zio->api) { + zap_stream_handle_t stream = { 0 }; + zap_status_t status; + ZAP_STANDARD_STREAM(stream); + status = zio->api(&stream, cmd); + + if (status != ZAP_SUCCESS) { + zap_safe_free(stream.data); + } else { + rval = (char *) stream.data; + } + } + + zap_safe_free(dup); + + return rval; +} + + static zap_status_t load_config(void) { char cfg_name[] = "openzap.conf"; @@ -2283,7 +2327,7 @@ static zap_status_t process_module_config(zap_io_interface_t *zio) snprintf(filename, sizeof(filename), "%s.conf", zio->name); if (!zio->configure) { - zap_log(ZAP_LOG_ERROR, "Module %s does not support configuration.\n", zio->name); + zap_log(ZAP_LOG_DEBUG, "Module %s does not support configuration.\n", zio->name); return ZAP_FAIL; } @@ -2339,12 +2383,12 @@ int zap_load_module(const char *name) } if (mod->io_load) { - zap_io_interface_t *interface; + zap_io_interface_t *interface = NULL; - if (mod->io_load(&interface) != ZAP_SUCCESS || !interface) { + if (mod->io_load(&interface) != ZAP_SUCCESS || !interface || !interface->name) { zap_log(ZAP_LOG_ERROR, "Error loading %s\n", path); } else { - zap_log(ZAP_LOG_INFO, "Loading IO from %s\n", path); + zap_log(ZAP_LOG_INFO, "Loading IO from %s [%s]\n", path, interface->name); zap_mutex_lock(globals.mutex); if (hashtable_search(globals.interface_hash, (void *)interface->name)) { zap_log(ZAP_LOG_ERROR, "Interface %s already loaded!\n", interface->name);