]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add a bunch of goodies
authorAnthony Minessale <anthony.minessale@gmail.com>
Sat, 19 May 2007 00:50:50 +0000 (00:50 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Sat, 19 May 2007 00:50:50 +0000 (00:50 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@35 a93c3328-9c30-0410-af19-c9cd2b2d52af

libs/freetdm/src/Makefile
libs/freetdm/src/include/openzap.h
libs/freetdm/src/openzap.c
libs/freetdm/src/testapp.c
libs/freetdm/src/wanpipe
libs/freetdm/src/zap_wanpipe.c

index 9c6788826c7a3cc90940dfb04db204749259bcbe..301d5836a949b8647eb2ae1ef0abc40246c9814a 100644 (file)
@@ -30,7 +30,7 @@
 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
-OBJS=hashtable.o hashtable_itr.o openzap.o zap_config.o libteletone_detect.o libteletone_generate.o zap_buffer.o
+OBJS=hashtable.o hashtable_itr.o openzap.o zap_config.o g711.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
@@ -69,5 +69,5 @@ zap_zt.o: zap_zt.c
        $(CC) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@
 
 clean:
-       rm -f *.o $(MYLIB) *~ \#*
+       rm -f *.o $(MYLIB) *~ \#* testapp priserver
 
index 08201a2a4176cf7e1a78c96c8d9d1167cc438113..67db68761ab9326bf9f04c60cd33bb4abee97d1d 100644 (file)
@@ -101,6 +101,8 @@ typedef int zap_socket_t;
 typedef size_t zap_size_t;
 struct zap_software_interface;
 
+#define ZAP_COMMAND_OBJ_INT *((int *)obj)
+
 #define zap_true(expr)\
        (expr && ( !strcasecmp(expr, "yes") ||\
                           !strcasecmp(expr, "on") ||\
@@ -111,6 +113,11 @@ struct zap_software_interface;
 
 #define zap_copy_string(x,y,z) strncpy(x, y, z - 1) 
 
+
+#define zap_channel_test_feature(obj, flag) ((obj)->features & flag)
+#define zap_channel_set_feature(obj, flag) (obj)->features |= (flag)
+#define zap_channel_clear_feature(obj, flag) (obj)->features &= ~(flag)
+
 /*!
   \brief Test for the existance of a flag on an arbitary object
   \command obj the object to test
@@ -169,18 +176,24 @@ 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
+       ZAP_CODEC_SLIN = 10,
+       ZAP_CODEC_NONE = (1 << 31)
 } zap_codec_t;
 
+typedef enum {
+       ZAP_TONE_DTMF = (1 << 0)
+} zap_tone_type_t;
+
 typedef enum {
        ZAP_COMMAND_NOOP,
        ZAP_COMMAND_SET_INTERVAL,
        ZAP_COMMAND_GET_INTERVAL,
        ZAP_COMMAND_SET_CODEC,
-       ZAP_COMMAND_GET_CODEC
+       ZAP_COMMAND_GET_CODEC,
+       ZAP_COMMAND_ENABLE_TONE_DETECT,
+       ZAP_COMMAND_DISABLE_TONE_DETECT
 } zap_command_t;
 
 typedef enum {
@@ -196,33 +209,23 @@ typedef enum {
        ZAP_CHAN_TYPE_FXO
 } zap_chan_type_t;
 
+typedef enum {
+       ZAP_CHANNEL_FEATURE_DTMF_DETECT = (1 << 0)
+} zap_channel_feature_t;
+
 typedef enum {
        ZAP_CHANNEL_CONFIGURED = (1 << 0),
        ZAP_CHANNEL_READY = (1 << 1),
-       ZAP_CHANNEL_OPEN = (1 << 2)
+       ZAP_CHANNEL_OPEN = (1 << 2),
+       ZAP_CHANNEL_DTMF_DETECT = (1 << 3),
+       ZAP_CHANNEL_SUPRESS_DTMF = (1 << 4)
 } zap_channel_flag_t;
 
-struct zap_channel {
-       unsigned span_id;
-       unsigned chan_id;
-       zap_chan_type_t type;
-       zap_socket_t sockfd;
-       zap_channel_flag_t flags;
-       char last_error[256];
-       void *mod_data;
-       struct zap_software_interface *zint;
-};
 typedef struct zap_channel zap_channel_t;
+typedef struct zap_event zap_event_t;
 
-struct zap_span {
-       unsigned span_id;
-       unsigned chan_count;
-       zap_span_flag_t flags;
-       struct zap_software_interface *zint;
-       zap_channel_t channels[ZAP_MAX_CHANNELS_SPAN];
-};
-typedef struct zap_span zap_span_t;
-
+#define ZINT_EVENT_CB_ARGS (zap_channel_t *zchan, zap_event_t *event)
+#define ZINT_CODEC_ARGS (void *data, zap_size_t max, zap_size_t *datalen)
 #define ZINT_CONFIGURE_ARGS (struct zap_software_interface *zint)
 #define ZINT_OPEN_ARGS (zap_channel_t *zchan)
 #define ZINT_CLOSE_ARGS (zap_channel_t *zchan)
@@ -231,6 +234,8 @@ typedef struct zap_span zap_span_t;
 #define ZINT_READ_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen)
 #define ZINT_WRITE_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen)
 
+typedef zap_status_t (*zint_event_cb_t) ZINT_EVENT_CB_ARGS ;
+typedef zap_status_t (*zint_codec_t) ZINT_CODEC_ARGS ;
 typedef zap_status_t (*zint_configure_t) ZINT_CONFIGURE_ARGS ;
 typedef zap_status_t (*zint_open_t) ZINT_OPEN_ARGS ;
 typedef zap_status_t (*zint_close_t) ZINT_CLOSE_ARGS ;
@@ -239,6 +244,8 @@ typedef zap_status_t (*zint_wait_t) ZINT_WAIT_ARGS ;
 typedef zap_status_t (*zint_read_t) ZINT_READ_ARGS ;
 typedef zap_status_t (*zint_write_t) ZINT_WRITE_ARGS ;
 
+#define ZINT_EVENT_CB_FUNCTION(name) zap_status_t name ZINT_EVENT_CB_ARGS
+#define ZINT_CODEC_FUNCTION(name) zap_status_t name ZINT_CODEC_ARGS
 #define ZINT_CONFIGURE_FUNCTION(name) zap_status_t name ZINT_CONFIGURE_ARGS
 #define ZINT_OPEN_FUNCTION(name) zap_status_t name ZINT_OPEN_ARGS
 #define ZINT_CLOSE_FUNCTION(name) zap_status_t name ZINT_CLOSE_ARGS
@@ -275,6 +282,47 @@ typedef zap_status_t (*zint_write_t) ZINT_WRITE_ARGS ;
 #define ZAP_LOG_ALERT ZAP_PRE, ZAP_LOG_LEVEL_ALERT
 #define ZAP_LOG_EMERG ZAP_PRE, ZAP_LOG_LEVEL_EMERG
 
+typedef enum {
+       ZAP_EVENT_NONE,
+       ZAP_EVENT_DTMF
+} zap_event_type_t;
+
+struct zap_event {
+       zap_event_type_t e_type;
+       void *data;
+};
+
+struct zap_channel {
+       unsigned span_id;
+       unsigned chan_id;
+       zap_chan_type_t type;
+       zap_socket_t sockfd;
+       zap_channel_flag_t flags;
+       zap_channel_feature_t features;
+       zap_codec_t effective_codec;
+       zap_codec_t native_codec;
+       teletone_dtmf_detect_state_t dtmf_detect;
+       zap_event_t event_header;
+       char last_error[256];
+       zint_event_cb_t event_callback;
+       void *mod_data;
+       unsigned skip_read_frames;
+       struct zap_span *span;
+       struct zap_software_interface *zint;
+};
+
+
+struct zap_span {
+       unsigned span_id;
+       unsigned chan_count;
+       zap_span_flag_t flags;
+       struct zap_software_interface *zint;
+       zint_event_cb_t event_callback;
+       zap_channel_t channels[ZAP_MAX_CHANNELS_SPAN];
+};
+typedef struct zap_span zap_span_t;
+
+
 typedef void (*zap_logger_t)(char *file, const char *func, int line, int level, char *fmt, ...);
 extern zap_logger_t zap_log;
 
@@ -293,9 +341,11 @@ struct zap_software_interface {
 typedef struct zap_software_interface zap_software_interface_t;
 
 
+zap_status_t zap_span_find(const char *name, unsigned id, zap_span_t **span);
 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_span_set_event_callback(zap_span_t *span, zint_event_cb_t event_callback);
+zap_status_t zap_channel_set_event_callback(zap_channel_t *zchan, zint_event_cb_t event_callback);
 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);
index a33bcdbc982ea02453843d3101fd60bbb2ec063e..1e215cf78563afa23573441143818894616f94f0 100644 (file)
@@ -177,6 +177,7 @@ zap_status_t zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_cha
                new_chan->zint = span->zint;
                new_chan->span_id = span->span_id;
                new_chan->chan_id = span->chan_count;
+               new_chan->span = span;
                zap_set_flag(new_chan, ZAP_CHANNEL_CONFIGURED | ZAP_CHANNEL_READY);
                *chan = new_chan;
                return ZAP_SUCCESS;
@@ -185,6 +186,42 @@ zap_status_t zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_cha
        return ZAP_FAIL;
 }
 
+zap_status_t zap_span_find(const char *name, unsigned id, zap_span_t **span)
+{
+       zap_software_interface_t *zint = (zap_software_interface_t *) hashtable_search(globals.interface_hash, (char *)name);
+       zap_span_t *fspan;
+
+       if (!zint) {
+               return ZAP_FAIL;
+       }
+
+       if (id > ZAP_MAX_SPANS_INTERFACE) {
+               return ZAP_FAIL;
+       }
+
+       fspan = &zint->spans[id];
+
+       if (!zap_test_flag(fspan, ZAP_SPAN_CONFIGURED)) {
+               return ZAP_FAIL;
+       }
+
+       *span = fspan;
+
+       return ZAP_SUCCESS;
+       
+}
+
+zap_status_t zap_span_set_event_callback(zap_span_t *span, zint_event_cb_t event_callback)
+{
+       span->event_callback = event_callback;
+       return ZAP_SUCCESS;
+}
+
+zap_status_t zap_channel_set_event_callback(zap_channel_t *zchan, zint_event_cb_t event_callback)
+{
+       zchan->event_callback = event_callback;
+       return ZAP_SUCCESS;
+}
 
 zap_status_t zap_channel_open_any(const char *name, unsigned span_id, zap_direction_t direction, zap_channel_t **zchan)
 {
@@ -317,6 +354,9 @@ zap_status_t zap_channel_close(zap_channel_t **zchan)
                status = check->zint->close(check);
                if (status == ZAP_SUCCESS) {
                        zap_clear_flag(check, ZAP_CHANNEL_OPEN);
+                       check->event_callback = NULL;
+                       zap_clear_flag(check, ZAP_CHANNEL_DTMF_DETECT);
+                       zap_clear_flag(check, ZAP_CHANNEL_SUPRESS_DTMF);
                        *zchan = NULL;
                }
        }
@@ -331,10 +371,50 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
        assert(zchan->zint != NULL);
 
     if (!zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) {
+               snprintf(zchan->last_error, sizeof(zchan->last_error), "channel not open");
         return ZAP_FAIL;
     }
 
+       switch(command) {
+       case ZAP_COMMAND_ENABLE_TONE_DETECT:
+               {
+                       /* if they don't have thier own, use ours */
+                       if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_DETECT)) {
+                               zap_tone_type_t tt = ZAP_COMMAND_OBJ_INT;
+                               if (tt == ZAP_TONE_DTMF) {
+                                       teletone_dtmf_detect_init (&zchan->dtmf_detect, 8000);
+                                       zap_set_flag(zchan, ZAP_CHANNEL_DTMF_DETECT);
+                                       zap_set_flag(zchan, ZAP_CHANNEL_SUPRESS_DTMF);
+                                       return ZAP_SUCCESS;
+                               } else {
+                                       snprintf(zchan->last_error, sizeof(zchan->last_error), "invalid command");
+                                       return ZAP_FAIL;
+                               }
+                       }
+               }
+               break;
+       case ZAP_COMMAND_DISABLE_TONE_DETECT:
+               {
+                       if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF_DETECT)) {
+                               zap_tone_type_t tt = ZAP_COMMAND_OBJ_INT;
+                if (tt == ZAP_TONE_DTMF) {
+                    teletone_dtmf_detect_init (&zchan->dtmf_detect, 8000);
+                    zap_clear_flag(zchan, ZAP_CHANNEL_DTMF_DETECT);
+                                       zap_clear_flag(zchan, ZAP_CHANNEL_SUPRESS_DTMF);
+                    return ZAP_SUCCESS;
+                } else {
+                    snprintf(zchan->last_error, sizeof(zchan->last_error), "invalid command");
+                    return ZAP_FAIL;
+                }
+                       }
+               }
+               break;
+       default:
+               break;
+       }
+
        if (!zchan->zint->command) {
+               snprintf(zchan->last_error, sizeof(zchan->last_error), "method not implemented");
                return ZAP_FAIL;
        }
 
@@ -348,10 +428,12 @@ zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t *flags, unsi
        assert(zchan->zint != NULL);
 
     if (!zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) {
+               snprintf(zchan->last_error, sizeof(zchan->last_error), "channel not open");
         return ZAP_FAIL;
     }
 
        if (!zchan->zint->wait) {
+               snprintf(zchan->last_error, sizeof(zchan->last_error), "method not implemented");
                return ZAP_FAIL;
        }
 
@@ -359,41 +441,282 @@ zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t *flags, unsi
 
 }
 
+/*******************************/
+ZINT_CODEC_FUNCTION(zint_slin2ulaw)
+{
+       int16_t sln_buf[512] = {0}, *sln = sln_buf;
+       uint8_t *lp = data;
+       unsigned i;
+       zap_size_t len = *datalen;
+
+       if (max > len) {
+               max = len;
+       }
+
+       memcpy(sln, data, max);
+       
+       for(i = 0; i < max; i++) {
+               *lp++ = linear_to_ulaw(*sln++);
+       }
+
+       *datalen = max / 2;
+
+       return ZAP_SUCCESS;
+
+}
+
+
+ZINT_CODEC_FUNCTION(zint_ulaw2slin)
+{
+       int16_t *sln = data;
+       uint8_t law[1024] = {0}, *lp = law;
+       unsigned i;
+       zap_size_t len = *datalen;
+       
+       if (max > len) {
+               max = len;
+       }
+
+       memcpy(law, data, max);
+
+       for(i = 0; i < max; i++) {
+               *sln++ = ulaw_to_linear(*lp++);
+       }
+
+       *datalen = max * 2;
+
+       return ZAP_SUCCESS;
+}
+
+ZINT_CODEC_FUNCTION(zint_slin2alaw)
+{
+       int16_t sln_buf[512] = {0}, *sln = sln_buf;
+       uint8_t *lp = data;
+       unsigned i;
+       zap_size_t len = *datalen;
+
+       if (max > len) {
+               max = len;
+       }
+
+       memcpy(sln, data, max);
+       
+       for(i = 0; i < max; i++) {
+               *lp++ = linear_to_alaw(*sln++);
+       }
+
+       *datalen = max / 2;
+
+       return ZAP_SUCCESS;
+
+}
+
+
+ZINT_CODEC_FUNCTION(zint_alaw2slin)
+{
+       int16_t *sln = data;
+       uint8_t law[1024] = {0}, *lp = law;
+       unsigned i;
+       zap_size_t len = *datalen;
+       
+       if (max > len) {
+               max = len;
+       }
+
+       memcpy(law, data, max);
+
+       for(i = 0; i < max; i++) {
+               *sln++ = alaw_to_linear(*lp++);
+       }
+
+       *datalen = max * 2;
+
+       return ZAP_SUCCESS;
+}
+
+ZINT_CODEC_FUNCTION(zint_ulaw2alaw)
+{
+       zap_size_t len = *datalen;
+       unsigned i;
+       uint8_t *lp = data;
+
+       if (max > len) {
+        max = len;
+    }
+
+       for(i = 0; i < max; i++) {
+               *lp = ulaw_to_alaw(*lp);
+               lp++;
+       }
+
+       return ZAP_SUCCESS;
+}
+
+ZINT_CODEC_FUNCTION(zint_alaw2ulaw)
+{
+       zap_size_t len = *datalen;
+       unsigned i;
+       uint8_t *lp = data;
+
+       if (max > len) {
+        max = len;
+    }
+
+       for(i = 0; i < max; i++) {
+               *lp = alaw_to_ulaw(*lp);
+               lp++;
+       }
+
+       return ZAP_SUCCESS;
+}
+
+/******************************/
 
 zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *datalen)
 {
+       zap_status_t status = ZAP_FAIL;
+       zint_codec_t codec_func;
+       zap_size_t max = *datalen;
+
        assert(zchan != NULL);
        assert(zchan->zint != NULL);
        assert(zchan->zint != NULL);
        
     if (!zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) {
+               snprintf(zchan->last_error, sizeof(zchan->last_error), "channel not open");
         return ZAP_FAIL;
     }
 
        if (!zchan->zint->read) {
+               snprintf(zchan->last_error, sizeof(zchan->last_error), "method not implemented");
                return ZAP_FAIL;
        }
 
-    return zchan->zint->read(zchan, data, datalen);
-       
+    status = zchan->zint->read(zchan, data, datalen);
+
+       if (status == ZAP_SUCCESS && zchan->effective_codec != zchan->native_codec) {
+               if (zchan->native_codec == ZAP_CODEC_ULAW && zchan->effective_codec == ZAP_CODEC_SLIN) {
+                       codec_func = zint_ulaw2slin;
+               } else if (zchan->native_codec == ZAP_CODEC_ULAW && zchan->effective_codec == ZAP_CODEC_ALAW) {
+                       codec_func = zint_ulaw2alaw;
+               } else if (zchan->native_codec == ZAP_CODEC_ALAW && zchan->effective_codec == ZAP_CODEC_SLIN) {
+                       codec_func = zint_alaw2slin;
+               } else if (zchan->native_codec == ZAP_CODEC_ALAW && zchan->effective_codec == ZAP_CODEC_ULAW) {
+                       codec_func = zint_alaw2ulaw;
+               }
+
+               if (codec_func) {
+                       status = codec_func(data, max, datalen);
+               } else {
+                       snprintf(zchan->last_error, sizeof(zchan->last_error), "codec error!");
+                       status = ZAP_FAIL;
+               }
+       }
+
+       if (zap_test_flag(zchan, ZAP_CHANNEL_DTMF_DETECT)) {
+               int16_t sln_buf[1024], *sln = sln_buf;
+               zap_size_t slen;
+               char digit_str[80] = "";
+
+               if (zchan->effective_codec == ZAP_CODEC_SLIN) {
+                       sln = data;
+                       slen = *datalen / 2;
+               } else {
+                       zap_size_t len = *datalen;
+                       unsigned i;
+                       uint8_t *lp = data;
+                       slen = max;
+                       
+                       if (slen > len) {
+                               slen = len;
+                       }
+
+                       if (zchan->effective_codec == ZAP_CODEC_ULAW) {
+                               for(i = 0; i < max; i++) {
+                                       *sln++ = ulaw_to_linear(*lp++);
+                               } 
+                       } else if (zchan->effective_codec == ZAP_CODEC_ALAW) {
+                               for(i = 0; i < max; i++) {
+                                       *sln++ = alaw_to_linear(*lp++);
+                               } 
+                       }
+
+                       sln = sln_buf;
+               }
+
+               teletone_dtmf_detect (&zchan->dtmf_detect, sln, slen);
+               teletone_dtmf_get(&zchan->dtmf_detect, digit_str, sizeof(digit_str));
+               if(digit_str[0]) {
+                       zint_event_cb_t event_callback = NULL;
+                       if (zchan->span->event_callback) {
+                               event_callback = zchan->span->event_callback;
+                       } else if (zchan->event_callback) {
+                               event_callback = zchan->event_callback;
+                       }
+
+                       if (event_callback) {
+                               zchan->event_header.e_type = ZAP_EVENT_DTMF;
+                               zchan->event_header.data = digit_str;
+                               event_callback(zchan, &zchan->event_header);
+                               zchan->event_header.e_type = ZAP_EVENT_NONE;
+                               zchan->event_header.data = NULL;
+                       }
+                       if (zap_test_flag(zchan, ZAP_CHANNEL_SUPRESS_DTMF)) {
+                               zchan->skip_read_frames = 20;
+                       }
+                       if (zchan->skip_read_frames > 0) {
+                               memset(data, 0, *datalen);
+                               zchan->skip_read_frames--;
+                       }  
+               }
+       }
+
+       return status;
 }
 
 
 zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t *datalen)
 {
+       zap_status_t status = ZAP_FAIL;
+       zint_codec_t codec_func;
+       zap_size_t max = *datalen;
+
        assert(zchan != NULL);
        assert(zchan->zint != NULL);
 
     if (!zap_test_flag(zchan, ZAP_CHANNEL_OPEN)) {
+               snprintf(zchan->last_error, sizeof(zchan->last_error), "channel not open");
         return ZAP_FAIL;
     }
 
        if (!zchan->zint->write) {
+               snprintf(zchan->last_error, sizeof(zchan->last_error), "method not implemented");
                return ZAP_FAIL;
        }
-
-    return zchan->zint->write(zchan, data, datalen);
        
+       
+       if (zchan->effective_codec != zchan->native_codec) {
+               if (zchan->native_codec == ZAP_CODEC_ULAW && zchan->effective_codec == ZAP_CODEC_SLIN) {
+                       codec_func = zint_slin2ulaw;
+               } else if (zchan->native_codec == ZAP_CODEC_ULAW && zchan->effective_codec == ZAP_CODEC_ALAW) {
+                       codec_func = zint_alaw2ulaw;
+               } else if (zchan->native_codec == ZAP_CODEC_ALAW && zchan->effective_codec == ZAP_CODEC_SLIN) {
+                       codec_func = zint_slin2alaw;
+               } else if (zchan->native_codec == ZAP_CODEC_ALAW && zchan->effective_codec == ZAP_CODEC_ULAW) {
+                       codec_func = zint_ulaw2alaw;
+               }
+
+               if (codec_func) {
+                       status = codec_func(data, max, datalen);
+               } else {
+                       snprintf(zchan->last_error, sizeof(zchan->last_error), "codec error!");
+                       status = ZAP_FAIL;
+               }
+       }
+
+    status = zchan->zint->write(zchan, data, datalen);
+
+       return status;
 }
 
 zap_status_t zap_global_init(void)
index ab429f0f7983fd51497d33b8c609f1e4a5f1983b..8b9ae692ba0c54dbb36cdc7182840afcf8320492 100644 (file)
@@ -6,7 +6,8 @@ int main(int argc, char *argv[])
        zap_channel_t *chan;
        unsigned ms = 20;
        zap_codec_t codec = ZAP_CODEC_SLIN;
-       
+       unsigned runs = 4;
+
        if (zap_global_init() != ZAP_SUCCESS) {
                fprintf(stderr, "Error loading OpenZAP\n");
                exit(-1);
@@ -14,11 +15,12 @@ int main(int argc, char *argv[])
 
        printf("OpenZAP loaded\n");
 
-       
+ top:
        if (zap_channel_open_any("wanpipe", 0, ZAP_TOP_DOWN, &chan) == ZAP_SUCCESS) {
                int x = 0;
                printf("opened channel %d:%d\n", chan->span_id, chan->chan_id);
 
+#if 1
                if (zap_channel_command(chan, ZAP_COMMAND_SET_INTERVAL, &ms) == ZAP_SUCCESS) {
                        ms = 0;
                        zap_channel_command(chan, ZAP_COMMAND_GET_INTERVAL, &ms);
@@ -26,7 +28,7 @@ int main(int argc, char *argv[])
                } else {
                        printf("set interval failed [%s]\n", chan->last_error);
                }
-
+#endif
                if (zap_channel_command(chan, ZAP_COMMAND_SET_CODEC, &codec) == ZAP_SUCCESS) {
                        codec = 1;
                        zap_channel_command(chan, ZAP_COMMAND_GET_CODEC, &codec);
@@ -54,10 +56,14 @@ int main(int argc, char *argv[])
                                printf("wait fail [%s]\n", chan->last_error);
                        }
                }
+               zap_channel_close(&chan);
        } else {
                printf("open fail [%s]\n", chan->last_error);
        }
 
+       if(--runs) {
+               goto top;
+       }
        zap_global_destroy();
 
 }
index 917220c04e31b86ce3d9bffdbff6eff54b9722b7..ae554a11c26bb845264ed43983f672e6745cceef 100644 (file)
@@ -2,7 +2,7 @@ MOD_CFLAGS +=-DZAP_WANPIPE_SUPPORT
 OBJS += zap_wanpipe.o
 WANPIPE_INCLUDE=/usr/include/wanpipe
 
-WP_CFLAGS =-I$(WANPIPE_INCLUDE) -I/usr/local/include -I/usr/src/linux/include -I. -I/usr/include 
+WP_CFLAGS =-Wall -Werror -I$(WANPIPE_INCLUDE) -I/usr/local/include -I/usr/src/linux/include -I. -I/usr/include 
 WP_CFLAGS +=-D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -DAFT_A104 -DWANPIPE_TDM_API -D_GNUC_ -DWANPIPE_TDM_API
 
 
index d73a293e96958f3dca848c8591e2f5e6e830c5fa..0cfaa92e49d358b3ef2142f8a7d133b3fed5a58e 100644 (file)
@@ -47,6 +47,7 @@
 #define WP_INVALID_SOCKET INVALID_HANDLE_VALUE
 #else
 #define WP_INVALID_SOCKET -1
+#include <stropts.h>
 #endif
 
 #include <wanpipe_defines.h>
 #include <zap_wanpipe_windows.h>
 #endif
 
+static struct {
+       unsigned codec_ms;
+} wp_globals;
 
 static zap_software_interface_t wanpipe_interface;
 
+static zap_status_t wp_tdm_cmd_exec(zap_channel_t *zchan, wanpipe_tdm_api_t *tdm_api)
+{
+       int err;
+
+#if defined(WIN32)
+       err = tdmv_api_ioctl(zchan->sockfd, &tdm_api->wp_tdm_cmd);
+#else
+       err = ioctl(zchan->sockfd, SIOC_WANPIPE_TDM_API, &tdm_api->wp_tdm_cmd);
+#endif
+       
+       if (err) {
+               snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
+               return ZAP_FAIL;
+       }
+
+       return ZAP_SUCCESS;
+}
+
 static zap_socket_t wp_open_device(int span, int chan) 
 {
        char fname[256];
@@ -113,6 +135,7 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
                if (sockfd != WP_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) {
                        zap_log(ZAP_LOG_INFO, "configuring device s%dc%d as OpenZAP device %d:%d fd:%d\n", spanno, x, chan->span_id, chan->chan_id, sockfd);
                        configured++;
+
                } else {
                        zap_log(ZAP_LOG_ERROR, "failure configuring device s%dc%d\n", spanno, x);
                }
@@ -188,24 +211,6 @@ static unsigned wp_configure_channel(zap_config_t *cfg, const char *str, zap_spa
        return configured;
 }
 
-static zap_status_t wp_tdm_cmd_exec(zap_channel_t *zchan, wanpipe_tdm_api_t *tdm_api)
-{
-       int err;
-
-#if defined(WIN32)
-       err = tdmv_api_ioctl(zchan->sockfd, &tdm_api->wp_tdm_cmd);
-#else
-       err = ioctl(zchan->sockfd, SIOC_WANPIPE_TDM_API, &tdm_api->wp_tdm_cmd);
-#endif
-       
-       if (err) {
-               snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
-               return ZAP_FAIL;
-       }
-
-       return ZAP_SUCCESS;
-}
-
 static ZINT_CONFIGURE_FUNCTION(wanpipe_configure)
 {
        zap_config_t cfg;
@@ -223,7 +228,16 @@ static ZINT_CONFIGURE_FUNCTION(wanpipe_configure)
        }
        
        while (zap_config_next_pair(&cfg, &var, &val)) {
-               if (!strcasecmp(cfg.category, "span")) {
+               if (!strcasecmp(cfg.category, "defaults")) {
+                       if (!strcasecmp(var, "codec_ms")) {
+                               unsigned codec_ms = atoi(val);
+                               if (codec_ms < 10 || codec_ms > 60) {
+                                       zap_log(ZAP_LOG_WARNING, "invalid codec ms at line %d\n", cfg.lineno);
+                               } else {
+                                       wp_globals.codec_ms = codec_ms;
+                               }
+                       }
+               } else if (!strcasecmp(cfg.category, "span")) {
                        if (cfg.catno != catno) {
                                zap_log(ZAP_LOG_DEBUG, "found config for span\n");
                                catno = cfg.catno;
@@ -282,7 +296,28 @@ static ZINT_CONFIGURE_FUNCTION(wanpipe_configure)
 
 static ZINT_OPEN_FUNCTION(wanpipe_open) 
 {
-       ZINT_OPEN_MUZZLE;
+
+       wanpipe_tdm_api_t tdm_api;
+
+       if (zchan->type == ZAP_CHAN_TYPE_DQ921 || zchan->type == ZAP_CHAN_TYPE_DQ931) {
+               zchan->native_codec = zchan->effective_codec = ZAP_CODEC_NONE;
+       } else {
+               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_CODEC;
+               tdm_api.wp_tdm_cmd.tdm_codec = WP_NONE;
+               wp_tdm_cmd_exec(zchan, &tdm_api);
+
+               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_USR_PERIOD;
+               tdm_api.wp_tdm_cmd.usr_period = wp_globals.codec_ms;
+               wp_tdm_cmd_exec(zchan, &tdm_api);
+
+               tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_HW_CODING;
+               if (tdm_api.wp_tdm_cmd.hw_tdm_coding) {
+                       zchan->native_codec = zchan->effective_codec = ZAP_CODEC_ULAW;
+               } else {
+                       zchan->native_codec = zchan->effective_codec = ZAP_CODEC_ALAW;
+               }
+       }
+
        return ZAP_SUCCESS;
 }
 
@@ -307,7 +342,7 @@ static ZINT_COMMAND_FUNCTION(wanpipe_command)
                        tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_GET_USR_PERIOD;
 
                        if (!(err = wp_tdm_cmd_exec(zchan, &tdm_api))) {
-                               *((int *)obj) = tdm_api.wp_tdm_cmd.usr_period;
+                               ZAP_COMMAND_OBJ_INT = tdm_api.wp_tdm_cmd.usr_period;
                        }
 
                }
@@ -315,51 +350,22 @@ static ZINT_COMMAND_FUNCTION(wanpipe_command)
        case ZAP_COMMAND_SET_INTERVAL: 
                {
                        tdm_api.wp_tdm_cmd.cmd = SIOC_WP_TDM_SET_USR_PERIOD;
-                       tdm_api.wp_tdm_cmd.usr_period = *((int *)obj);
+                       tdm_api.wp_tdm_cmd.usr_period = ZAP_COMMAND_OBJ_INT;
                        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;
-                       }
+                       zchan->effective_codec = ZAP_COMMAND_OBJ_INT;
+                       err = 0;
                }
                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;
-                       }
+                       ZAP_COMMAND_OBJ_INT = zchan->effective_codec;
+                       err = 0;
                }
                break;
        default:
@@ -413,7 +419,7 @@ static ZINT_WAIT_FUNCTION(wanpipe_wait)
        s = select(zchan->sockfd + 1, r, w, e, tvp);
 
        if (s < 0) {
-               snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
+               snprintf(zchan->last_error, sizeof(zchan->last_error), "select: %s", strerror(errno));
                return ZAP_FAIL;
        }
        
@@ -434,7 +440,8 @@ static ZINT_WAIT_FUNCTION(wanpipe_wait)
        if (s == 0) {
                return ZAP_TIMEOUT;
        }
-
+       
+       return ZAP_SUCCESS;
 }
 
 #ifndef __WINDOWS__
@@ -494,7 +501,6 @@ static ZINT_WRITE_FUNCTION(wanpipe_write_unix)
        
        msg.msg_iovlen = 2;
        msg.msg_iov = iov;
-       
        bsent = write(zchan->sockfd, &msg, iov[1].iov_len + iov[0].iov_len);
 
        if (bsent > 0){
@@ -510,13 +516,11 @@ static ZINT_WRITE_FUNCTION(wanpipe_write_unix)
 
 static ZINT_READ_FUNCTION(wanpipe_read)
 {
-       ZINT_READ_MUZZLE;
-       
+
 #ifndef WIN32
        return wanpipe_read_unix(zchan, data, datalen);
 #endif
-       
-       return ZAP_FAIL;
+
 }
 
 static ZINT_WRITE_FUNCTION(wanpipe_write)
@@ -535,6 +539,7 @@ zap_status_t wanpipe_init(zap_software_interface_t **zint)
        assert(zint != NULL);
        memset(&wanpipe_interface, 0, sizeof(wanpipe_interface));
 
+       wp_globals.codec_ms = 20;
        wanpipe_interface.name = "wanpipe";
        wanpipe_interface.configure =  wanpipe_configure;
        wanpipe_interface.open = wanpipe_open;