git-svn-id: http://svn.openzap.org/svn/openzap/trunk@62 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
Anthony Minessale 2007-05-21 17:48:13 +00:00
parent 491d7a2fe4
commit 5724bd4d6a
10 changed files with 297 additions and 106 deletions

View 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 $@

92
libs/openzap/src/g711.c Normal file
View File

@ -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 ------------------------------------------------------------*/

View 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);

View 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 (pfds[0].revents & POLLERR) {
res = -1;
}
if (res < 0) {
return -1;
if (res > 0) {
*flags = pfds[0].revents;
}
if ((pfds[0].revents & POLLERR)) {
return -1;
}
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;

View 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);

View 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)

View 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;
}

View 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) {

View 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;
}

View 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;