$(CC) $(INCS) -L. $(SRC)/testtones.c -o testtones -lopenzap -lm -lpthread
testisdn: $(SRC)/testisdn.c $(MYLIB)
- $(CC) $(INCS) -L. $(SRC)/testisdn.c -o testisdn -lopenzap -lm -lpthread
+ $(CC) $(INCS) $(ZAP_CFLAGS) -L. $(SRC)/testisdn.c -o testisdn -lopenzap -lm -lpthread
testanalog: $(SRC)/testanalog.c $(MYLIB)
$(CC) $(INCS) -L. $(SRC)/testanalog.c -o testanalog -lopenzap -lm -lpthread
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
-INPUT = .. ../include ../isdn ../isdn/include
+INPUT = ../src ../src/include ../src/isdn ../src/isdn/include
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
#define zap_test_flag(obj, flag) ((obj)->flags & flag)
#define zap_test_pflag(obj, flag) ((obj)->pflags & flag)
+
+#define zap_set_alarm_flag(obj, flag) (obj)->alarm_flags |= (flag)
+#define zap_clear_alarm_flag(obj, flag) (obj)->alarm_flags &= ~(flag)
+#define zap_test_alarm_flag(obj, flag) ((obj)->alarm_flags & flag)
+
/*!
\brief Set a flag on an arbitrary object
\command obj the object to set the flags on
zap_socket_t sockfd;
zap_channel_flag_t flags;
uint32_t pflags;
+ zap_alarm_flag_t alarm_flags;
zap_channel_feature_t features;
zap_codec_t effective_codec;
zap_codec_t native_codec;
zio_configure_t configure;
zio_open_t open;
zio_close_t close;
- zio_destroy_channel_t destroy_channel;
+ zio_channel_destroy_t channel_destroy;
+ zio_get_alarms_t get_alarms;
zio_command_t command;
zio_wait_t wait;
zio_read_t read;
void zap_channel_rotate_tokens(zap_channel_t *zchan);
void zap_channel_clear_detected_tones(zap_channel_t *zchan);
void zap_channel_clear_needed_tones(zap_channel_t *zchan);
+zap_status_t zap_channel_get_alarms(zap_channel_t *zchan);
zap_status_t zap_channel_send_fsk_data(zap_channel_t *zchan, zap_fsk_data_state_t *fsk_data, float db_level);
zap_status_t zap_channel_clear_token(zap_channel_t *zchan, const char *token);
zap_status_t zap_channel_add_token(zap_channel_t *zchan, char *token, int end);
ZAP_OOB_FLASH,
ZAP_OOB_RING_START,
ZAP_OOB_RING_STOP,
+ ZAP_OOB_ALARM_TRAP,
+ ZAP_OOB_ALARM_CLEAR,
ZAP_OOB_NOOP,
ZAP_OOB_INVALID
} zap_oob_event_t;
-#define OOB_STRINGS "DTMF", "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "NOOP", "INVALID"
+#define OOB_STRINGS "DTMF", "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "ALARM_TRAP", "ALARM_CLEAR", "NOOP", "INVALID"
ZAP_STR2ENUM_P(zap_str2zap_oob_event, zap_oob_event2str, zap_oob_event_t)
+typedef enum {
+ ZAP_ALARM_NONE = 0,
+ ZAP_ALARM_RECOVER = (1 << 0),
+ ZAP_ALARM_LOOPBACK = (1 << 2),
+ ZAP_ALARM_YELLOW = (1 << 3),
+ ZAP_ALARM_RED = (1 << 4),
+ ZAP_ALARM_BLUE = (1 << 5),
+ ZAP_ALARM_NOTOPEN = ( 1 << 6)
+} zap_alarm_flag_t;
+
typedef enum {
ZAP_SIGTYPE_NONE,
ZAP_SIGTYPE_ISDN,
ZAP_SIGEVENT_PROGRESS_MEDIA,
ZAP_SIGEVENT_NOTIFY,
ZAP_SIGEVENT_TONE_DETECTED,
+ ZAP_SIGEVENT_ALARM_TRAP,
+ ZAP_SIGEVENT_ALARM_CLEAR,
ZAP_SIGEVENT_MISC,
ZAP_SIGEVENT_INVALID
} zap_signal_event_t;
-#define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "FLASH", "PROGRESS", "PROGRESS_MEDIA", "NOTIFY", "TONE_DETECTED", "MISC", "INVALID"
+#define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "FLASH", "PROGRESS", \
+ "PROGRESS_MEDIA", "NOTIFY", "TONE_DETECTED", "ALARM_TRAP", "ALARM_CLEAR", "MISC", "INVALID"
ZAP_STR2ENUM_P(zap_str2zap_signal_event, zap_signal_event2str, zap_signal_event_t)
typedef enum {
#define ZIO_CONFIGURE_ARGS (const char *category, const char *var, const char *val, int lineno)
#define ZIO_OPEN_ARGS (zap_channel_t *zchan)
#define ZIO_CLOSE_ARGS (zap_channel_t *zchan)
-#define ZIO_DESTROY_CHANNEL_ARGS (zap_channel_t *zchan)
+#define ZIO_CHANNEL_DESTROY_ARGS (zap_channel_t *zchan)
#define ZIO_COMMAND_ARGS (zap_channel_t *zchan, zap_command_t command, void *obj)
#define ZIO_WAIT_ARGS (zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to)
+#define ZIO_GET_ALARMS_ARGS (zap_channel_t *zchan)
#define ZIO_READ_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen)
#define ZIO_WRITE_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen)
typedef zap_status_t (*zio_configure_t) ZIO_CONFIGURE_ARGS ;
typedef zap_status_t (*zio_open_t) ZIO_OPEN_ARGS ;
typedef zap_status_t (*zio_close_t) ZIO_CLOSE_ARGS ;
-typedef zap_status_t (*zio_destroy_channel_t) ZIO_DESTROY_CHANNEL_ARGS ;
+typedef zap_status_t (*zio_channel_destroy_t) ZIO_CHANNEL_DESTROY_ARGS ;
+typedef zap_status_t (*zio_get_alarms_t) ZIO_GET_ALARMS_ARGS ;
typedef zap_status_t (*zio_command_t) ZIO_COMMAND_ARGS ;
typedef zap_status_t (*zio_wait_t) ZIO_WAIT_ARGS ;
typedef zap_status_t (*zio_read_t) ZIO_READ_ARGS ;
#define ZIO_CONFIGURE_FUNCTION(name) zap_status_t name ZIO_CONFIGURE_ARGS
#define ZIO_OPEN_FUNCTION(name) zap_status_t name ZIO_OPEN_ARGS
#define ZIO_CLOSE_FUNCTION(name) zap_status_t name ZIO_CLOSE_ARGS
-#define ZIO_DESTROY_CHANNEL_FUNCTION(name) zap_status_t name ZIO_DESTROY_CHANNEL_ARGS
+#define ZIO_CHANNEL_DESTROY_FUNCTION(name) zap_status_t name ZIO_CHANNEL_DESTROY_ARGS
+#define ZIO_GET_ALARMS_FUNCTION(name) zap_status_t name ZIO_GET_ALARMS_ARGS
#define ZIO_COMMAND_FUNCTION(name) zap_status_t name ZIO_COMMAND_ARGS
#define ZIO_WAIT_FUNCTION(name) zap_status_t name ZIO_WAIT_ARGS
#define ZIO_READ_FUNCTION(name) zap_status_t name ZIO_READ_ARGS
int main(int argc, char *argv[])
{
zap_span_t *span;
-
+
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(1, &span) != ZAP_SUCCESS) {
+ if (zap_span_find(atoi(argv[1]), &span) != ZAP_SUCCESS) {
fprintf(stderr, "Error finding OpenZAP span\n");
goto done;
}
return NULL;
}
-static zap_status_t process_event(zap_span_t *span, zap_event_t *event)
+static __inline__ zap_status_t process_event(zap_span_t *span, zap_event_t *event)
{
zap_sigmsg_t sig;
zap_analog_data_t *data = event->channel->span->analog_data;
{
zap_event_t *event;
while (zap_span_next_event(span, &event) == ZAP_SUCCESS) {
- if (event->e_type == ZAP_OOB_NOOP) {
+ if (event->enum_id == ZAP_OOB_NOOP) {
continue;
}
if (process_event(span, event) != ZAP_SUCCESS) {
}
-static zap_status_t zap_destroy_channel(zap_channel_t *zchan)
+static zap_status_t zap_channel_destroy(zap_channel_t *zchan)
{
if (zap_test_flag(zchan, ZAP_CHANNEL_CONFIGURED)) {
}
- if (zchan->span->zio->destroy_channel) {
+ if (zchan->span->zio->channel_destroy) {
zap_log(ZAP_LOG_INFO, "Closing channel %u:%u fd:%d\n", zchan->span_id, zchan->chan_id, zchan->sockfd);
- if (zchan->span->zio->destroy_channel(zchan) == ZAP_SUCCESS) {
+ if (zchan->span->zio->channel_destroy(zchan) == ZAP_SUCCESS) {
zap_clear_flag_locked(zchan, ZAP_CHANNEL_CONFIGURED);
} else {
zap_log(ZAP_LOG_ERROR, "Error Closing channel %u:%u fd:%d\n", zchan->span_id, zchan->chan_id, zchan->sockfd);
return ZAP_SUCCESS;
}
+
+
+zap_status_t zap_channel_get_alarms(zap_channel_t *zchan)
+{
+ zap_status_t status = ZAP_FAIL;
+
+ if (zap_test_flag(zchan, ZAP_CHANNEL_CONFIGURED)) {
+ if (zchan->span->zio->get_alarms) {
+ if ((status = zchan->span->zio->get_alarms(zchan)) == ZAP_SUCCESS) {
+ *zchan->last_error = '\0';
+ if (zap_test_alarm_flag(zchan, ZAP_ALARM_RED)) {
+ snprintf(zchan->last_error + strlen(zchan->last_error), sizeof(zchan->last_error) - strlen(zchan->last_error), "RED/");
+ }
+ if (zap_test_alarm_flag(zchan, ZAP_ALARM_YELLOW)) {
+ snprintf(zchan->last_error + strlen(zchan->last_error), sizeof(zchan->last_error) - strlen(zchan->last_error), "YELLOW/");
+ }
+ if (zap_test_alarm_flag(zchan, ZAP_ALARM_BLUE)) {
+ snprintf(zchan->last_error + strlen(zchan->last_error), sizeof(zchan->last_error) - strlen(zchan->last_error), "BLUE/");
+ }
+ if (zap_test_alarm_flag(zchan, ZAP_ALARM_LOOPBACK)) {
+ snprintf(zchan->last_error + strlen(zchan->last_error), sizeof(zchan->last_error) - strlen(zchan->last_error), "LOOP/");
+ }
+ if (zap_test_alarm_flag(zchan, ZAP_ALARM_RECOVER)) {
+ snprintf(zchan->last_error + strlen(zchan->last_error), sizeof(zchan->last_error) - strlen(zchan->last_error), "RECOVER/");
+ }
+ *(zchan->last_error + strlen(zchan->last_error) - 1) = '\0';
+
+ }
+ } else {
+ status = ZAP_NOTIMPL;
+ }
+ }
+
+ return status;
+}
+
zap_status_t zap_span_create(zap_io_interface_t *zio, zap_span_t **span)
{
zap_span_t *new_span = NULL;
span = &globals.spans[i];
for(j = 0; j < span->chan_count; j++) {
- zap_destroy_channel(&span->channels[i]);
+ zap_channel_destroy(&span->channels[i]);
}
if (span->mutex) {
for(j = 1; j <= cur_span->chan_count; j++) {
zap_channel_t *cur_chan = &cur_span->channels[j];
if (zap_test_flag(cur_chan, ZAP_CHANNEL_CONFIGURED)) {
- zap_destroy_channel(cur_chan);
+ zap_channel_destroy(cur_chan);
}
}
zap_mutex_unlock(cur_span->mutex);
static L2ULONG zap_time_now()
{
-#ifdef WIN32
- return timeGetTime();
-#else
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
-#endif
+ return zap_current_time_in_ms();
}
static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(isdn_outgoing_call)
static int zap_isdn_921_23(void *pvt, L2UCHAR *msg, L2INT mlen)
{
int ret;
- //char bb[4096] = "";
- //print_hex_bytes(msg+4, mlen-2, bb, sizeof(bb));
- //zap_log(ZAP_LOG_DEBUG, "READ %d\n%s\n%s\n\n", (int)mlen-2, LINE, bb);
+ char bb[4096] = "";
+ print_hex_bytes(msg+4, mlen-2, bb, sizeof(bb));
+ zap_log(ZAP_LOG_DEBUG, "READ %d\n%s\n%s\n\n", (int)mlen-2, LINE, bb);
ret = Q931Rx23(pvt, msg, mlen);
if (ret != 0)
}
}
+static __inline__ zap_status_t process_event(zap_span_t *span, zap_event_t *event)
+{
+ zap_sigmsg_t sig;
+ zap_isdn_data_t *data = span->isdn_data;
+
+ memset(&sig, 0, sizeof(sig));
+ sig.chan_id = event->channel->chan_id;
+ sig.span_id = event->channel->span_id;
+ sig.channel = event->channel;
+
+ zap_log(ZAP_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n",
+ zap_oob_event2str(event->enum_id), event->channel->span_id, event->channel->chan_id, zap_channel_state2str(event->channel->state));
+
+ switch(event->enum_id) {
+ case ZAP_OOB_ALARM_TRAP:
+ {
+ sig.event_id = ZAP_OOB_ALARM_TRAP;
+ if (event->channel->state != ZAP_CHANNEL_STATE_DOWN) {
+ zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_TERMINATING);
+ }
+ zap_set_flag(event->channel, ZAP_CHANNEL_SUSPENDED);
+ zap_channel_get_alarms(event->channel);
+ data->sig_cb(&sig);
+ zap_log(ZAP_LOG_WARNING, "channel %d:%d (%d:%d) has alarms [%s]\n",
+ event->channel->span_id, event->channel->chan_id,
+ event->channel->physical_span_id, event->channel->physical_chan_id,
+ event->channel->last_error);
+ }
+ break;
+ case ZAP_OOB_ALARM_CLEAR:
+ {
+ sig.event_id = ZAP_OOB_ALARM_CLEAR;
+ zap_clear_flag(event->channel, ZAP_CHANNEL_SUSPENDED);
+ zap_channel_get_alarms(event->channel);
+ data->sig_cb(&sig);
+ }
+ break;
+ }
+
+ return ZAP_SUCCESS;
+}
+
+
+static __inline__ void check_events(zap_span_t *span)
+{
+ zap_status_t status;
+
+ status = zap_span_poll_event(span, 5);
+
+ switch(status) {
+ case ZAP_SUCCESS:
+ {
+ zap_event_t *event;
+ while (zap_span_next_event(span, &event) == ZAP_SUCCESS) {
+ if (event->enum_id == ZAP_OOB_NOOP) {
+ continue;
+ }
+ if (process_event(span, event) != ZAP_SUCCESS) {
+ break;
+ }
+ }
+ }
+ break;
+ case ZAP_FAIL:
+ {
+ zap_log(ZAP_LOG_DEBUG, "Event Failure!\n");
+ }
+ break;
+ default:
+ break;
+ }
+}
+
static void *zap_isdn_run(zap_thread_t *me, void *obj)
{
zap_span_t *span = (zap_span_t *) obj;
Q921TimerTick(&data->q921);
check_state(span);
-
+ check_events(span);
+
switch(status) {
case ZAP_FAIL:
{
}
-static ZIO_DESTROY_CHANNEL_FUNCTION(wanpipe_destroy_channel)
+static ZIO_CHANNEL_DESTROY_FUNCTION(wanpipe_channel_destroy)
{
if (zchan->sockfd > -1) {
close(zchan->sockfd);
wanpipe_interface.poll_event = wanpipe_poll_event;
#endif
wanpipe_interface.next_event = wanpipe_next_event;
- wanpipe_interface.destroy_channel = wanpipe_destroy_channel;
+ wanpipe_interface.channel_destroy = wanpipe_channel_destroy;
*zio = &wanpipe_interface;
return ZAP_SUCCESS;
} zt_globals;
#define ZT_INVALID_SOCKET -1
+static const char ctlpath[] = "/dev/zap/ctl";
+static zap_socket_t CONTROL_FD = ZT_INVALID_SOCKET;
static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, zap_chan_type_t type, char *name, char *number)
{
unsigned configured = 0, x;
- const char ctlpath[] = "/dev/zap/ctl";
char path[] = "/dev/zap/channel";
zt_params_t ztp;
- zap_socket_t ctlfd = ZT_INVALID_SOCKET;
-
- if ((ctlfd = open(ctlpath, O_RDWR)) < 0) {
- zap_log(ZAP_LOG_ERROR, "Cannot open control device\n");
- return 0;
- }
memset(&ztp, 0, sizeof(ztp));
if (sockfd != ZT_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &zchan) == ZAP_SUCCESS) {
if (ioctl(sockfd, ZT_SPECIFY, &x)) {
- zap_log(ZAP_LOG_ERROR, "failure configuring device %s chan %d fd %d (%s)\n", path, x, ctlfd, strerror(errno));
+ zap_log(ZAP_LOG_ERROR, "failure configuring device %s chan %d fd %d (%s)\n", path, x, sockfd, strerror(errno));
close(sockfd);
continue;
}
default:
break;
}
- if (ioctl(ctlfd, ZT_CHANCONFIG, &cc)) {
+ if (ioctl(CONTROL_FD, ZT_CHANCONFIG, &cc)) {
zap_log(ZAP_LOG_ERROR, "failure configuring device %s chan %d fd %d (%s)\n",
- path, x, ctlfd, strerror(errno));
+ path, x, CONTROL_FD, strerror(errno));
close(sockfd);
break;
}
}
}
- close(ctlfd);
+
return configured;
}
return ZAP_SUCCESS;
}
+static ZIO_GET_ALARMS_FUNCTION(zt_get_alarms)
+{
+ struct zt_spaninfo info;
+
+ memset(&info, 0, sizeof(info));
+ info.span_no = zchan->physical_span_id;
+
+ if (ioctl(CONTROL_FD, ZT_SPANSTAT, &info)) {
+ snprintf(zchan->last_error, sizeof(zchan->last_error), "ioctl failed (%s)", strerror(errno));
+ snprintf(zchan->span->last_error, sizeof(zchan->span->last_error), "ioctl failed (%s)", strerror(errno));
+ return ZAP_FAIL;
+ }
+
+ zchan->alarm_flags = info.alarms;
+
+ return ZAP_SUCCESS;
+}
+
+
static ZIO_WAIT_FUNCTION(zt_wait)
{
int32_t inflags = 0;
}
if (result > 0) {
- *flags = pfds[0].revents;
+ inflags = pfds[0].revents;
}
-
*flags = ZAP_NO_FLAGS;
if (result < 0){
}
}
break;
+ case ZT_EVENT_ALARM:
+ {
+ event_id = ZAP_OOB_ALARM_TRAP;
+ }
+ break;
+ case ZT_EVENT_NOALARM:
+ {
+ event_id = ZAP_OOB_ALARM_CLEAR;
+ }
+ break;
default:
{
zap_log(ZAP_LOG_WARNING, "Unhandled event %d\n", zt_event_id);
return ZAP_FAIL;
}
-static ZIO_DESTROY_CHANNEL_FUNCTION(zt_destroy_channel)
+static ZIO_CHANNEL_DESTROY_FUNCTION(zt_channel_destroy)
{
close(zchan->sockfd);
zchan->sockfd = ZT_INVALID_SOCKET;
memset(&zt_interface, 0, sizeof(zt_interface));
memset(&zt_globals, 0, sizeof(zt_globals));
+ if ((CONTROL_FD = open(ctlpath, O_RDWR)) < 0) {
+ zap_log(ZAP_LOG_ERROR, "Cannot open control device\n");
+ return 0;
+ }
+
zt_globals.codec_ms = 20;
zt_globals.wink_ms = 150;
zt_globals.flash_ms = 750;
zt_interface.write = zt_write;
zt_interface.poll_event = zt_poll_event;
zt_interface.next_event = zt_next_event;
- zt_interface.destroy_channel = zt_destroy_channel;
-
+ zt_interface.channel_destroy = zt_channel_destroy;
+ zt_interface.get_alarms = zt_get_alarms;
*zio = &zt_interface;
return ZAP_SUCCESS;
zap_status_t zt_destroy(void)
{
-
+ close(CONTROL_FD);
memset(&zt_interface, 0, sizeof(zt_interface));
return ZAP_SUCCESS;
}