update
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@62 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
parent
e5fb4a3cc0
commit
5013baf37a
|
@ -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 $@
|
||||
|
|
|
@ -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 ------------------------------------------------------------*/
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue