提交 68c889ce authored 作者: Moises Silva's avatar Moises Silva

added initial OpenR2 support

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@808 a93c3328-9c30-0410-af19-c9cd2b2d52af
上级 1dda64ab
......@@ -101,7 +101,7 @@ core-install: install-libLTLIBRARIES
#
# tools & test programs
#
noinst_PROGRAMS = testtones detect_tones detect_dtmf testisdn testpri testboost testanalog testapp testcid
noinst_PROGRAMS = testtones detect_tones detect_dtmf testisdn testpri testr2 testboost testanalog testapp testcid
testapp_SOURCES = $(SRC)/testapp.c
testapp_LDADD = libopenzap.la
......@@ -131,6 +131,10 @@ testpri_SOURCES = $(SRC)/testpri.c
testpri_LDADD = libopenzap.la
testpri_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS)
testr2_SOURCES = $(SRC)/testr2.c
testr2_LDADD = libopenzap.la
testr2_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS)
testboost_SOURCES = $(SRC)/testboost.c
testboost_LDADD = libopenzap.la
testboost_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS)
......@@ -152,6 +156,10 @@ if LIBPRI
mod_LTLIBRARIES += ozmod_libpri.la
endif
if OPENR2
mod_LTLIBRARIES += ozmod_r2.la
endif
ozmod_zt_la_SOURCES = $(SRC)/ozmod/ozmod_zt/ozmod_zt.c
ozmod_zt_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS)
ozmod_zt_la_LDFLAGS = -module -avoid-version
......@@ -218,6 +226,13 @@ ozmod_libpri_la_LDFLAGS = -module -avoid-version -lpri
ozmod_libpri_la_LIBADD = $(MYLIB)
endif
if OPENR2
ozmod_r2_la_SOURCES = $(SRC)/ozmod/ozmod_r2/ozmod_r2.c
ozmod_r2_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS)
ozmod_r2_la_LDFLAGS = -module -avoid-version -lopenr2
ozmod_r2_la_LIBADD = $(MYLIB)
endif
dox doxygen:
cd docs && doxygen $(OZ_SRCDIR)/docs/Doxygen.conf
......
......@@ -168,6 +168,9 @@ AM_CONDITIONAL([LIBSANGOMA],[test "${have_libsangoma}" = "yes"])
AM_CONDITIONAL([LIBPRI],[test "${enable_libpri}" = "yes"])
AC_CHECK_LIB([openr2], [openr2_context_set_io_type], [have_openr2="yes"])
AM_CONDITIONAL([OPENR2],[test "${have_openr2}" = "yes"])
COMP_VENDOR_CFLAGS="$COMP_VENDOR_CFLAGS"
AC_SUBST(COMP_VENDOR_CFLAGS)
AC_CONFIG_FILES([Makefile
......
......@@ -280,6 +280,17 @@
} \
} while(0);
#define zap_locked_wait_for_flag_cleared(obj, flag, time) \
do { \
int __safety = time; \
while(__safety-- && zap_test_flag(obj, flag)) { \
zap_sleep(10); \
} \
if(!__safety) { \
zap_log(ZAP_LOG_CRIT, "flag %d was never cleared\n", flag); \
} \
} while(0);
typedef enum {
ZAP_STATE_CHANGE_FAIL,
......@@ -517,7 +528,7 @@ struct zap_channel {
struct zap_span *span;
struct zap_io_interface *zio;
zap_hash_t *variable_hash;
unsigned char cas_bits;
unsigned char rx_cas_bits;
};
......
......@@ -175,7 +175,8 @@ typedef enum {
ZAP_SIGTYPE_RBS,
ZAP_SIGTYPE_ANALOG,
ZAP_SIGTYPE_SS7BOOST,
ZAP_SIGTYPE_M3UA
ZAP_SIGTYPE_M3UA,
ZAP_SIGTYPE_R2
} zap_signal_type_t;
typedef enum {
......@@ -279,6 +280,9 @@ typedef enum {
ZAP_COMMAND_GET_RX_GAIN,
ZAP_COMMAND_SET_TX_GAIN,
ZAP_COMMAND_GET_TX_GAIN,
ZAP_COMMAND_FLUSH_TX_BUFFERS,
ZAP_COMMAND_FLUSH_RX_BUFFERS,
ZAP_COMMAND_FLUSH_BUFFERS,
ZAP_COMMAND_COUNT
} zap_command_t;
......
差异被折叠。
......@@ -202,7 +202,7 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
unsigned configured = 0, x;
if (type == ZAP_CHAN_TYPE_CAS) {
zap_log(ZAP_LOG_DEBUG, "Configuring CAS channels with abcd == 0x%X\n", cas_bits);
zap_log(ZAP_LOG_DEBUG, "Configuring Wanpipe CAS channels with abcd == 0x%X\n", cas_bits);
}
for(x = start; x < end; x++) {
zap_channel_t *chan;
......@@ -210,22 +210,25 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
const char *dtmf = "none";
sockfd = tdmv_api_open_span_chan(spanno, x);
if (sockfd == WP_INVALID_SOCKET) {
zap_log(ZAP_LOG_ERROR, "Failed to open wanpipe device span %d channel %d\n", spanno, x);
continue;
}
if (sockfd != WP_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) {
if (zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) {
wanpipe_tdm_api_t tdm_api;
memset(&tdm_api, 0, sizeof(tdm_api));
#ifdef LIBSANGOMA_VERSION
sangoma_status_t sangstatus;
sangoma_status_t sangstatus;
sangoma_wait_obj_t *sangoma_wait_obj;
sangstatus = sangoma_wait_obj_create(&sangoma_wait_obj, sockfd, SANGOMA_DEVICE_WAIT_OBJ);
if (sangstatus != SANG_STATUS_SUCCESS) {
zap_log(ZAP_LOG_ERROR, "failure create waitable object for s%dc%d\n", spanno, x);
continue;
}
sangstatus = sangoma_wait_obj_create(&sangoma_wait_obj, sockfd, SANGOMA_DEVICE_WAIT_OBJ);
if (sangstatus != SANG_STATUS_SUCCESS) {
zap_log(ZAP_LOG_ERROR, "failure create waitable object for s%dc%d\n", spanno, x);
continue;
}
chan->mod_data = sangoma_wait_obj;
#endif
memset(&tdm_api,0,sizeof(tdm_api));
chan->physical_span_id = spanno;
chan->physical_chan_id = x;
......@@ -237,7 +240,7 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
dtmf = "software";
/* FIXME: Handle Error Condition Check for return code */
err= sangoma_tdm_get_hw_coding(chan->sockfd, &tdm_api);
err = sangoma_tdm_get_hw_coding(chan->sockfd, &tdm_api);
if (tdm_api.wp_tdm_cmd.hw_tdm_coding) {
chan->native_codec = chan->effective_codec = ZAP_CODEC_ALAW;
......@@ -270,15 +273,26 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
if (type == ZAP_CHAN_TYPE_CAS ||
((span->trunk_type == ZAP_TRUNK_T1 || span->trunk_type == ZAP_TRUNK_E1) && type != ZAP_CHAN_TYPE_B)) {
#ifdef LIBSANGOMA_VERSION
sangoma_tdm_write_rbs(chan->sockfd,&tdm_api,chan->physical_chan_id,wanpipe_swap_bits(cas_bits));
sangoma_tdm_write_rbs(chan->sockfd,&tdm_api,chan->physical_chan_id, wanpipe_swap_bits(cas_bits));
/* this should probably be done for old libsangoma but I am not sure if the API is available and I'm lazy to check,
The poll rate is hard coded to 100 per second (done in the driver, is the max rate of polling allowed by wanpipe)
*/
if (sangoma_tdm_enable_rbs_events(chan->sockfd, &tdm_api, 100)) {
zap_log(ZAP_LOG_ERROR, "Failed to enable RBS/CAS events in device %d:%d fd:%d\n", chan->span_id, chan->chan_id, sockfd);
continue;
}
/* probably done by the driver but lets write defensive code this time */
sangoma_flush_bufs(chan->sockfd, &tdm_api);
#else
sangoma_tdm_write_rbs(chan->sockfd,&tdm_api,wanpipe_swap_bits(cas_bits));
sangoma_tdm_write_rbs(chan->sockfd,&tdm_api, wanpipe_swap_bits(cas_bits));
#endif
}
if (!zap_strlen_zero(name)) {
zap_copy_string(chan->chan_name, name, sizeof(chan->chan_name));
}
if (!zap_strlen_zero(number)) {
zap_copy_string(chan->chan_number, number, sizeof(chan->chan_number));
}
......@@ -288,7 +302,7 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
spanno, x, chan->span_id, chan->chan_id, sockfd, dtmf);
} else {
zap_log(ZAP_LOG_ERROR, "failure configuring device s%dc%d\n", spanno, x);
zap_log(ZAP_LOG_ERROR, "zap_span_add_channel failed for wanpipe span %d channel %d\n", spanno, x);
}
}
......@@ -371,15 +385,13 @@ static ZIO_CONFIGURE_SPAN_FUNCTION(wanpipe_configure_span)
}
if (!(sp && ch)) {
zap_log(ZAP_LOG_ERROR, "Invalid input\n");
zap_log(ZAP_LOG_ERROR, "No valid wanpipe span and channel was specified\n");
continue;
}
channo = atoi(ch);
spanno = atoi(sp);
if (channo < 0) {
zap_log(ZAP_LOG_ERROR, "Invalid channel number %d\n", channo);
continue;
......@@ -528,16 +540,24 @@ static ZIO_COMMAND_FUNCTION(wanpipe_command)
case ZAP_COMMAND_SET_CAS_BITS:
{
#ifdef LIBSANGOMA_VERSION
err=sangoma_tdm_write_rbs(zchan->sockfd,&tdm_api,zchan->physical_chan_id,wanpipe_swap_bits(ZAP_COMMAND_OBJ_INT));
err = sangoma_tdm_write_rbs(zchan->sockfd,&tdm_api, zchan->physical_chan_id, wanpipe_swap_bits(ZAP_COMMAND_OBJ_INT));
#else
err=sangoma_tdm_write_rbs(zchan->sockfd,&tdm_api,wanpipe_swap_bits(ZAP_COMMAND_OBJ_INT));
err = sangoma_tdm_write_rbs(zchan->sockfd, &tdm_api, wanpipe_swap_bits(ZAP_COMMAND_OBJ_INT));
#endif
}
break;
case ZAP_COMMAND_GET_CAS_BITS:
{
/* wanpipe does not has a command to get the CAS bits so we emulate it */
ZAP_COMMAND_OBJ_INT = zchan->cas_bits;
#ifdef LIBSANGOMA_VERSION
unsigned char rbsbits;
err = sangoma_tdm_read_rbs(zchan->sockfd, &tdm_api, zchan->physical_chan_id, &rbsbits);
if (!err) {
ZAP_COMMAND_OBJ_INT = wanpipe_swap_bits(rbsbits);
}
#else
// does sangoma_tdm_read_rbs is available here?
ZAP_COMMAND_OBJ_INT = zchan->rx_cas_bits;
#endif
}
break;
default:
......@@ -817,7 +837,6 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
{
uint32_t i,err;
zap_oob_event_t event_id;
for(i = 1; i <= span->chan_count; i++) {
if (span->channels[i]->last_event_time && !zap_test_flag(span->channels[i], ZAP_CHANNEL_EVENT)) {
uint32_t diff = (uint32_t)(zap_current_time_in_ms() - span->channels[i]->last_event_time);
......@@ -856,7 +875,7 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
memset(&tdm_api, 0, sizeof(tdm_api));
zap_clear_flag(span->channels[i], ZAP_CHANNEL_EVENT);
err=sangoma_tdm_read_event(zchan->sockfd,&tdm_api);
err = sangoma_tdm_read_event(zchan->sockfd, &tdm_api);
if (err != ZAP_SUCCESS) {
snprintf(span->last_error, sizeof(span->last_error), "%s", strerror(errno));
return ZAP_FAIL;
......@@ -926,9 +945,7 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
case WP_TDMAPI_EVENT_RBS:
{
event_id = ZAP_OOB_CAS_BITS_CHANGE;
/* save the CAS bits, user should retrieve it with ZAP_COMMAND_GET_CAS_BITS
is there a best play to store this? instead of adding cas_bits member to zap_chan? */
span->channels[i]->cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
span->channels[i]->rx_cas_bits = wanpipe_swap_bits(tdm_api.wp_tdm_cmd.event.wp_tdm_api_event_rbs_bits);
}
break;
case WP_TDMAPI_EVENT_DTMF:
......
......@@ -442,7 +442,7 @@ static ZIO_CONFIGURE_SPAN_FUNCTION(zt_configure_span)
{
int items, i;
char *mydata, *item_list[10];
char *mydata, *item_list[10];
char *ch, *mx;
unsigned char cas_bits = 0;
int channo;
......@@ -777,10 +777,9 @@ static ZIO_COMMAND_FUNCTION(zt_command)
zchan->packet_len = len;
zchan->effective_interval = zchan->native_interval = zchan->packet_len / 8;
if (zchan->effective_codec == ZAP_CODEC_SLIN) {
zchan->packet_len *= 2;
}
if (zchan->effective_codec == ZAP_CODEC_SLIN) {
zchan->packet_len *= 2;
}
}
}
break;
......@@ -792,21 +791,42 @@ static ZIO_COMMAND_FUNCTION(zt_command)
break;
case ZAP_COMMAND_GET_CAS_BITS:
{
/* probably we should call ZT_GETRXBITS instead? */
ZAP_COMMAND_OBJ_INT = zchan->cas_bits;
err = ioctl(zchan->sockfd, codes.GETRXBITS, &zchan->rx_cas_bits);
if (!err) {
ZAP_COMMAND_OBJ_INT = zchan->rx_cas_bits;
}
}
break;
case ZAP_COMMAND_FLUSH_TX_BUFFERS:
{
int flushmode = ZT_FLUSH_WRITE;
err = ioctl(zchan->sockfd, codes.FLUSH, &flushmode);
}
break;
case ZAP_COMMAND_FLUSH_RX_BUFFERS:
{
int flushmode = ZT_FLUSH_READ;
err = ioctl(zchan->sockfd, codes.FLUSH, &flushmode);
}
break;
case ZAP_COMMAND_FLUSH_BUFFERS:
{
int flushmode = ZT_FLUSH_BOTH;
err = ioctl(zchan->sockfd, codes.FLUSH, &flushmode);
}
break;
default:
err = ZAP_NOTIMPL;
break;
};
if (err) {
if (err && err != ZAP_NOTIMPL) {
snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
return ZAP_FAIL;
}
return ZAP_SUCCESS;
return err == 0 ? ZAP_SUCCESS : err;
}
/**
......@@ -1019,7 +1039,7 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
if (err) {
return ZAP_FAIL;
}
span->channels[i]->cas_bits = bits;
span->channels[i]->rx_cas_bits = bits;
}
break;
default:
......
#include "openzap.h"
#include <signal.h>
static int R = 0;
static zap_mutex_t *mutex = NULL;
static ZIO_SIGNAL_CB_FUNCTION(on_r2_signal)
{
zap_log(ZAP_LOG_DEBUG, "Got R2 channel sig [%s] in channel\n", zap_signal_event2str(sigmsg->event_id), sigmsg->channel->physical_chan_id);
return ZAP_SUCCESS;
}
static void handle_SIGINT(int sig)
{
zap_mutex_lock(mutex);
R = 0;
zap_mutex_unlock(mutex);
return;
}
int main(int argc, char *argv[])
{
zap_span_t *span;
zap_mutex_create(&mutex);
zap_global_set_default_logger(ZAP_LOG_LEVEL_DEBUG);
if (argc < 2) {
printf("umm no\n");
exit(-1);
}
if (zap_global_init() != ZAP_SUCCESS) {
fprintf(stderr, "Error loading OpenZAP\n");
exit(-1);
}
printf("OpenZAP loaded\n");
if (zap_span_find(atoi(argv[1]), &span) != ZAP_SUCCESS) {
fprintf(stderr, "Error finding OpenZAP span\n");
goto done;
}
if (zap_configure_span("r2", span, on_r2_signal,
"variant", "mx",
"max_ani", 10,
"max_dnis", 4,
"logging", "all",
TAG_END) == ZAP_SUCCESS) {
zap_span_start(span);
} else {
fprintf(stderr, "Error starting R2 span\n");
goto done;
}
signal(SIGINT, handle_SIGINT);
zap_mutex_lock(mutex);
R = 1;
zap_mutex_unlock(mutex);
while(R) {
zap_sleep(1 * 1000);
}
done:
zap_global_destroy();
return 1;
}
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
*/
......@@ -216,14 +216,14 @@ OZ_DECLARE (int) zap_config_get_cas_bits(char *strvalue, unsigned char *outbits)
int x = 0;
char *double_colon = strchr(strvalue, ':');
if (!double_colon) {
zap_log(ZAP_LOG_ERROR, "No CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", double_colon);
zap_log(ZAP_LOG_ERROR, "No CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", strvalue);
return -1;
}
double_colon++;
*outbits = 0;
cas_bits[4] = 0;
if (sscanf(double_colon, "%c%c%c%c", &cas_bits[0], &cas_bits[1], &cas_bits[2], &cas_bits[3]) != 4) {
zap_log(ZAP_LOG_ERROR, "Invalid CAS bits specified: %s, :xxxx definition expected, where x is 1 or 0\n", double_colon);
zap_log(ZAP_LOG_ERROR, "Invalid CAS bits specified: '%s', :xxxx definition expected, where x is 1 or 0\n", double_colon);
return -1;
}
zap_log(ZAP_LOG_DEBUG, "CAS bits specification found: %s\n", cas_bits);
......
......@@ -1522,14 +1522,17 @@ OZ_DECLARE(zap_status_t) zap_channel_command(zap_channel_t *zchan, zap_command_t
if (!zchan->zio->command) {
snprintf(zchan->last_error, sizeof(zchan->last_error), "method not implemented");
zap_log(ZAP_LOG_ERROR, "no commnand functon!\n");
zap_log(ZAP_LOG_ERROR, "no command function defined by the I/O openzap module!\n");
GOTO_STATUS(done, ZAP_FAIL);
}
status = zchan->zio->command(zchan, command, obj);
done:
if (status == ZAP_NOTIMPL) {
snprintf(zchan->last_error, sizeof(zchan->last_error), "I/O command %d not implemented in backend", command);
zap_log(ZAP_LOG_ERROR, "I/O backend does not support command %d!\n", command);
}
done:
zap_mutex_unlock(zchan->mutex);
return status;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论