Example #1
0
void next_event(struct params *p)
{
	struct timeval to, now;
	int el;
	int max;
	fd_set fds;
	int rtr = 3*1000;

	/* figure out select timeout */
	if (gettimeofday(&now, NULL) == -1)
		err(1, "gettimeofday()");

	/* check beacon timeout */
	el = elapsed(&p->blast, &now);
	if (el >= p->bint) {
		send_beacon(p);
		el = 0;
	}
	el = p->bint - el;
	to.tv_sec = el/1000/1000;
	to.tv_usec = el - to.tv_sec*1000*1000;

	/* check tx timeout */
	if (p->packet_try) {
		el = elapsed(&p->plast, &now);
		if (el >= rtr) {
			/* check if we gotta retransmit more */
			if (retransmit(p)) {
				el = 0;
			}
			else
				el = -1;
		}

		/* gotta retransmit in future */
		if (el != -1) {
			el = rtr - el;
			if ((to.tv_sec*1000*1000 + to.tv_usec) > el) {
				to.tv_sec = el/1000/1000;
				to.tv_usec = el - to.tv_sec*1000*1000;
			}
		}
	}

	/* select */
	FD_ZERO(&fds);
	FD_SET(p->rx, &fds);
	FD_SET(p->tap, &fds);
	max = p->rx > p->tap ? p->rx : p->tap;
	if (select(max+1, &fds, NULL, NULL, &to) == -1)
		err(1, "select()");

	if (FD_ISSET(p->tap, &fds))
		read_tap(p);
	if (FD_ISSET(p->rx, &fds))
		read_wifi(p);
}
Example #2
0
static int process_events_once(int timeout)
{
	struct timeval tv = {0, 0};
	int r;
	int libusb_delay;
	int delay;
	unsigned int i;
	char process_libusb = 0;

	r = libusb_get_next_timeout(ctx, &tv);
	if (r == 1 && tv.tv_sec == 0 && tv.tv_usec == 0)
	{
		r = libusb_handle_events_timeout(ctx, &tv);
	}

	delay = libusb_delay = tv.tv_sec * 1000 + tv.tv_usec;
	if (delay <= 0 || delay > timeout)
	{
		delay = timeout;
	}

	CHECK_NEGATIVE(poll(fds, nfds, delay));

	process_libusb = (r == 0 && delay == libusb_delay);

	for (i = 0; i < nfds; ++i)
	{
		if (fds[i].fd == tap_fd) {
			if (fds[i].revents)
			{
				CHECK_NEGATIVE(read_tap());
			}
			continue;
		}
		process_libusb |= fds[i].revents;
	}

	if (process_libusb)
	{
		struct timeval tv = {.tv_sec = 0, .tv_usec = 0};
		CHECK_NEGATIVE(libusb_handle_events_timeout(ctx, &tv));
	}

	return 0;
}

/* handle events until timeout is reached or all of the events in event_mask happen */
static int process_events_by_mask(int timeout, unsigned int event_mask)
{
	struct timeval start, curr;
	int r;
	int delay = timeout;

	CHECK_NEGATIVE(gettimeofday(&start, NULL));

	wd_status.info_updated &= ~event_mask;

	while ((event_mask == 0 || (wd_status.info_updated & event_mask) != event_mask) && delay >= 0) {
		long a;

		CHECK_NEGATIVE(process_events_once(delay));

		if (device_disconnected) {
			exit_release_resources(0);
		}

		CHECK_NEGATIVE(gettimeofday(&curr, NULL));

		a = (curr.tv_sec - start.tv_sec) * 1000 + (curr.tv_usec - start.tv_usec) / 1000;
		delay = timeout - a;
	}

	wd_status.info_updated &= ~event_mask;

	return (delay > 0) ? delay : 0;
}

int alloc_fds()
{
	int i;
	const struct libusb_pollfd **usb_fds = libusb_get_pollfds(ctx);

	if (!usb_fds)
	{
		return -1;
	}

	nfds = 0;
	while (usb_fds[nfds])
	{
		nfds++;
	}
	if (tap_fd != -1) {
		nfds++;
	}

	if(fds != NULL) {
		free(fds);
	}

	fds = (struct pollfd*)calloc(nfds, sizeof(struct pollfd));
	for (i = 0; usb_fds[i]; ++i)
	{
		fds[i].fd = usb_fds[i]->fd;
		fds[i].events = usb_fds[i]->events;
		set_coe(usb_fds[i]->fd);
	}
	if (tap_fd != -1) {
		fds[i].fd = tap_fd;
		fds[i].events = POLLIN;
		fds[i].revents = 0;
	}

	free(usb_fds);

	return 0;
}