]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
update
authorAnthony Minessale <anthony.minessale@gmail.com>
Mon, 21 May 2007 17:48:13 +0000 (17:48 +0000)
committerAnthony Minessale <anthony.minessale@gmail.com>
Mon, 21 May 2007 17:48:13 +0000 (17:48 +0000)
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@62 a93c3328-9c30-0410-af19-c9cd2b2d52af

libs/openzap/src/Makefile
libs/openzap/src/g711.c [new file with mode: 0644]
libs/openzap/src/include/openzap.h
libs/openzap/src/include/sangoma_tdm_api.h
libs/openzap/src/include/zap_threadmutex.h
libs/openzap/src/include/zap_types.h
libs/openzap/src/openzap.c
libs/openzap/src/testapp.c
libs/openzap/src/zap_threadmutex.c
libs/openzap/src/zap_wanpipe.c

index 8ec0c6dd2db10bc8acebf54e9cde0973d0190b15..50e4b6ba7b9356a1e05b516442a8cb28a05f5e64 100644 (file)
@@ -44,7 +44,7 @@ $(MYLIB): $(OBJS)
        ranlib $(MYLIB)
 
 testapp: testapp.c $(MYLIB)
-       $(CC) -L. -Iinclude testapp.c -o testapp -lopenzap -lm
+       $(CC) -L. -Iinclude testapp.c -o testapp -lopenzap -lm -lpthread
 
 
 priserver.o: priserver.c
@@ -54,7 +54,7 @@ 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
+       $(CC) sangoma_pri.o priserver.o -L. -o priserver -lopenzap -lm -lpthread ../../libpri-1.2.4/libpri.a
 
 openzap.o: openzap.c
        $(CC) $(MOD_CFLAGS) $(CC_CFLAGS) $(CFLAGS) -c $< -o $@
diff --git a/libs/openzap/src/g711.c b/libs/openzap/src/g711.c
new file mode 100644 (file)
index 0000000..8a5c58b
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * g711.c - A-law and u-law transcoding routines
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2006 Steve Underwood
+ *
+ *  Despite my general liking of the GPL, I place this code in the
+ *  public domain for the benefit of all mankind - even the slimy
+ *  ones who might try to proprietize my work and use it to my
+ *  detriment.
+ *
+ * $Id: g711.c,v 1.1 2006/06/07 15:46:39 steveu Exp $
+ */
+
+/*! \file */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#ifndef _MSC_VER
+#include <inttypes.h>
+#ifdef HAVE_TGMATH_H
+#include <tgmath.h>
+#endif
+#endif
+
+#include "g711.h"
+
+/* Copied from the CCITT G.711 specification */
+static const uint8_t ulaw_to_alaw_table[256] =
+{
+     42,  43,  40,  41,  46,  47,  44,  45,  34,  35,  32,  33,  38,  39,  36,  37,
+     58,  59,  56,  57,  62,  63,  60,  61,  50,  51,  48,  49,  54,  55,  52,  53,
+     10,  11,   8,   9,  14,  15,  12,  13,   2,   3,   0,   1,   6,   7,   4,  26,
+     27,  24,  25,  30,  31,  28,  29,  18,  19,  16,  17,  22,  23,  20,  21, 106,
+    104, 105, 110, 111, 108, 109,  98,  99,  96,  97, 102, 103, 100, 101, 122, 120,
+    126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117,  75,  73,  79,  77,
+     66,  67,  64,  65,  70,  71,  68,  69,  90,  91,  88,  89,  94,  95,  92,  93,
+     82,  82,  83,  83,  80,  80,  81,  81,  86,  86,  87,  87,  84,  84,  85,  85,
+    170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
+    186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181,
+    138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154,
+    155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234,
+    232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248,
+    254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205,
+    194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221,
+    210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213, 213
+};
+
+/* These transcoding tables are copied from the CCITT G.711 specification. To achieve
+   optimal results, do not change them. */
+
+static const uint8_t alaw_to_ulaw_table[256] =
+{
+     42,  43,  40,  41,  46,  47,  44,  45,  34,  35,  32,  33,  38,  39,  36,  37,
+     57,  58,  55,  56,  61,  62,  59,  60,  49,  50,  47,  48,  53,  54,  51,  52,
+     10,  11,   8,   9,  14,  15,  12,  13,   2,   3,   0,   1,   6,   7,   4,   5,
+     26,  27,  24,  25,  30,  31,  28,  29,  18,  19,  16,  17,  22,  23,  20,  21,
+     98,  99,  96,  97, 102, 103, 100, 101,  93,  93,  92,  92,  95,  95,  94,  94,
+    116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109,
+     72,  73,  70,  71,  76,  77,  74,  75,  64,  65,  63,  63,  68,  69,  66,  67,
+     86,  87,  84,  85,  90,  91,  88,  89,  79,  79,  78,  78,  82,  83,  80,  81,
+    170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
+    185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180,
+    138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133,
+    154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149,
+    226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222,
+    244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237,
+    200, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195,
+    214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209
+};
+
+uint8_t alaw_to_ulaw(uint8_t alaw)
+{
+    return alaw_to_ulaw_table[alaw];
+}
+/*- End of function --------------------------------------------------------*/
+
+uint8_t ulaw_to_alaw(uint8_t ulaw)
+{
+    return ulaw_to_alaw_table[ulaw];
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/
index 8f4b012a800305f528a4fd30b0e2f8a420d1b719..256b4e8f9bb23515a07b46fa84c5f4a5ad2192ea 100644 (file)
@@ -87,6 +87,7 @@
 #include "g711.h"
 #include "libteletone.h"
 #include "zap_buffer.h"
+#include "zap_threadmutex.h"
 
 #ifdef  NDEBUG
 #undef assert
@@ -96,7 +97,7 @@
 #define ZAP_MAX_CHANNELS_SPAN 513
 #define ZAP_MAX_SPANS_INTERFACE 33
 
-
+#define GOTO_STATUS(label,st) status = st; goto label ;
 
 #define zap_true(expr)\
        (expr && ( !strcasecmp(expr, "yes") ||\
@@ -190,6 +191,7 @@ struct zap_span {
        zap_span_flag_t flags;
        struct zap_software_interface *zint;
        zint_event_cb_t event_callback;
+       zap_mutex_t *mutex;
        zap_channel_t channels[ZAP_MAX_CHANNELS_SPAN];
 };
 
@@ -211,6 +213,7 @@ struct zap_software_interface {
 
 zap_status_t zap_span_find(const char *name, uint32_t 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_close_all(zap_software_interface_t *zint);
 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);
@@ -218,7 +221,7 @@ zap_status_t zap_channel_open(const char *name, uint32_t span_id, uint32_t chan_
 zap_status_t zap_channel_open_any(const char *name, uint32_t 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, uint32_t to);
+zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to);
 zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *datalen);
 zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t *datalen);
 zap_status_t zap_global_init(void);
index a58caf5d8d6e4d0a0399a2a7df2382a7c5e40be5..b8b40d61fb303368440c1ebe7892adaffb61c4f4 100644 (file)
@@ -107,7 +107,7 @@ static __inline__ int tdmv_api_ioctl(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api_cmd
 
        memcpy( wan_udp.wan_udphdr_data, (void*)tdm_api_cmd, sizeof(wanpipe_tdm_api_cmd_t));
 
-       if(DeviceIoControl(
+       if (DeviceIoControl(
                        fd,
                        IoctlManagementCommand,
                        (LPVOID)&wan_udp,
@@ -120,7 +120,7 @@ static __inline__ int tdmv_api_ioctl(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api_cmd
                return 1;
        }
 
-       if(wan_udp.wan_udphdr_return_code != WAN_CMD_OK){
+       if (wan_udp.wan_udphdr_return_code != WAN_CMD_OK){
                return 2;
        }
 
@@ -137,7 +137,7 @@ static __inline__ int tdmv_api_ioctl(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api_cmd
 
 void __inline__ tdmv_api_close_socket(sng_fd_t *sp) 
 {
-       if    *sp != WP_INVALID_SOCKET){
+       if (    *sp != WP_INVALID_SOCKET){
 #if defined(__WINDOWS__)
                CloseHandle(*sp);
 #else
@@ -186,7 +186,7 @@ static __inline__ sng_fd_t tdmv_api_open_span_chan(int span, int chan)
                (LPOVERLAPPED)NULL
                );
 
-       if((wan_udp.wan_udphdr_return_code) || (*(int*)&wan_udp.wan_udphdr_data[0] != 1)){
+       if ((wan_udp.wan_udphdr_return_code) || (*(int*)&wan_udp.wan_udphdr_data[0] != 1)){
                /* somone already has this channel, or somthing else is not right. */
                tdmv_api_close_socket(&fd);
        }
@@ -218,7 +218,7 @@ static __inline__ sng_fd_t tdmv_api_open_span_chan(int span, int chan)
 /* a cross platform way to poll on an actual pollset (span and/or list of spans) will probably also be needed for analog */
 /* so we can have one analong handler thread that will deal with all the idle analog channels for events */
 /* the alternative would be for the driver to provide one socket for all of the oob events for all analog channels */
-static __inline__ int tdmv_api_wait_socket(sng_fd_t fd, int timeout, int flags)
+static __inline__ int tdmv_api_wait_socket(sng_fd_t fd, int timeout, int *flags)
 {
 #if defined(__WINDOWS__)
        DWORD ln;
@@ -226,7 +226,7 @@ static __inline__ int tdmv_api_wait_socket(sng_fd_t fd, int timeout, int flags)
 
        memset(&api_poll, 0x00, sizeof(API_POLL_STRUCT));
        
-       api_poll.user_flags_bitmap = flags;
+       api_poll.user_flags_bitmap = *flags;
        api_poll.timeout = timeout;
 
        if (!DeviceIoControl(
@@ -241,6 +241,8 @@ static __inline__ int tdmv_api_wait_socket(sng_fd_t fd, int timeout, int flags)
                return -1;
        }
 
+       *flags = 0;
+
        switch(api_poll.operation_status)
        {
                case SANG_STATUS_RX_DATA_AVAILABLE:
@@ -253,37 +255,36 @@ static __inline__ int tdmv_api_wait_socket(sng_fd_t fd, int timeout, int flags)
                        return -1;
        }
 
-       if(api_poll.poll_events_bitmap == 0){
+       if (api_poll.poll_events_bitmap == 0){
                return -1;
        }
 
-       if(api_poll.poll_events_bitmap & POLL_EVENT_TIMEOUT){
+       if (api_poll.poll_events_bitmap & POLL_EVENT_TIMEOUT) {
                return 0;
        }
 
-       return api_poll.poll_events_bitmap;
+       *flags = api_poll.poll_events_bitmap;
+
+       return 1;
 #else
     struct pollfd pfds[1];
     int res;
 
     memset(&pfds[0], 0, sizeof(pfds[0]));
     pfds[0].fd = fd;
-    pfds[0].events = flags;
+    pfds[0].events = *flags;
     res = poll(pfds, 1, timeout);
+       *flags = 0;
 
-       if (res == 0) {
-               return 0;
-       }
-
-       if (res < 0) {
-               return -1;
+       if (pfds[0].revents & POLLERR) {
+               res = -1;
        }
 
-       if ((pfds[0].revents & POLLERR)) {
-               return -1;
+       if (res > 0) {
+               *flags = pfds[0].revents;
        }
 
-    return pfds[0].revents;
+    return res;
 #endif
 }
 
@@ -303,11 +304,11 @@ static __inline__ int tdmv_api_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen
        wp_tdm_api_rx_hdr_t             *user_buf = (wp_tdm_api_rx_hdr_t*)hdrbuf;
        DWORD ln;
 
-       if(hdrlen != sizeof(wp_tdm_api_rx_hdr_t)){
+       if (hdrlen != sizeof(wp_tdm_api_rx_hdr_t)){
                return -1;
        }
 
-       if(!DeviceIoControl(
+       if (!DeviceIoControl(
                        fd,
                        IoctlReadCommand,
                        (LPVOID)NULL,
@@ -328,7 +329,7 @@ static __inline__ int tdmv_api_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen
        switch(pri->operation_status)
        {
        case SANG_STATUS_RX_DATA_AVAILABLE:
-               if(pri->data_length > datalen){
+               if (pri->data_length > datalen){
                        break;
                }
                memcpy(databuf, rx_data.data, pri->data_length);
@@ -384,7 +385,7 @@ static __inline__ int tdmv_api_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrle
        pri->data_length = datalen;
        memcpy(local_tx_data.data, databuf, pri->data_length);
 
-       if(!DeviceIoControl(
+       if (!DeviceIoControl(
                        fd,
                        IoctlWriteCommand,
                        (LPVOID)&local_tx_data,
@@ -406,18 +407,18 @@ static __inline__ int tdmv_api_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrle
 
        memset(&msg,0,sizeof(struct msghdr));
 
-       iov[0].iov_len=hdrlen;
-       iov[0].iov_base=hdrbuf;
+       iov[0].iov_len = hdrlen;
+       iov[0].iov_base = hdrbuf;
 
-       iov[1].iov_len=datalen;
-       iov[1].iov_base=databuf;
+       iov[1].iov_len = datalen;
+       iov[1].iov_base = databuf;
 
-       msg.msg_iovlen=2;
-       msg.msg_iov=iov;
+       msg.msg_iovlen = 2;
+       msg.msg_iov = iov;
 
-       bsent = write(fd,&msg,datalen+hdrlen);
+       bsent = write(fd, &msg, datalen + hdrlen);
        if (bsent > 0){
-               bsent-=sizeof(wp_tdm_api_tx_hdr_t);
+               bsent -= sizeof(wp_tdm_api_tx_hdr_t);
        }
 #endif
        return bsent;
index 9a9b336ed1384f8ce5bb204937786708e38488fb..557f23ea51e64882f8657335ac025c4ec5da001c 100644 (file)
@@ -31,7 +31,7 @@ zap_status_t zap_thread_create_detached(zap_thread_function_t func, void *data);
 zap_status_t zap_thread_create_detached_ex(zap_thread_function_t func, void *data, zap_size_t stack_size);
 void zap_thread_override_default_stacksize(zap_size_t size);
 zap_status_t zap_mutex_create(zap_mutex_t **mutex);
-zap_status_t zap_mutex_destroy(zap_mutex_t *mutex);
+zap_status_t zap_mutex_destroy(zap_mutex_t **mutex);
 zap_status_t zap_mutex_lock(zap_mutex_t *mutex);
 zap_status_t zap_mutex_trylock(zap_mutex_t *mutex);
 zap_status_t zap_mutex_unlock(zap_mutex_t *mutex);
index d4ba2428db144f52eb5083f3b8d01aa8d3203f2d..9e189a138ad269603b6d9aa34c6e19ff2a4034fc 100644 (file)
@@ -66,9 +66,9 @@ typedef enum {
 
 typedef enum {
        ZAP_NO_FLAGS = 0,
-       ZAP_READ =  (1 <<  0),
-       ZAP_WRITE = (1 <<  1),
-       ZAP_ERROR = (1 <<  2)
+       ZAP_READ =  (1 << 0),
+       ZAP_WRITE = (1 << 1),
+       ZAP_EVENTS = (1 << 2)
 } zap_wait_flag_t;
 
 typedef enum {
@@ -139,7 +139,7 @@ typedef struct zap_event zap_event_t;
 #define ZINT_OPEN_ARGS (zap_channel_t *zchan)
 #define ZINT_CLOSE_ARGS (zap_channel_t *zchan)
 #define ZINT_COMMAND_ARGS (zap_channel_t *zchan, zap_command_t command, void *obj)
-#define ZINT_WAIT_ARGS (zap_channel_t *zchan, zap_wait_flag_t *flags, uint32_t to)
+#define ZINT_WAIT_ARGS (zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to)
 #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)
 
index b10227bb6314b116d913435edde34ef66860e5da..3550fed88031ac5df8429f137de2608cfa6dc124 100644 (file)
@@ -42,6 +42,7 @@
 
 static struct {
        zap_hash_t *interface_hash;
+       zap_mutex_t *mutex;
 } globals;
 
 static char *LEVEL_NAMES[] = {
@@ -158,6 +159,7 @@ zap_status_t zap_span_create(zap_software_interface_t *zint, zap_span_t **span)
                zap_set_flag(new_span, ZAP_SPAN_CONFIGURED);
                new_span->span_id = zint->span_index;
                new_span->zint = zint;
+               zap_mutex_create(&new_span->mutex);
                *span = new_span;
                return ZAP_SUCCESS;
        }
@@ -165,6 +167,21 @@ zap_status_t zap_span_create(zap_software_interface_t *zint, zap_span_t **span)
        return ZAP_FAIL;
 }
 
+zap_status_t zap_span_close_all(zap_software_interface_t *zint)
+{
+       zap_span_t *span;
+       uint32_t i;
+
+       for(i = 0; i < zint->span_index; i++) {
+               span = &zint->spans[i];
+               if (span->mutex) {
+                       zap_mutex_destroy(&span->mutex);
+               }
+       }
+       
+       return i ? ZAP_SUCCESS : ZAP_FAIL;
+}
+
 zap_status_t zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_chan_type_t type, zap_channel_t **chan)
 {
        if (span->chan_count < ZAP_MAX_CHANNELS_SPAN) {
@@ -186,9 +203,13 @@ zap_status_t zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_cha
 
 zap_status_t zap_span_find(const char *name, uint32_t id, zap_span_t **span)
 {
-       zap_software_interface_t *zint = (zap_software_interface_t *) hashtable_search(globals.interface_hash, (char *)name);
+       zap_software_interface_t *zint;
        zap_span_t *fspan;
 
+       zap_mutex_lock(globals.mutex);
+       zint = (zap_software_interface_t *) hashtable_search(globals.interface_hash, (char *)name);
+       zap_mutex_unlock(globals.mutex);
+
        if (!zint) {
                return ZAP_FAIL;
        }
@@ -211,25 +232,33 @@ zap_status_t zap_span_find(const char *name, uint32_t id, zap_span_t **span)
 
 zap_status_t zap_span_set_event_callback(zap_span_t *span, zint_event_cb_t event_callback)
 {
+       zap_mutex_lock(span->mutex);
        span->event_callback = event_callback;
+       zap_mutex_unlock(span->mutex);
        return ZAP_SUCCESS;
 }
 
 zap_status_t zap_channel_set_event_callback(zap_channel_t *zchan, zint_event_cb_t event_callback)
 {
+       zap_mutex_lock(zchan->span->mutex);
        zchan->event_callback = event_callback;
+       zap_mutex_unlock(zchan->span->mutex);
        return ZAP_SUCCESS;
 }
 
 zap_status_t zap_channel_open_any(const char *name, uint32_t 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_software_interface_t *zint;
        zap_status_t status = ZAP_FAIL;
        zap_channel_t *check;
        uint32_t i,j;
        zap_span_t *span;
        uint32_t span_max;
 
+       zap_mutex_lock(globals.mutex);
+       zint = (zap_software_interface_t *) hashtable_search(globals.interface_hash, (char *)name);
+       zap_mutex_unlock(globals.mutex);
+
        if (!zint) {
                zap_log(ZAP_LOG_ERROR, "Invalid interface name!\n");
                return ZAP_FAIL;
@@ -247,7 +276,7 @@ zap_status_t zap_channel_open_any(const char *name, uint32_t span_id, zap_direct
                j = span_max;
        }
 
-       
+       zap_mutex_lock(globals.mutex);
 
        for(;;) {
                span = &zint->spans[j];
@@ -314,25 +343,60 @@ zap_status_t zap_channel_open_any(const char *name, uint32_t span_id, zap_direct
                }
        }
 
+       zap_mutex_unlock(globals.mutex);
+
        return status;
 }
 
+static zap_status_t zap_channel_reset(zap_channel_t *zchan)
+{
+       zap_clear_flag(zchan, ZAP_CHANNEL_OPEN);
+       zchan->event_callback = NULL;
+       zap_clear_flag(zchan, ZAP_CHANNEL_DTMF_DETECT);
+       zap_clear_flag(zchan, ZAP_CHANNEL_SUPRESS_DTMF);
+       if (zchan->tone_session.buffer) {
+               teletone_destroy_session(&zchan->tone_session);
+               memset(&zchan->tone_session, 0, sizeof(zchan->tone_session));
+       }
+       if (zchan->dtmf_buffer) {
+               zap_buffer_destroy(&zchan->dtmf_buffer);
+       }
+       zchan->dtmf_on = zchan->dtmf_off = 0;
+
+       if (zap_test_flag(zchan, ZAP_CHANNEL_TRANSCODE)) {
+               zchan->effective_codec = zchan->native_codec;
+               zchan->packet_len = zchan->native_interval * (zchan->effective_codec == ZAP_CODEC_SLIN ? 16 : 8);
+               zap_clear_flag(zchan, ZAP_CHANNEL_TRANSCODE);
+       }
+
+       return ZAP_SUCCESS;
+}
+
+
+
 zap_status_t zap_channel_open(const char *name, uint32_t span_id, uint32_t chan_id, zap_channel_t **zchan)
 {
-       zap_software_interface_t *zint = (zap_software_interface_t *) hashtable_search(globals.interface_hash, (char *)name);
+       zap_software_interface_t *zint;
        zap_status_t status = ZAP_FAIL;
 
+       zap_mutex_lock(globals.mutex);
+    zint = (zap_software_interface_t *) hashtable_search(globals.interface_hash, (char *)name);
+    zap_mutex_unlock(globals.mutex);
+       
+
        if (span_id < ZAP_MAX_SPANS_INTERFACE && chan_id < ZAP_MAX_CHANNELS_SPAN && zint) {
                zap_channel_t *check;
+               zap_mutex_lock(zint->spans[span_id].mutex);
                check = &zint->spans[span_id].channels[chan_id];
+
                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;
                }
+               zap_mutex_unlock(zint->spans[span_id].mutex);
        }
 
        return status;
@@ -347,25 +411,17 @@ zap_status_t zap_channel_close(zap_channel_t **zchan)
        check = *zchan;
        assert(check != NULL);
        *zchan = NULL;
-       
+
+       zap_mutex_lock(check->span->mutex);
        if (zap_test_flag(check, ZAP_CHANNEL_OPEN)) {
                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);
-                       if (check->tone_session.buffer) {
-                               teletone_destroy_session(&check->tone_session);
-                               memset(&check->tone_session, 0, sizeof(check->tone_session));
-                       }
-                       if (check->dtmf_buffer) {
-                               zap_buffer_destroy(&check->dtmf_buffer);
-                       }
-                       check->dtmf_on = check->dtmf_off = 0;
+                       zap_channel_reset(check);
                        *zchan = NULL;
                }
        }
+
+       zap_mutex_unlock(check->span->mutex);
        
        return status;
 }
@@ -405,6 +461,8 @@ static zap_status_t zchan_activate_dtmf_buffer(zap_channel_t *zchan)
 
 zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, void *obj)
 {
+       zap_status_t status = ZAP_FAIL;
+
        assert(zchan != NULL);
        assert(zchan->zint != NULL);
 
@@ -413,6 +471,8 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
         return ZAP_FAIL;
     }
 
+       zap_mutex_lock(zchan->span->mutex);
+
        switch(command) {
        case ZAP_COMMAND_SET_INTERVAL:
                {
@@ -424,7 +484,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                                        zap_set_flag(zchan, ZAP_CHANNEL_BUFFER);
                                }
                                zchan->packet_len = zchan->native_interval * (zchan->effective_codec == ZAP_CODEC_SLIN ? 16 : 8);
-                               return ZAP_SUCCESS;
+                               GOTO_STATUS(done, ZAP_SUCCESS);
                        }
                }
                break;
@@ -432,7 +492,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                {
                        if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_INTERVAL)) {
                                ZAP_COMMAND_OBJ_INT = zchan->effective_interval;
-                               return ZAP_SUCCESS;
+                               GOTO_STATUS(done, ZAP_SUCCESS);
                        }
                }
                break;
@@ -446,7 +506,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                                        zap_set_flag(zchan, ZAP_CHANNEL_TRANSCODE);
                                }
                                zchan->packet_len = zchan->native_interval * (zchan->effective_codec == ZAP_CODEC_SLIN ? 16 : 8);
-                               return ZAP_SUCCESS;
+                               GOTO_STATUS(done, ZAP_SUCCESS);
                        }
                }
                break;
@@ -455,7 +515,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                {
                        if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_CODECS)) {
                                ZAP_COMMAND_OBJ_INT = zchan->effective_codec;
-                               return ZAP_SUCCESS;
+                               GOTO_STATUS(done, ZAP_SUCCESS);
                        }
                }
                break;
@@ -468,10 +528,10 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                                        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;
+                                       GOTO_STATUS(done, ZAP_SUCCESS);
                                } else {
                                        snprintf(zchan->last_error, sizeof(zchan->last_error), "invalid command");
-                                       return ZAP_FAIL;
+                                       GOTO_STATUS(done, ZAP_FAIL);
                                }
                        }
                }
@@ -484,10 +544,10 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                     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;
+                                       GOTO_STATUS(done, ZAP_SUCCESS);
                 } else {
                     snprintf(zchan->last_error, sizeof(zchan->last_error), "invalid command");
-                    return ZAP_FAIL;
+                                       GOTO_STATUS(done, ZAP_FAIL);
                 }
                        }
                }
@@ -495,7 +555,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                {
                        if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) {
                                ZAP_COMMAND_OBJ_INT = zchan->dtmf_on;
-                               return ZAP_SUCCESS;
+                               GOTO_STATUS(done, ZAP_SUCCESS);
                        }
                }
                break;
@@ -503,7 +563,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                {
                        if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) {
                                ZAP_COMMAND_OBJ_INT = zchan->dtmf_on;
-                               return ZAP_SUCCESS;
+                               GOTO_STATUS(done, ZAP_SUCCESS);
                        }
                }
                break;
@@ -513,10 +573,10 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                                int val = ZAP_COMMAND_OBJ_INT;
                                if (val > 10 && val < 1000) {
                                        zchan->dtmf_on = val;
-                                       return ZAP_SUCCESS;
+                                       GOTO_STATUS(done, ZAP_SUCCESS);
                                } else {
                                        snprintf(zchan->last_error, sizeof(zchan->last_error), "invalid value %d range 10-1000", val);
-                                       return ZAP_FAIL;
+                                       GOTO_STATUS(done, ZAP_FAIL);
                                }
                        }
                }
@@ -527,10 +587,10 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                                int val = ZAP_COMMAND_OBJ_INT;
                                if (val > 10 && val < 1000) {
                                        zchan->dtmf_off = val;
-                                       return ZAP_SUCCESS;
+                                       GOTO_STATUS(done, ZAP_SUCCESS);
                                } else {
                                        snprintf(zchan->last_error, sizeof(zchan->last_error), "invalid value %d range 10-1000", val);
-                                       return ZAP_FAIL;
+                                       GOTO_STATUS(done, ZAP_FAIL);
                                }
                        }
                }
@@ -538,16 +598,15 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
        case ZAP_COMMAND_SEND_DTMF:
                {
                        if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) {
-                               zap_status_t status;
                                char *cur;
                                char *digits = ZAP_COMMAND_OBJ_CHAR_P;
                                if (!zchan->dtmf_buffer) {
                                        if ((status = zchan_activate_dtmf_buffer(zchan)) != ZAP_SUCCESS) {
-                                               return status;
+                                               GOTO_STATUS(done, status);
                                        }
                                }
                                zap_log(ZAP_LOG_DEBUG, "Adding DTMF SEQ [%s]\n", digits);       
-
+                               
                                for (cur = digits; *cur; cur++) {
                                        int wrote = 0;
                                        if ((wrote = teletone_mux_tones(&zchan->tone_session, &zchan->tone_session.TONES[(int)*cur]))) {
@@ -556,7 +615,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
                                }
                                
                                zchan->skip_read_frames = 200;
-                               return ZAP_SUCCESS;
+                               GOTO_STATUS(done, ZAP_SUCCESS);
                        }
                }
                break;
@@ -566,14 +625,18 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
 
        if (!zchan->zint->command) {
                snprintf(zchan->last_error, sizeof(zchan->last_error), "method not implemented");
-               return ZAP_FAIL;
+               GOTO_STATUS(done, ZAP_FAIL);
        }
 
-    return zchan->zint->command(zchan, command, obj);
+    status = zchan->zint->command(zchan, command, obj);
+
+ done:
+       zap_mutex_unlock(zchan->span->mutex);
+       return status;
 
 }
 
-zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t *flags, uint32_t to)
+zap_status_t zap_channel_wait(zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to)
 {
        assert(zchan != NULL);
        assert(zchan->zint != NULL);
@@ -899,30 +962,39 @@ zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t *dat
        return status;
 }
 
+static struct {
+       zap_software_interface_t *wanpipe_interface;
+       zap_software_interface_t *zt_interface;
+} interfaces;
+
 zap_status_t zap_global_init(void)
 {
        zap_config_t cfg;
        char *var, *val;
        uint32_t configured = 0;
-       zap_software_interface_t *zint;
        int modcount;
 
+       memset(&interfaces, 0, sizeof(interfaces));
        globals.interface_hash = create_hashtable(16, hashfromstring, equalkeys);
-       zint = NULL;
        modcount = 0;
-
+       zap_mutex_create(&globals.mutex);
+       
 #ifdef ZAP_WANPIPE_SUPPORT
-       if (wanpipe_init(&zint) == ZAP_SUCCESS) {
-               hashtable_insert(globals.interface_hash, (void *)zint->name, zint);
+       if (wanpipe_init(&interfaces.wanpipe_interface) == ZAP_SUCCESS) {
+               zap_mutex_lock(globals.mutex);
+               hashtable_insert(globals.interface_hash, (void *)interfaces.wanpipe_interface->name, interfaces.wanpipe_interface);
+               zap_mutex_unlock(globals.mutex);
                modcount++;
        } else {
                zap_log(ZAP_LOG_ERROR, "Error initilizing wanpipe.\n"); 
        }
 #endif
-       zint = NULL;
+
 #ifdef ZAP_ZT_SUPPORT
-       if (zt_init(&zint) == ZAP_SUCCESS) {
-               hashtable_insert(globals.interface_hash, (void *)zint->name, zint);
+       if (zt_init(&interfaces.zt_interface) == ZAP_SUCCESS) {
+               zap_mutex_lock(globals.mutex);
+               hashtable_insert(globals.interface_hash, (void *)interfaces.zt_interface->name, interfaces.zt_interface);
+               zap_mutex_unlock(globals.mutex);
                modcount++;
        } else {
                zap_log(ZAP_LOG_ERROR, "Error initilizing zt.\n");      
@@ -942,8 +1014,11 @@ zap_status_t zap_global_init(void)
                if (!strcasecmp(cfg.category, "openzap")) {
                        if (!strcmp(var, "load")) {
                                zap_software_interface_t *zint;
-               
+
+                               zap_mutex_lock(globals.mutex);
                                zint = (zap_software_interface_t *) hashtable_search(globals.interface_hash, val);
+                               zap_mutex_unlock(globals.mutex);
+
                                if (zint) {
                                        if (zint->configure(zint) == ZAP_SUCCESS) {
                                                configured++;
@@ -967,16 +1042,21 @@ zap_status_t zap_global_init(void)
 
 zap_status_t zap_global_destroy(void)
 {
-
 #ifdef ZAP_ZT_SUPPORT
-       zt_destroy();
+       if (interfaces.zt_interface) {
+               zt_destroy();
+               zap_span_close_all(interfaces.zt_interface);
+       }
 #endif
 #ifdef ZAP_WANPIPE_SUPPORT
-       wanpipe_destroy();
+       if (interfaces.wanpipe_interface) {
+               wanpipe_destroy();
+               zap_span_close_all(interfaces.wanpipe_interface);
+       }
 #endif
 
        hashtable_destroy(globals.interface_hash, 0);
-
+       zap_mutex_destroy(&globals.mutex);
        return ZAP_SUCCESS;
 }
 
index 8b9ae692ba0c54dbb36cdc7182840afcf8320492..8160496c29ccbae794e193d33cd27bef19f93a00 100644 (file)
@@ -16,7 +16,8 @@ int main(int argc, char *argv[])
        printf("OpenZAP loaded\n");
 
  top:
-       if (zap_channel_open_any("wanpipe", 0, ZAP_TOP_DOWN, &chan) == ZAP_SUCCESS) {
+       //if (zap_channel_open_any("wanpipe", 0, ZAP_TOP_DOWN, &chan) == ZAP_SUCCESS) {
+       if (zap_channel_open("wanpipe", 1, 1, &chan) == ZAP_SUCCESS) {
                int x = 0;
                printf("opened channel %d:%d\n", chan->span_id, chan->chan_id);
 
@@ -42,7 +43,7 @@ int main(int argc, char *argv[])
                        zap_size_t len = sizeof(buf);
                        zap_wait_flag_t flags = ZAP_READ;
                        
-                       if (zap_channel_wait(chan, &flags, 0) == ZAP_FAIL) {
+                       if (zap_channel_wait(chan, &flags, -1) == ZAP_FAIL) {
                                printf("wait FAIL! %d [%s]\n", len, chan->last_error);
                        }
                        if (flags & ZAP_READ) {
index 8fc4632fd3b91bdf1aebe97ef12966a7f9f6db6c..34e23bec5c5a3dd7b966890d650e096cc35cdc5b 100644 (file)
@@ -170,15 +170,17 @@ done:
        return status;
 }
 
-zap_status_t zap_mutex_destroy(zap_mutex_t *mutex)
+zap_status_t zap_mutex_destroy(zap_mutex_t **mutex)
 {
+       zap_mutex_t *mp = *mutex;
+       *mutex = NULL;
 #ifdef WIN32
-       DeleteCriticalSection(&mutex->mutex);
+       DeleteCriticalSection(&mp->mutex);
 #else
-       if (pthread_mutex_destroy(&mutex->mutex))
+       if (pthread_mutex_destroy(&mp->mutex))
                return ZAP_FAIL;
 #endif
-       free(mutex);
+       free(mp);
        return ZAP_SUCCESS;
 }
 
index 98325449e9911e4525585c25eaaaa26bfd6c92e7..6386741e1fb59c4a8c54117f6fdfe1be22b80ae9 100644 (file)
@@ -346,14 +346,26 @@ static ZINT_WRITE_FUNCTION(wanpipe_write)
 
 static ZINT_WAIT_FUNCTION(wanpipe_wait)
 {
-       zap_wait_flag_t inflags = *flags;
+       int32_t inflags = 0;
        int result;
-       
-       result = tdmv_api_wait_socket(zchan->sockfd, to, inflags);
+
+       if (*flags & ZAP_READ) {
+               inflags |= POLLIN;
+       }
+
+       if (*flags & ZAP_WRITE) {
+               inflags |= POLLOUT;
+       }
+
+       if (*flags & ZAP_EVENTS) {
+               inflags |= POLLPRI;
+       }
+
+       result = tdmv_api_wait_socket(zchan->sockfd, to, &inflags);
 
        *flags = ZAP_NO_FLAGS;
 
-       if(result < 0){
+       if (result < 0){
                snprintf(zchan->last_error, sizeof(zchan->last_error), "Poll failed");
                return ZAP_FAIL;
        }
@@ -362,16 +374,16 @@ static ZINT_WAIT_FUNCTION(wanpipe_wait)
                return ZAP_TIMEOUT;
        }
 
-       if (result & POLLIN) {
+       if (inflags & POLLIN) {
                *flags |= ZAP_READ;
        }
 
-       if (result & POLLOUT) {
+       if (inflags & POLLOUT) {
                *flags |= ZAP_WRITE;
        }
 
-       if (result & POLLPRI) {
-               *flags |= ZAP_ERROR;
+       if (inflags & POLLPRI) {
+               *flags |= ZAP_EVENTS;
        }
 
        return ZAP_SUCCESS;