예제 #1
0
static int __pri_sangoma_read(struct pri *pri, void *buf, int buflen)
{
	unsigned char tmpbuf[sizeof(wp_tdm_api_rx_hdr_t)];
	int prifd = pri_fd(pri);	

	/* NOTE: This code will be different for A104 
	 *       A104   receives data + 2byte CRC + 1 byte flag 
	 *       A101/2 receives data only */ 
	
	int res = sangoma_readmsg_socket(prifd, 
					 tmpbuf, sizeof(wp_tdm_api_rx_hdr_t), 
					 buf, buflen, 
					 0);
	if (res > 0){
#ifdef WANPIPE_LEGACY_A104
		/* Prior 2.3.4 release A104 API passed up
                 * 3 extra bytes: 2 CRC + 1 FLAG,
                 * PRI is expecting only 2 CRC bytes, thus we
                 * must remove 1 flag byte */
		res--;
#else
		/* Add 2 byte CRC and set it to ZERO */ 
		memset(&((unsigned char*)buf)[res],0,2);
		res+=2;
#endif
	} else if (res < 0) {
		sbridge_log(SBRIDGE_LOG_ERROR, "Failed to read PRI from sangoma device %d: %s\n", 
				prifd, sbridge_os_get_last_error());
	}

	return res;
}
예제 #2
0
static int __pri_sangoma_write(struct pri *pri, void *buf, int buflen)
{
	unsigned char tmpbuf[sizeof(wp_tdm_api_rx_hdr_t)];
	int res, myerrno;
	int prifd = pri_fd(pri);

	memset(&tmpbuf[0],0,sizeof(wp_tdm_api_rx_hdr_t));	

	if (buflen < 1){
		/* HDLC Frame must be greater than 2byte CRC */
		sbridge_log(SBRIDGE_LOG_ERROR, "Got short PRI frame of len %d\n", buflen);
		return -1;
	}

	/* FIXME: This might cause problems with other libraries
	 * We must remove 2 bytes from buflen because
	 * libpri sends 2 fake CRC bytes */
	res = sangoma_sendmsg_socket(prifd,
				   tmpbuf, sizeof(wp_tdm_api_rx_hdr_t),
				   buf, (unsigned short)buflen - 2,
				   0);	
	if (res > 0){
		res = buflen;
	} else if (res < 0) {
		myerrno = errno;
		sbridge_log(SBRIDGE_LOG_ERROR, "Failed to write %d bytes to PRI sangoma device %d: %s\n", 
				buflen, prifd, sbridge_os_get_last_error());
		if (errno == EBUSY) {
			/* TODO: flush buffers */
		}
	}
	
	return res;
}
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;
}
예제 #4
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;
}
예제 #5
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;
}
예제 #6
0
int sangoma_close_pri(struct sangoma_pri *spri)
{
	int prifd = pri_fd(spri->pri);
	sangoma_socket_close(&prifd);
	return 0;
}