static void *dchan(void *data)
{
	/* Joint D-channel */
	struct pri *pri = data;
	struct timeval *next, tv;
	pri_event *e;
	fd_set fds;
	int res;
	for(;;) {
		if ((next = pri_schedule_next(pri))) {
			gettimeofday(&tv, NULL);
			tv.tv_sec = next->tv_sec - tv.tv_sec;
			tv.tv_usec = next->tv_usec - tv.tv_usec;
			if (tv.tv_usec < 0) {
				tv.tv_usec += 1000000;
				tv.tv_sec -= 1;
			}
			if (tv.tv_sec < 0) {
				tv.tv_sec = 0;
				tv.tv_usec = 0;
			}
		}
		FD_ZERO(&fds);
		FD_SET(pri_fd(pri), &fds);
		res = select(pri_fd(pri) + 1, &fds, NULL, NULL, next ? &tv : NULL);
		pthread_mutex_lock(&lock);
		cur = pri;
		if (res < 0) {
			perror("select");
		} else if (!res) {
			e = pri_schedule_run(pri);
		} else {
			e = pri_check_event(pri);
		}
		if (e) {
			if (first == pri) {
				event1(pri, e);
			} else {
				event2(pri, e);
			}
		}
		pthread_mutex_unlock(&lock);
	}
	return NULL;
}
Exemplo n.º 2
0
pri_event *pri_dchannel_run(struct pri *pri, int block)
{
	pri_event *e;
	int res;
	if (!pri)
		return NULL;
	if (block) {
		do {
			e =  NULL;
			res = wait_pri(pri);
			/* Check for error / interruption */
			if (res < 0)
				return NULL;
			if (!res)
				e = pri_schedule_run(pri);
			else
				e = pri_check_event(pri);
		} while(!e);
	} else {
		e = pri_check_event(pri);
		return e;
	}
	return e;
}
Exemplo n.º 3
0
int lpwrap_one_loop(struct lpwrap_pri *spri)
{
	fd_set rfds, efds;
	struct timeval now = {0,0}, *next;
	pri_event *event;
	event_handler handler;
    int sel;
	
	if (spri->on_loop) {
		if ((sel = spri->on_loop(spri)) < 0) {
			return sel;
		}
	}

	if (spri->errs >= 2) {
		spri->errs = 0;
		return -1;
	}

	FD_ZERO(&rfds);
	FD_ZERO(&efds);

#ifdef _MSC_VER
	//Windows macro for FD_SET includes a warning C4127: conditional expression is constant
#pragma warning(push)
#pragma warning(disable:4127)
#endif

	FD_SET(pri_fd(spri->pri), &rfds);
	FD_SET(pri_fd(spri->pri), &efds);

#ifdef _MSC_VER
#pragma warning(pop)
#endif

	now.tv_sec = 0;
	now.tv_usec = 100000;

	sel = select(pri_fd(spri->pri) + 1, &rfds, NULL, &efds, &now);

	event = NULL;

	if (!sel) {
		if ((next = pri_schedule_next(spri->pri))) {
			gettimeofday(&now, NULL);
			if (now.tv_sec >= next->tv_sec && (now.tv_usec >= next->tv_usec || next->tv_usec <= 100000)) {
				//zap_log(ZAP_LOG_DEBUG, "Check event\n");
				event = pri_schedule_run(spri->pri);
			}
		}
	} else if (sel > 0) {
		event = pri_check_event(spri->pri);
	}

	if (event) {
		/* 0 is catchall event handler */
		if ((handler = spri->eventmap[event->e] ? spri->eventmap[event->e] : spri->eventmap[0] ? spri->eventmap[0] : NULL)) {
			handler(spri, event->e, event);
		} else {
			zap_log(ZAP_LOG_CRIT, "No event handler found for event %d.\n", event->e);
		}
	}


	return sel;


	if ((handler = spri->eventmap[LPWRAP_PRI_EVENT_IO_FAIL] ? spri->eventmap[LPWRAP_PRI_EVENT_IO_FAIL] : spri->eventmap[0] ? spri->eventmap[0] : NULL)) {
		handler(spri, LPWRAP_PRI_EVENT_IO_FAIL, NULL);
	}

	return -1;
}
Exemplo n.º 4
0
int sangoma_one_loop(struct sangoma_pri *spri)
{
	fd_set rfds, efds;
	struct timeval now = {0,0}, *next;
	pri_event *event;
    int sel;
	
	if (spri->on_loop) {
		spri->on_loop(spri);
	}

	FD_ZERO(&rfds);
	FD_ZERO(&efds);

#ifdef _MSC_VER
	//Windows macro for FD_SET includes a warning C4127: conditional expression is constant
#pragma warning(push)
#pragma warning(disable:4127)
#endif

	FD_SET(spri->pri->fd, &rfds);
	FD_SET(spri->pri->fd, &efds);

#ifdef _MSC_VER
#pragma warning(pop)
#endif

	if ((next = pri_schedule_next(spri->pri))) {
		gettimeofday(&now, NULL);
		now.tv_sec = next->tv_sec - now.tv_sec;
		now.tv_usec = next->tv_usec - now.tv_usec;
		if (now.tv_usec < 0) {
			now.tv_usec += 1000000;
			now.tv_sec -= 1;
		}
		if (now.tv_sec < 0) {
			now.tv_sec = 0;
			now.tv_usec = 0;
		}
	}

	sel = select(spri->pri->fd + 1, &rfds, NULL, &efds, next ? &now : NULL);
	event = NULL;

	if (!sel) {
		event = pri_schedule_run(spri->pri);
	} else if (sel > 0) {
		event = pri_check_event(spri->pri);
	}

	if (event) {
		event_handler handler;
		/* 0 is catchall event handler */
		if ((handler = spri->eventmap[event->e] ? spri->eventmap[event->e] : spri->eventmap[0] ? spri->eventmap[0] : NULL)) {
			handler(spri, event->e, event);
		} else {
			fprintf(stderr,"No event handler found for event %d.\n", event->e);
		}
	}

	return sel;
}
Exemplo n.º 5
0
static int run_pri(int dfd, int swtype, int node)
{
	struct pri *pri;
	pri_event *e;
	struct timeval tv = {0,0}, *next;
	fd_set rfds, efds;
	int res,x;

	pri = pri_new_bri(dfd, 1, node, swtype);
	if (!pri) {
		fprintf(stderr, "Unable to create PRI\n");
		return -1;
	}
	pri_set_debug(pri, -1);
	for (;;) {
		
		/* Run the D-Channel */
		FD_ZERO(&rfds);
		FD_ZERO(&efds);
		FD_SET(dfd, &rfds);
		FD_SET(dfd, &efds);

		if ((next = pri_schedule_next(pri))) {
			gettimeofday(&tv, NULL);
			tv.tv_sec = next->tv_sec - tv.tv_sec;
			tv.tv_usec = next->tv_usec - tv.tv_usec;
			if (tv.tv_usec < 0) {
				tv.tv_usec += 1000000;
				tv.tv_sec -= 1;
			}
			if (tv.tv_sec < 0) {
				tv.tv_sec = 0;
				tv.tv_usec = 0;
			}
		}
		res = select(dfd + 1, &rfds, NULL, &efds, next ? &tv : NULL);
		e = NULL;

		if (!res) {
			e = pri_schedule_run(pri);
		} else if (res > 0) {
			e = pri_check_event(pri);
		} else if (errno == ELAST) {
			res = ioctl(dfd, ZT_GETEVENT, &x);
			printf("Got Zaptel event: %d\n", x);
		} else if (errno != EINTR) 
			fprintf(stderr, "Error (%d) on select: %s\n", ELAST, strerror(errno));

		if (e) {
			handle_pri_event(pri, e);
		}

		res = ioctl(dfd, ZT_GETEVENT, &x);

		if (!res && x) {
			fprintf(stderr, "Got event on PRI interface: %d\n", x);
		}

		/* Check for lines that need hangups */
		for (x=0;x<MAX_CHAN;x++)
			if (chans[x].needhangup) {
				chans[x].needhangup = 0;
				pri_release(pri, chans[x].call, PRI_CAUSE_NORMAL_CLEARING);
			}

	}
	return 0;
}
Exemplo n.º 6
0
int sangoma_one_loop(struct sangoma_pri *spri)
{
	fd_set rfds;
	// we dont need efds unless we want to handle span alarms
	// right now sbridge does not makes calls, so there is no point
	// in handling alarms
	//fd_set efds; 
	struct timeval now = {0,0}, *next;
	pri_event *event;
    	int sel;
	
	sbridge_mutex_lock(&spri->lock);
	if (spri->on_loop) {
		spri->on_loop(spri);
	}
	FD_ZERO(&rfds);
	//FD_ZERO(&efds);

#ifdef _MSC_VER
//Windows macro for FD_SET includes a warning C4127: conditional expression is constant
#pragma warning(push)
#pragma warning(disable:4127)
#endif

	FD_SET(pri_fd(spri->pri), &rfds);
	//FD_SET(pri_fd(spri->pri), &efds);

#ifdef _MSC_VER
#pragma warning(pop)
#endif

	if ((next = pri_schedule_next(spri->pri))) {
		gettimeofday(&now, NULL);
		now.tv_sec = next->tv_sec - now.tv_sec;
		now.tv_usec = next->tv_usec - now.tv_usec;
		if (now.tv_usec < 0) {
			now.tv_usec += 1000000;
			now.tv_sec -= 1;
		}
		if (now.tv_sec < 0) {
			now.tv_sec = 0;
			now.tv_usec = 0;
		}
	}
	sbridge_mutex_unlock(&spri->lock);
	//sel = select(pri_fd(spri->pri) + 1, &rfds, NULL, &efds, next ? &now : NULL);
	sel = select(pri_fd(spri->pri) + 1, &rfds, NULL, NULL, next ? &now : NULL);
	sbridge_mutex_lock(&spri->lock);
	event = NULL;

	if (!sel) {
		event = pri_schedule_run(spri->pri);
	} else if (sel > 0) {
		event = pri_check_event(spri->pri);
	} else if (errno != EINTR){
		sbridge_log(SBRIDGE_LOG_ERROR, "select failed: %s\n", sbridge_os_get_last_error());
	} else {
		/* at this point we know there is a select error and is EINTR, ignore */
		sel = 0;
	}

	if (event) {
		event_handler handler;
		/* 0 is catchall event handler */
		const int eventmap_size = sizeof(spri->eventmap)/sizeof(spri->eventmap[0]);
		if (eventmap_size <= event->e) {
			sbridge_log(SBRIDGE_LOG_ERROR, "Event %d is too big, we did not expect it!.\n", event->e);
		} else {
			if ((handler = spri->eventmap[event->e] ? spri->eventmap[event->e] : spri->eventmap[0] ? spri->eventmap[0] : NULL)) {
				handler(spri, event->e, event);
			} else {
				sbridge_log(SBRIDGE_LOG_ERROR, "No event handler found for event %d.\n", event->e);
			}
		}
	}
	sbridge_mutex_unlock(&spri->lock);
	return sel;
}
Exemplo n.º 7
0
static void *ftdm_pritap_run(ftdm_thread_t *me, void *obj)
{
    ftdm_span_t *span = (ftdm_span_t *) obj;
    ftdm_span_t *peer = NULL;
    pritap_t *pritap = span->signal_data;
    pritap_t *p_pritap = NULL;
    pri_event *event = NULL;
    struct pollfd dpoll[2];
    int rc = 0;

    ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread started on span %s\n", span->name);

    pritap->span = span;

    ftdm_set_flag(span, FTDM_SPAN_IN_THREAD);

    if (ftdm_channel_open(span->span_id, pritap->dchan->chan_id, &pritap->dchan) != FTDM_SUCCESS) {
        ftdm_log(FTDM_LOG_ERROR, "Failed to open D-channel for span %s\n", span->name);
        goto done;
    }

    if ((pritap->pri = pri_new_cb(pritap->dchan->sockfd, PRI_NETWORK, PRI_SWITCH_NI2, pri_io_read, pri_io_write, pritap))) {
        pri_set_debug(pritap->pri, pritap->debug);
    } else {
        ftdm_log(FTDM_LOG_CRIT, "Failed to create tapping PRI\n");
        goto done;
    }

    /* The last span starting runs the show ...
     * This simplifies locking and avoid races by having multiple threads for a single tapped link
     * Since both threads really handle a single tapped link there is no benefit on multi-threading, just complications ... */
    peer = pritap->peerspan;
    p_pritap = peer->signal_data;
    if (!ftdm_test_flag(pritap, PRITAP_MASTER)) {
        ftdm_log(FTDM_LOG_DEBUG, "Running dummy thread on span %s\n", span->name);
        while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) {
            poll(NULL, 0, 100);
        }
    } else {
        memset(&dpoll, 0, sizeof(dpoll));
        dpoll[0].fd = pritap->dchan->sockfd;
        dpoll[1].fd = p_pritap->dchan->sockfd;

        ftdm_log(FTDM_LOG_DEBUG, "Master tapping thread on span %s (fd1=%d, fd2=%d)\n", span->name,
                 pritap->dchan->sockfd, p_pritap->dchan->sockfd);

        while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) {

            pritap_check_state(span);
            pritap_check_state(peer);

            dpoll[0].revents = 0;
            dpoll[0].events = POLLIN;

            dpoll[1].revents = 0;
            dpoll[1].events = POLLIN;

            rc = poll(&dpoll[0], 2, 10);

            if (rc < 0) {
                if (errno == EINTR) {
                    ftdm_log(FTDM_LOG_DEBUG, "D-channel waiting interrupted, continuing ...\n");
                    continue;
                }
                ftdm_log(FTDM_LOG_ERROR, "poll failed: %s\n", strerror(errno));
                continue;
            }

            pri_schedule_run(pritap->pri);
            pri_schedule_run(p_pritap->pri);

            pritap_check_state(span);
            pritap_check_state(peer);

            if (rc) {
                if (dpoll[0].revents & POLLIN) {
                    event = pri_read_event(pritap->pri);
                    if (event) {
                        handle_pri_passive_event(pritap, event);
                        pritap_check_state(span);
                    }
                }

                if (dpoll[1].revents & POLLIN) {
                    event = pri_read_event(p_pritap->pri);
                    if (event) {
                        handle_pri_passive_event(p_pritap, event);
                        pritap_check_state(peer);
                    }
                }
            }

        }
    }


done:
    ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread ended on span %s\n", span->name);

    ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
    ftdm_clear_flag(pritap, PRITAP_RUNNING);
    ftdm_clear_flag(pritap, PRITAP_MASTER);

    return NULL;
}