diff --git a/libs/freetdm/src/Makefile b/libs/freetdm/src/Makefile index fa8c8d601c..9c6788826c 100644 --- a/libs/freetdm/src/Makefile +++ b/libs/freetdm/src/Makefile @@ -33,6 +33,7 @@ OBJS=hashtable.o hashtable_itr.o openzap.o zap_config.o libteletone_detect.o libteletone_generate.o zap_buffer.o CFLAGS=$(ZAP_CFLAGS) -Iinclude MYLIB=libopenzap.a +TMP=-I../../libpri-1.2.4 -Iinclude -I. -w include general.makefile $(ZAP_MODS) @@ -45,6 +46,16 @@ $(MYLIB): $(OBJS) testapp: testapp.c $(MYLIB) $(CC) -L. -Iinclude testapp.c -o testapp -lopenzap -lm + +priserver.o: priserver.c + $(CC) $(TMP) -c priserver.c -o priserver.o + +sangoma_pri.o: sangoma_pri.c + $(CC) $(TMP) -c sangoma_pri.c -o sangoma_pri.o + +priserver: $(MYLIB) priserver.o sangoma_pri.o + $(CC) sangoma_pri.o priserver.o -L. -o priserver -lopenzap -lm ../../libpri-1.2.4/libpri.a + openzap.o: openzap.c $(CC) $(MOD_CFLAGS) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@ diff --git a/libs/freetdm/src/include/openzap.h b/libs/freetdm/src/include/openzap.h index 077e4a098f..08201a2a41 100644 --- a/libs/freetdm/src/include/openzap.h +++ b/libs/freetdm/src/include/openzap.h @@ -149,6 +149,11 @@ struct zap_software_interface; #define zap_socket_close(it) if (it > -1) { close(it); it = -1;} +typedef enum { + ZAP_TOP_DOWN, + ZAP_BOTTOM_UP +} zap_direction_t; + typedef enum { ZAP_SUCCESS, ZAP_FAIL, @@ -164,6 +169,7 @@ typedef enum { } zap_wait_flag_t; typedef enum { + ZAP_CODEC_NONE = (1 << 31), ZAP_CODEC_ULAW = 0, ZAP_CODEC_ALAW = 8, ZAP_CODEC_SLIN = 10 @@ -172,7 +178,9 @@ typedef enum { typedef enum { ZAP_COMMAND_NOOP, ZAP_COMMAND_SET_INTERVAL, - ZAP_COMMAND_GET_INTERVAL + ZAP_COMMAND_GET_INTERVAL, + ZAP_COMMAND_SET_CODEC, + ZAP_COMMAND_GET_CODEC } zap_command_t; typedef enum { @@ -289,6 +297,7 @@ zap_status_t zap_span_create(zap_software_interface_t *zint, zap_span_t **span); zap_status_t zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_chan_type_t type, zap_channel_t **chan); zap_status_t zap_channel_open(const char *name, unsigned span_id, unsigned chan_id, zap_channel_t **zchan); +zap_status_t zap_channel_open_any(const char *name, unsigned span_id, zap_direction_t direction, zap_channel_t **zchan); zap_status_t zap_channel_close(zap_channel_t **zchan); zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, void *obj); zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t *flags, unsigned to); diff --git a/libs/freetdm/src/openzap.c b/libs/freetdm/src/openzap.c index dbb831b3e1..c7fe7b5199 100644 --- a/libs/freetdm/src/openzap.c +++ b/libs/freetdm/src/openzap.c @@ -186,6 +186,46 @@ zap_status_t zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_cha } +zap_status_t zap_channel_open_any(const char *name, unsigned span_id, zap_direction_t direction, zap_channel_t **zchan) +{ + zap_software_interface_t *zint = (zap_software_interface_t *) hashtable_search(globals.interface_hash, (char *)name); + zap_status_t status = ZAP_FAIL; + + if (span_id < ZAP_MAX_SPANS_INTERFACE && zint) { + zap_channel_t *check; + zap_span_t *span = &zint->spans[span_id]; + unsigned i; + + if (direction == ZAP_TOP_DOWN) { + for(i = 1; i <= span->chan_count; i++) { + check = &span->channels[i]; + if (zap_test_flag(check, ZAP_CHANNEL_READY) && !zap_test_flag(check, ZAP_CHANNEL_OPEN)) { + status = check->zint->open(check); + if (status == ZAP_SUCCESS) { + zap_set_flag(check, ZAP_CHANNEL_OPEN); + *zchan = check; + return status; + } + } + } + } else if (direction == ZAP_BOTTOM_UP) { + for(i = span->chan_count; i > 0; i--) { + check = &span->channels[i]; + if (zap_test_flag(check, ZAP_CHANNEL_READY) && !zap_test_flag(check, ZAP_CHANNEL_OPEN)) { + status = check->zint->open(check); + if (status == ZAP_SUCCESS) { + zap_set_flag(check, ZAP_CHANNEL_OPEN); + *zchan = check; + return status; + } + } + } + } + } + + return status; +} + zap_status_t zap_channel_open(const char *name, unsigned span_id, unsigned chan_id, zap_channel_t **zchan) { zap_software_interface_t *zint = (zap_software_interface_t *) hashtable_search(globals.interface_hash, (char *)name); @@ -212,10 +252,10 @@ zap_status_t zap_channel_close(zap_channel_t **zchan) zap_channel_t *check; zap_status_t status = ZAP_FAIL; - *zchan = NULL; assert(zchan != NULL); check = *zchan; assert(check != NULL); + *zchan = NULL; if (zap_test_flag(check, ZAP_CHANNEL_OPEN)) { status = check->zint->close(check); diff --git a/libs/freetdm/src/testapp.c b/libs/freetdm/src/testapp.c index 0950c2acee..dbd7d989ee 100644 --- a/libs/freetdm/src/testapp.c +++ b/libs/freetdm/src/testapp.c @@ -5,6 +5,7 @@ int main(int argc, char *argv[]) zap_global_set_default_logger(ZAP_LOG_LEVEL_DEBUG); zap_channel_t *chan; unsigned ms = 20; + zap_codec_t codec = ZAP_CODEC_SLIN; if (zap_global_init() != ZAP_SUCCESS) { fprintf(stderr, "Error loading OpenZAP\n"); @@ -25,6 +26,14 @@ int main(int argc, char *argv[]) printf("set interval failed [%s]\n", chan->last_error); } + if (zap_channel_command(chan, ZAP_COMMAND_SET_CODEC, &codec) == ZAP_SUCCESS) { + codec = 1; + zap_channel_command(chan, ZAP_COMMAND_GET_CODEC, &codec); + printf("codec set to %u\n", codec); + } else { + printf("set codec failed [%s]\n", chan->last_error); + } + for(x = 0; x < 25; x++) { unsigned char buf[2048]; zap_size_t len = sizeof(buf); diff --git a/libs/freetdm/src/zap_wanpipe.c b/libs/freetdm/src/zap_wanpipe.c index fef68ab584..d73a293e96 100644 --- a/libs/freetdm/src/zap_wanpipe.c +++ b/libs/freetdm/src/zap_wanpipe.c @@ -319,6 +319,51 @@ static ZINT_COMMAND_FUNCTION(wanpipe_command) err = wp_tdm_cmd_exec(zchan, &tdm_api); } break; + + case ZAP_COMMAND_SET_CODEC: + { + zap_codec_t codec = *((int *)obj); + unsigned wp_codec = 0; + + switch(codec) { + case ZAP_CODEC_SLIN: + wp_codec = WP_SLINEAR; + break; + default: + break; + }; + + if (wp_codec) { + tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_CODEC; + tdm_api.wp_tdm_cmd.tdm_codec = wp_codec; + err = wp_tdm_cmd_exec(zchan, &tdm_api); + } else { + snprintf(zchan->last_error, sizeof(zchan->last_error), "Invalid Codec"); + return ZAP_FAIL; + } + } + break; + case ZAP_COMMAND_GET_CODEC: + { + tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_CODEC; + + if (!(err = wp_tdm_cmd_exec(zchan, &tdm_api))) { + unsigned wp_codec = tdm_api.wp_tdm_cmd.tdm_codec; + zap_codec_t codec = ZAP_CODEC_NONE; + switch(wp_codec) { + case WP_SLINEAR: + codec = ZAP_CODEC_SLIN; + break; + default: + break; + }; + + *((int *)obj) = codec; + } + } + break; + default: + break; }; if (err) { @@ -449,14 +494,16 @@ static ZINT_WRITE_FUNCTION(wanpipe_write_unix) msg.msg_iovlen = 2; msg.msg_iov = iov; - - bsent = write(zchan->sockfd, &msg, iov[1].iov_len + sizeof(hdrframe)); + + bsent = write(zchan->sockfd, &msg, iov[1].iov_len + iov[0].iov_len); if (bsent > 0){ bsent -= sizeof(wp_tdm_api_tx_hdr_t); } *datalen = bsent; + + return ZAP_SUCCESS; } #endif