Exemplo n.º 1
0
void freespace_setFileDescriptorCallbacks(freespace_pollfdAddedCallback addedCallback,
                                          freespace_pollfdRemovedCallback removedCallback) {
    userAddedCallback = addedCallback;
    userRemovedCallback = removedCallback;

    libusb_set_pollfd_notifiers(freespace_libusb_context, pollfd_added_cb, pollfd_removed_cb, NULL);
}
Exemplo n.º 2
0
static void exit_release_resources(int code)
{
	if(tap_fd >= 0) {
		if_down();
		while (wait(NULL) > 0) {}
		if_release();
		while (wait(NULL) > 0) {}
	}
	if(ctx != NULL) {
		if(req_transfer != NULL) {
			libusb_cancel_transfer(req_transfer);
			libusb_free_transfer(req_transfer);
		}
		libusb_set_pollfd_notifiers(ctx, NULL, NULL, NULL);
		if(fds != NULL) {
			free(fds);
		}
		if(devh != NULL) {
			libusb_release_interface(devh, 0);
			if (kernel_driver_active)
				libusb_attach_kernel_driver(devh, 0);
			libusb_unlock_events(ctx);
			libusb_close(devh);
		}
		libusb_exit(ctx);
	}
	if(logfile != NULL) {
		fclose(logfile);
	}
	exit(code);
}
Exemplo n.º 3
0
void ncusb_start_descriptor_watching(struct aura_node *node, libusb_context *ctx)
{
	/* Fetch all existing descriptors from the library */ 
	const struct libusb_pollfd** fds_data = libusb_get_pollfds(ctx);
	const struct libusb_pollfd** fds = fds_data; 

	while (*fds != NULL) { 
		pollfd_added_cb((*fds)->fd, (*fds)->events, node);
		fds++;
	}
	free(fds_data);
	/* Register a callback */ 
	libusb_set_pollfd_notifiers(ctx, pollfd_added_cb, pollfd_removed_cb, node);
}
Exemplo n.º 4
0
/** USB event source finalize() method.
 */
static void usb_source_finalize(GSource *source)
{
	struct usb_source *usource;

	usource = (struct usb_source *)source;

	sr_spew("%s", __func__);

	libusb_set_pollfd_notifiers(usource->usb_ctx, NULL, NULL, NULL);

	g_ptr_array_unref(usource->pollfds);
	usource->pollfds = NULL;

	sr_session_source_destroyed(usource->session,
			usource->usb_ctx, source);
}
Exemplo n.º 5
0
/** Create an event source for libusb I/O.
 *
 * TODO: The combination of the USB I/O source with a user timeout is
 * conceptually broken. The user timeout supplied here is completely
 * unrelated to I/O -- the actual I/O timeout is set when submitting
 * a USB transfer.
 * The sigrok drivers generally use the timeout to poll device state.
 * Usually, this polling can be sensibly done only when there is no
 * active USB transfer -- i.e. it's actually mutually exclusive with
 * waiting for transfer completion.
 * Thus, the user timeout should be removed from the USB event source
 * API at some point. Instead, drivers should install separate timer
 * event sources for their polling needs.
 *
 * @param session The session the event source belongs to.
 * @param usb_ctx The libusb context for which to handle events.
 * @param timeout_ms The timeout interval in ms, or -1 to wait indefinitely.
 * @return A new event source object, or NULL on failure.
 */
static GSource *usb_source_new(struct sr_session *session,
		struct libusb_context *usb_ctx, int timeout_ms)
{
	static GSourceFuncs usb_source_funcs = {
		.prepare  = &usb_source_prepare,
		.check    = &usb_source_check,
		.dispatch = &usb_source_dispatch,
		.finalize = &usb_source_finalize
	};
	GSource *source;
	struct usb_source *usource;
	const struct libusb_pollfd **upollfds, **upfd;

	upollfds = libusb_get_pollfds(usb_ctx);
	if (!upollfds) {
		sr_err("Failed to get libusb file descriptors.");
		return NULL;
	}
	source = g_source_new(&usb_source_funcs, sizeof(struct usb_source));
	usource = (struct usb_source *)source;

	g_source_set_name(source, "usb");

	if (timeout_ms >= 0) {
		usource->timeout_us = 1000 * (int64_t)timeout_ms;
		usource->due_us = 0;
	} else {
		usource->timeout_us = -1;
		usource->due_us = INT64_MAX;
	}
	usource->session = session;
	usource->usb_ctx = usb_ctx;
	usource->pollfds = g_ptr_array_new_full(8, &usb_source_free_pollfd);

	for (upfd = upollfds; *upfd != NULL; upfd++)
		usb_pollfd_added((*upfd)->fd, (*upfd)->events, usource);

#if (LIBUSB_API_VERSION >= 0x01000104)
	libusb_free_pollfds(upollfds);
#else
	free(upollfds);
#endif
	libusb_set_pollfd_notifiers(usb_ctx,
		&usb_pollfd_added, &usb_pollfd_removed, usource);

	return source;
}
Exemplo n.º 6
0
int start_libusb_events()
{
	pthread_mutex_lock(&refcnt_mutex);
	event_loop_refcnt++;
	pthread_mutex_unlock(&refcnt_mutex);

	if(event_loop_refcnt == 1) {
		libusb_set_pollfd_notifiers(libusb_ctx, NULL,
			(libusb_pollfd_removed_cb) usb_removed, NULL);

		int ret = pthread_create(&event_thread, NULL, &event_loop, NULL);
		if(ret != 0) {
			ERROR_NORET("Unable to create USB events thread!");
			pthread_mutex_lock(&refcnt_mutex);
			event_loop_refcnt=0;
			pthread_mutex_unlock(&refcnt_mutex);
			return -1;
		}
	}

	return 0;
}
Exemplo n.º 7
0
void usb_destroy_context(libusb_context *context) {
	const struct libusb_pollfd **pollfds = NULL;
	const struct libusb_pollfd **pollfd;

	libusb_set_pollfd_notifiers(context, NULL, NULL, NULL);

	pollfds = libusb_get_pollfds(context);

	if (pollfds == NULL) {
		log_error("Could not get pollfds from main libusb context");
	} else {
		for (pollfd = pollfds; *pollfd != NULL; ++pollfd) {
			event_remove_source((*pollfd)->fd, EVENT_SOURCE_TYPE_USB);
		}

#if defined(_WIN32) || (defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000104) // libusb 1.0.20
		libusb_free_pollfds(pollfds); // avoids possible heap-mismatch on Windows
#else
		free(pollfds);
#endif
	}

	libusb_exit(context);
}
Exemplo n.º 8
0
int usb_create_context(libusb_context **context) {
	int phase = 0;
	int rc;
	const struct libusb_pollfd **pollfds = NULL;
	const struct libusb_pollfd **pollfd;
	const struct libusb_pollfd **last_added_pollfd = NULL;

	rc = libusb_init(context);

	if (rc < 0) {
		log_error("Could not initialize libusb context: %s (%d)",
		          usb_get_error_name(rc), rc);

		goto cleanup;
	}

	switch (log_get_effective_level()) {
	case LOG_LEVEL_ERROR:
		libusb_set_debug(*context, 1);
		break;

	case LOG_LEVEL_WARN:
		libusb_set_debug(*context, 2);
		break;

	case LOG_LEVEL_INFO:
		libusb_set_debug(*context, 3);
		break;

	case LOG_LEVEL_DEBUG:
		if (log_is_included(LOG_LEVEL_DEBUG, &_libusb_log_source,
		                    LOG_DEBUG_GROUP_LIBUSB)) {
			libusb_set_debug(*context, 4);
		} else {
			libusb_set_debug(*context, 3);
		}

		break;

	default:
		break;
	}

	phase = 1;

	// get pollfds from main libusb context
	pollfds = libusb_get_pollfds(*context);

	if (pollfds == NULL) {
		log_error("Could not get pollfds from libusb context");

		goto cleanup;
	}

	for (pollfd = pollfds; *pollfd != NULL; ++pollfd) {
		if (event_add_source((*pollfd)->fd, EVENT_SOURCE_TYPE_USB,
		                     (*pollfd)->events, usb_handle_events,
		                     *context) < 0) {
			goto cleanup;
		}

		last_added_pollfd = pollfd;
		phase = 2;
	}

	phase = 3;

	// register pollfd notifiers
	libusb_set_pollfd_notifiers(*context, usb_add_pollfd, usb_remove_pollfd,
	                            *context);

cleanup:
	switch (phase) { // no breaks, all cases fall through intentionally
	case 2:
		for (pollfd = pollfds; pollfd != last_added_pollfd; ++pollfd) {
			event_remove_source((*pollfd)->fd, EVENT_SOURCE_TYPE_USB);
		}

	case 1:
		libusb_exit(*context);

	default:
		break;
	}

#if defined(_WIN32) || (defined(LIBUSB_API_VERSION) && LIBUSB_API_VERSION >= 0x01000104) // libusb 1.0.20
	libusb_free_pollfds(pollfds); // avoids possible heap-mismatch on Windows
#else
	free(pollfds);
#endif

	return phase == 3 ? 0 : -1;
}
Exemplo n.º 9
0
int main(int argc, char **argv)
{
	struct sigaction sigact;
  struct sigevent sev;
  struct itimerspec its;
	int r = 1;

	parse_args(argc, argv);

	sigact.sa_handler = sighandler_exit;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);
	sigact.sa_handler = sighandler_wait_child;
	sigaction(SIGCHLD, &sigact, NULL);
  sigact.sa_handler = sighandler_stats;
  sigfillset(&sigact.sa_mask);
  if (stats_period == 0)
    sigaction(SIGUSR1, &sigact, NULL);

	if (logfile != NULL) {
		set_wmlogger(argv[0], WMLOGGER_FILE, logfile);
	} else if (daemonize) {
		set_wmlogger(argv[0], WMLOGGER_SYSLOG, NULL);
	} else {
		set_wmlogger(argv[0], WMLOGGER_FILE, stderr);
	}

	if (daemonize) {
		daemon(0, 0);
	}
	
	if (stats_period != 0) {
    sigemptyset(&sigact.sa_mask);
    sigaction(SIGRTMIN, &sigact, NULL);
    
    // create the POSIX timer 
    sev.sigev_notify = SIGEV_SIGNAL;
    sev.sigev_signo = SIGRTMIN;
    sev.sigev_value.sival_ptr = (void *) &timerid;
    if (timer_create(CLOCK_MONOTONIC, &sev, &timerid) == 0) {
        // start the POSIX timer
        its.it_value.tv_sec = stats_period;
        its.it_value.tv_nsec = 0;
        its.it_interval.tv_sec = its.it_value.tv_sec;
        its.it_interval.tv_nsec = its.it_value.tv_nsec;
        timer_settime(timerid, 0, &its, NULL);
    }
  }

	r = libusb_init(&ctx);
	if (r < 0) {
		wmlog_msg(0, "failed to initialise libusb");
		exit_release_resources(1);
	}
	
	if (pid_fname && !write_pidfile(pid_fname)) {
    wmlog_msg(0, "failed to create pid file %s", pid_fname);
    exit_release_resources(1);
  }

	devh = find_wimax_device();
	if (devh == NULL) {
		wmlog_msg(0, "Could not find/open device");
		exit_release_resources(1);
	}

	wmlog_msg(0, "Device found");

	if (detach_dvd && libusb_kernel_driver_active(devh, IF_DVD) == 1) {
		r = libusb_detach_kernel_driver(devh, IF_DVD);
		if (r < 0) {
			wmlog_msg(0, "kernel driver detach error %d", r);
		} else {
			wmlog_msg(0, "detached pseudo-DVD kernel driver");
		}
	}

	if (libusb_kernel_driver_active(devh, IF_MODEM) == 1) {
		kernel_driver_active = 1;
		r = libusb_detach_kernel_driver(devh, IF_MODEM);
		if (r < 0) {
			wmlog_msg(0, "kernel driver detach error %d", r);
		} else {
			wmlog_msg(0, "detached modem kernel driver");
		}
	}

	r = libusb_claim_interface(devh, IF_MODEM);
	if (r < 0) {
		wmlog_msg(0, "Claim usb interface error %d", r);
		exit_release_resources(1);
	}
	wmlog_msg(0, "Claimed interface");

	alloc_fds();
	libusb_set_pollfd_notifiers(ctx, cb_add_pollfd, cb_remove_pollfd, NULL);

	r = init();
	if (r < 0) {
		wmlog_msg(0, "init error %d", r);
		exit_release_resources(1);
	}

	if_create();
	cb_add_pollfd(tap_fd, POLLIN, NULL);

	r = scan_loop();
	if (r < 0) {
		wmlog_msg(0, "scan_loop error %d", r);
		exit_release_resources(1);
	}

	exit_release_resources(0);
	return 0;
}
Exemplo n.º 10
0
int main(int argc, char **argv)
{
	struct sigaction sigact;
	int r = 1;

	parse_args(argc, argv);

	sigact.sa_handler = sighandler_exit;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);
	sigact.sa_handler = sighandler_wait_child;
	sigaction(SIGCHLD, &sigact, NULL);

	if (logfile != NULL) {
		set_wmlogger(argv[0], WMLOGGER_FILE, logfile);
	} else if (daemonize) {
		set_wmlogger(argv[0], WMLOGGER_SYSLOG, NULL);
	} else {
		set_wmlogger(argv[0], WMLOGGER_FILE, stderr);
	}

	if (daemonize) {
		daemon(0, 0);
	}

	r = libusb_init(&ctx);
	if (r < 0) {
		wmlog_msg(0, "failed to initialise libusb");
		exit_release_resources(1);
	}

	devh = find_wimax_device();
	if (devh == NULL) {
		wmlog_msg(0, "Could not find/open device");
		exit_release_resources(1);
	}

	wmlog_msg(0, "Device found");

	if (detach_dvd && libusb_kernel_driver_active(devh, IF_DVD) == 1) {
		r = libusb_detach_kernel_driver(devh, IF_DVD);
		if (r < 0) {
			wmlog_msg(0, "kernel driver detach error %d", r);
		} else {
			wmlog_msg(0, "detached pseudo-DVD kernel driver");
		}
	}

	if (libusb_kernel_driver_active(devh, IF_MODEM) == 1) {
		kernel_driver_active = 1;
		r = libusb_detach_kernel_driver(devh, IF_MODEM);
		if (r < 0) {
			wmlog_msg(0, "kernel driver detach error %d", r);
		} else {
			wmlog_msg(0, "detached modem kernel driver");
		}
	}

	r = libusb_claim_interface(devh, IF_MODEM);
	if (r < 0) {
		wmlog_msg(0, "Claim usb interface error %d", r);
		exit_release_resources(1);
	}
	wmlog_msg(0, "Claimed interface");

	alloc_fds();
	libusb_set_pollfd_notifiers(ctx, cb_add_pollfd, cb_remove_pollfd, NULL);

	r = init();
	if (r < 0) {
		wmlog_msg(0, "init error %d", r);
		exit_release_resources(1);
	}

	if_create();
	cb_add_pollfd(tap_fd, POLLIN, NULL);

	r = scan_loop();
	if (r < 0) {
		wmlog_msg(0, "scan_loop error %d", r);
		exit_release_resources(1);
	}

	exit_release_resources(0);
	return 0;
}