Esempio n. 1
1
gboolean read_g_stdin(GIOChannel * source, GIOCondition condition, gpointer data){
	struct libusb_transfer ** bulkIO = (struct libusb_transfer **)data;
	struct libusb_transfer * bulk_in  = bulkIO[0];
	struct libusb_transfer * bulk_out = bulkIO[1];
	unsigned char * in_buf = NULL;
	gsize bytes_read = 0;
	gsize terminator_pos = 0;
	GError * error = NULL;

	if(condition & ~(G_IO_IN | G_IO_ERR | G_IO_HUP)){
		printf("**Unknown GIOCondition\n");
		g_main_loop_quit(edfc_main);
		return FALSE;
	}
	if(condition & G_IO_ERR){
		printf("**stdin error\n");
		g_main_loop_quit(edfc_main);
		return FALSE;
	}
	if(condition & G_IO_HUP){
		printf("**stdin hung up\n");
		g_main_loop_quit(edfc_main);
		return FALSE;
	}
	//then condition must be G_IO_IN
	g_io_channel_read_line(source, (gchar**)&in_buf, &bytes_read, &terminator_pos, &error);
	if(bytes_read > 0){ //todo: handle series of chars?
		printf("input: %c\n", in_buf[0]);
		bulk_out->length=1;
		switch(in_buf[0]){
		case 'g':
			libusb_submit_transfer(bulk_in);
			break;

		case 'B':
			bulk_out->buffer[0] = 'B';
			if(libusb_submit_transfer(bulk_out))
				printf("last char transfer not yet submitted\n");
			break;

		case 'q':
			printf("\nquit\n");
			//todo: send stop to IMU?
			libusb_cancel_transfer(bulk_in);
			libusb_cancel_transfer(bulk_out);
			g_main_loop_quit(edfc_main);
			break;
		default:
			printf("unknown input\n");
			break;
		}
		g_free(in_buf);
	}
	return TRUE;
}
Esempio n. 2
0
static void usb_panic_and_reset_state(struct aura_node *node)
{
	struct usb_dev_info *inf = aura_get_transportdata(node);	

	slog(4, SLOG_DEBUG, "usb: pending transfers: %s %s", 
	     inf->ibusy ? "interrupt " : "",
	     inf->cbusy ? "control" : "" );

	if (inf->state != AUSB_DEVICE_SEARCHING) { 
		slog(4, SLOG_DEBUG, "usb: Entering 'failing' state");
		inf->state = AUSB_DEVICE_FAILING;
		if (inf->ibusy) { 
			libusb_cancel_transfer(inf->itransfer);
			slog(4, SLOG_DEBUG, "usb: cancelling itransfer");
		}
		if (inf->cbusy) { 
			libusb_cancel_transfer(inf->ctransfer);
			slog(4, SLOG_DEBUG, "usb: cancelling ctransfer");
		}
	}
	
	if ((!inf->ibusy) && (!inf->cbusy)) { 
		slog(4, SLOG_DEBUG, "usb: Cleanup done, entering 'restart' state");
		/* 
		 * We can't call libusb_close from within a callback
		 * some versions of libusb will hang, we'll close 
		 * from main loop
		 */
		/* libusb_close(inf->handle); */
		inf->state = AUSB_DEVICE_RESTART;
	}
}
Esempio n. 3
0
static void
cd_sensor_unlock_thread_cb (GTask *task,
			    gpointer source_object,
			    gpointer task_data,
			    GCancellable *cancellable)
{
	CdSensor *sensor = CD_SENSOR (object);
	CdSensorMunkiPrivate *priv = cd_sensor_munki_get_private (sensor);
	gboolean ret = FALSE;
	g_autoptr(GError) error = NULL;

	/* stop watching the dial */
	libusb_cancel_transfer (priv->transfer_interrupt);
	libusb_cancel_transfer (priv->transfer_state);

	/* close */
	if (priv->device != NULL) {
		if (!g_usb_device_close (priv->device, &error)) {
			g_task_return_new_error (task,
					 CD_SENSOR_ERROR,
					 CD_SENSOR_ERROR_INTERNAL,
					 "%s", error->message);
			return;
		}
		g_clear_object (&priv->device);
	}

	/* success */
	g_task_return_boolean (task, TRUE);
}
Esempio n. 4
0
 void close_transfers()
 {
     libusb_cancel_transfer(xfr[0]);
     libusb_cancel_transfer(xfr[1]);
     while(num_transfers)
     {
         if( !USBMgr::instance()->handleEvents() )
         {
             break;
         }
     }
 }
Esempio n. 5
0
	void FalconCommLibUSB::reset()
	{
		if(m_isWriteAllocated)
		{
			libusb_cancel_transfer(in_transfer);
			setSent();
		}
		if(m_isReadAllocated)
		{
			libusb_cancel_transfer(out_transfer);
			setReceived();
		}
	}
Esempio n. 6
0
void HID_API_EXPORT hid_close(hid_device *dev)
{
	if (!dev)
		return;
	
	/* Cause read_thread() to stop. */
	dev->shutdown_thread = 1;
	libusb_cancel_transfer(dev->transfer);

	/* Wait for read_thread() to end. */
	pthread_join(dev->thread, NULL);
	
	/* Clean up the Transfer objects allocated in read_thread(). */
	free(dev->transfer->buffer);
	libusb_free_transfer(dev->transfer);
	
	/* release the interface */
	libusb_release_interface(dev->device_handle, dev->interface);
	
	/* Close the handle */
	libusb_close(dev->device_handle);
	
	/* Clear out the queue of received reports. */
	pthread_mutex_lock(&dev->mutex);
	while (dev->input_reports) {
		return_data(dev, NULL, 0);
	}
	pthread_mutex_unlock(&dev->mutex);
	
	free_hid_device(dev);
}
Esempio n. 7
0
FN_INTERNAL int fnusb_stop_iso(fnusb_dev *dev, fnusb_isoc_stream *strm)
{
	freenect_context *ctx = dev->parent->parent;
	int i;

	FN_FLOOD("fnusb_stop_iso() called\n");

	strm->dead = 1;

	for (i=0; i<strm->num_xfers; i++)
		libusb_cancel_transfer(strm->xfers[i]);
	FN_FLOOD("fnusb_stop_iso() cancelled all transfers\n");

	while (strm->dead_xfers < strm->num_xfers) {
		FN_FLOOD("fnusb_stop_iso() dead = %d\tnum = %d\n", strm->dead_xfers, strm->num_xfers);
		libusb_handle_events(ctx->usb.ctx);
	}

	for (i=0; i<strm->num_xfers; i++)
		libusb_free_transfer(strm->xfers[i]);
	FN_FLOOD("fnusb_stop_iso() freed all transfers\n");

	free(strm->buffer);
	free(strm->xfers);

	FN_FLOOD("fnusb_stop_iso() freed buffers and stream\n");
	FN_FLOOD("fnusb_stop_iso() done\n");
	return 0;
}
Esempio n. 8
0
void ubertooth_stop(struct libusb_device_handle *devh)
{
	/* make sure xfers are not active */
	if(rx_xfer != NULL)
		libusb_cancel_transfer(rx_xfer);
	if (devh != NULL) {
		cmd_stop(devh);
		libusb_release_interface(devh, 0);
	}
	libusb_close(devh);
	libusb_exit(NULL);

#if defined(USE_PCAP)
	if (h_pcap_bredr) {
		btbb_pcap_close(h_pcap_bredr);
		h_pcap_bredr = NULL;
	}
	if (h_pcap_le) {
		lell_pcap_close(h_pcap_le);
		h_pcap_le = NULL;
	}
#endif
	if (h_pcapng_bredr) {
		btbb_pcapng_close(h_pcapng_bredr);
		h_pcapng_bredr = NULL;
	}
	if (h_pcapng_le) {
		lell_pcapng_close(h_pcapng_le);
		h_pcapng_le = NULL;
	}
}
uint8_t portpilot_helpers_free_ctx(struct portpilot_ctx *pp_ctx, uint8_t force)
{
    struct portpilot_dev *ppd_itr = pp_ctx->dev_head.lh_first, *ppd_tmp;
    uint8_t failed_cancels = 0;

    while (ppd_itr != NULL) {
        ppd_tmp = ppd_itr;
        ppd_itr = ppd_itr->next_dev.le_next;

        //We are only allowed to free memory if transfer is cancelled, so check
        //for this and indicate to loop if we need to wait for cancelled
        //transfers
        if (force || (ppd_tmp->transfer &&
                libusb_cancel_transfer(ppd_tmp->transfer) ==
                LIBUSB_ERROR_NOT_FOUND)) {
            portpilot_helpers_free_dev(ppd_tmp);
        } else {
            ++pp_ctx->num_cancel;
            ++failed_cancels;
        }
    }

    if (failed_cancels)
        return failed_cancels;

    if (pp_ctx->output_timeout_handle)
        free(pp_ctx->output_timeout_handle);

    free(pp_ctx->itr_timeout_handle);
    free(pp_ctx->libusb_handle);
    free(pp_ctx->event_loop);
    free(pp_ctx);

    return failed_cancels;
}
Esempio n. 10
0
FX3Dev::~FX3Dev() {
    if ( write_transfer ) {
        libusb_cancel_transfer(write_transfer);
        libusb_free_transfer(write_transfer);
    }
    
    if ( device_handle ) {
        int ires = libusb_release_interface(device_handle, 0);
        if( ires != 0 ) {
            fprintf( stderr,"FX3Dev::~FX3Dev(): libusb_release_interface failed with code %d %s\n", ires, libusb_error_name( ires ) );
        }
        libusb_close( device_handle );
        device_handle = NULL;
    }
    if ( ctx ) {
        libusb_exit( ctx );
    }
    
    for( uint32_t i = 0; i < buffers_count; i++ ) {
        delete [] half_full_buffers[ i ];
    }
    if ( write_buffer ) {
        delete[] write_buffer;
    }
}
Esempio n. 11
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);
}
Esempio n. 12
0
int ubertooth_bulk_receive(ubertooth_t* ut, rx_callback cb, void* cb_args)
{
	int i;
	usb_pkt_rx* rx;

	if (ut->usb_really_full) {
		/* process each received block */
		for (i = 0; i < PKTS_PER_XFER; i++) {
			rx = (usb_pkt_rx *)(ut->full_usb_buf + PKT_LEN * i);
			if(rx->pkt_type != KEEP_ALIVE) {
				ringbuffer_add(ut->packets, rx);
				(*cb)(ut, cb_args);
			}
			if(ut->stop_ubertooth) {
				if(ut->rx_xfer)
					libusb_cancel_transfer(ut->rx_xfer);
				return 1;
			}
		}
		ut->usb_really_full = 0;
		fflush(stderr);
		return 0;
	} else {
		return -1;
	}
}
Esempio n. 13
0
static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
	unsigned char endpoint, unsigned char *buffer, int length,
	int *transferred, unsigned int timeout, unsigned char type)
{
	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
	int completed = 0;
	int r;

	if (!transfer)
		return LIBUSB_ERROR_NO_MEM;

	libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length,
		bulk_transfer_cb, &completed, timeout);
	transfer->type = type;

	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		libusb_free_transfer(transfer);
		return r;
	}

	while (!completed) {
		r = libusb_handle_events(HANDLE_CTX(dev_handle));
		if (r < 0) {
			libusb_cancel_transfer(transfer);
			while (!completed)
				if (libusb_handle_events(HANDLE_CTX(dev_handle)) < 0)
					break;
			libusb_free_transfer(transfer);
			return r;
		}
	}

	*transferred = transfer->actual_length;
	switch (transfer->status) {
	case LIBUSB_TRANSFER_COMPLETED:
		r = 0;
		break;
	case LIBUSB_TRANSFER_TIMED_OUT:
		r = LIBUSB_ERROR_TIMEOUT;
		break;
	case LIBUSB_TRANSFER_STALL:
		r = LIBUSB_ERROR_PIPE;
		break;
	case LIBUSB_TRANSFER_OVERFLOW:
		r = LIBUSB_ERROR_OVERFLOW;
		break;
	case LIBUSB_TRANSFER_NO_DEVICE:
		r = LIBUSB_ERROR_NO_DEVICE;
		break;
	default:
		usbi_warn(HANDLE_CTX(dev_handle),
			"unrecognised status code %d", transfer->status);
		r = LIBUSB_ERROR_OTHER;
	}

	libusb_free_transfer(transfer);
	return r;
}
Esempio n. 14
0
Chatpad::~Chatpad()
{
  if (m_read_transfer)
  {
    libusb_cancel_transfer(m_read_transfer);
    libusb_free_transfer(m_read_transfer);
  }
}
Esempio n. 15
0
void LibusbDevice::TransferEndpoint::CancelTransfers()
{
  std::lock_guard<std::mutex> lk(m_transfers_mutex);
  if (m_transfers.empty())
    return;
  INFO_LOG(IOS_USB, "Cancelling %ld transfer(s)", m_transfers.size());
  for (const auto& pending_transfer : m_transfers)
    libusb_cancel_transfer(pending_transfer.first);
}
Esempio n. 16
0
void aesX660_dev_deactivate(struct fp_img_dev *dev)
{
	struct aesX660_dev *aesdev = dev->priv;

	if (aesdev->fd_data_transfer)
		libusb_cancel_transfer(aesdev->fd_data_transfer);

	aesdev->deactivating = TRUE;
}
Esempio n. 17
0
static void *read_thread(void *param)
{
	hid_device *dev = param;
	unsigned char *buf;
	const size_t length = dev->input_ep_max_packet_size;

	/* Set up the transfer object. */
	buf = malloc(length);
	dev->transfer = libusb_alloc_transfer(0);
	libusb_fill_interrupt_transfer(dev->transfer,
		dev->device_handle,
		dev->input_endpoint,
		buf,
		length,
		read_callback,
		dev,
		5000/*timeout*/);
	
	/* Make the first submission. Further submissions are made
	   from inside read_callback() */
	libusb_submit_transfer(dev->transfer);

	// Notify the main thread that the read thread is up and running.
	pthread_barrier_wait(&dev->barrier);
	
	/* Handle all the events. */
	while (!dev->shutdown_thread) {
		int res;
		struct timeval tv;

		tv.tv_sec = 0;
		tv.tv_usec = 100; //TODO: Fix this value.
		res = libusb_handle_events_timeout(NULL, &tv);
		if (res < 0) {
			/* There was an error. Break out of this loop. */
			break;
		}
	}
	
	/* Cancel any transfer that may be pending. This call will fail
	   if no transfers are pending, but that's OK. */
	if (libusb_cancel_transfer(dev->transfer) == 0) {
		/* The transfer was cancelled, so wait for its completion. */
		libusb_handle_events(NULL);
	}

	/* The dev->transfer->buffer and dev->transfer objects are cleaned up
	   in hid_close(). They are not cleaned up here because this thread
	   could end either due to a disconnect or due to a user
	   call to hid_close(). In both cases the objects can be safely
	   cleaned up after the call to pthread_join() (in hid_close()), but
	   since hid_close() calls libusb_cancel_transfer(), on these objects,
	   they can not be cleaned up here. */
	
	return NULL;
}
Esempio n. 18
0
static void abort_acquisition(struct dev_context *devc)
{
	int i;

	devc->sent_samples = -1;

	for (i = devc->num_transfers - 1; i >= 0; i--) {
		if (devc->transfers[i])
			libusb_cancel_transfer(devc->transfers[i]);
	}
}
Esempio n. 19
0
extern "C" int LIBUSB_CALL hotplugDetachCallback (libusb_context *, libusb_device *, libusb_hotplug_event, void *ref)
{
    qDebug()<<"Hotplug detach";
    LibUsbDevice *cthis = static_cast<LibUsbDevice *>(ref);
    if(cthis->isDeviceConnected)
    {
        if(cthis->usbDeviceToPcTransfer)
        {
            libusb_cancel_transfer(cthis->usbDeviceToPcTransfer);
        }
        if(cthis->pcToUsbDeviceTransfer)
        {
            libusb_cancel_transfer(cthis->pcToUsbDeviceTransfer);
        }
        libusb_release_interface(cthis->deviceHandle, INTERFACE_NUMBER);
        libusb_close(cthis->deviceHandle);
        cthis->isDeviceConnected = false;
    }
  return 0;
}
Esempio n. 20
0
SR_PRIV void fx2lafw_abort_acquisition(struct dev_context *devc)
{
	int i;

	devc->acq_aborted = TRUE;

	for (i = devc->num_transfers - 1; i >= 0; i--) {
		if (devc->transfers[i])
			libusb_cancel_transfer(devc->transfers[i]);
	}
}
Esempio n. 21
0
/*The API is used to cancel the uart Event notification*/
CYWINEXPORT CY_RETURN_STATUS WINCALLCONVEN CyAbortEventNotification(
    CY_HANDLE handle                               /*Valid handle to communicate with device*/
    )
{
    CY_DEVICE *device;
    device = (CY_DEVICE*)handle;
    pthread_mutex_lock (&device->notificationLock);
    if (device->deviceType == CY_TYPE_UART){
        if ((device->uartThreadId == 0)){
            CY_DEBUG_PRINT_ERROR ("CY:Error uart event notification not created ....function is %s \n", __func__);
            pthread_mutex_unlock (&device->notificationLock);
            return CY_ERROR_REQUEST_FAILED;
        }
        device->uartCancelEvent = true;
        libusb_cancel_transfer (device->uartTransfer);
        pthread_join (device->uartThreadId, NULL);
        device->uartThreadId = 0;
		device->uartCancelEvent = false;
        pthread_mutex_unlock (&device->notificationLock); 
        return CY_SUCCESS;    
    }
    else if (device->deviceType == CY_TYPE_SPI){
        if ((device->spiThreadId == 0)){
            CY_DEBUG_PRINT_ERROR ("CY:Error spi event notification not created ....function is %s \n", __func__);
            pthread_mutex_unlock (&device->notificationLock);
            return CY_ERROR_REQUEST_FAILED;
        }
        device->spiCancelEvent = true;
        libusb_cancel_transfer (device->spiTransfer);
        pthread_join (device->spiThreadId, NULL);
        device->spiThreadId = 0;
        device->spiCancelEvent = false;
        pthread_mutex_unlock (&device->notificationLock); 
        return CY_SUCCESS;    
    }
    else {
        CY_DEBUG_PRINT_ERROR ("CY:Error.. unknown device type ....function is %s \n", __func__);
        pthread_mutex_unlock (&device->notificationLock);
        return CY_ERROR_REQUEST_FAILED;
    }
}
EnttecDMXDevice::~EnttecDMXDevice()
{
    /*
     * If we have pending transfers, cancel them.
     * The Transfer objects themselves will be freed once libusb completes them.
     */

    for (std::set<Transfer*>::iterator i = mPending.begin(), e = mPending.end(); i != e; ++i) {
        Transfer *fct = *i;
        libusb_cancel_transfer(fct->transfer);
    }
}
Esempio n. 23
0
int slogic_spindown(struct slogic_ctx *handle){
	unsigned int transfer_id;
	
	for (transfer_id = 0; transfer_id < handle->n_transfer_buffers; transfer_id++) {
		if(handle->transfers[transfer_id].state == 1){
			libusb_cancel_transfer(handle->transfers[transfer_id].transfer);
			libusb_free_transfer(handle->transfers[transfer_id].transfer);
			handle->transfers[transfer_id].state = 0;
		}
	}
	return 1; //did i want to do something with this?
}
Esempio n. 24
0
FCDevice::~FCDevice()
{
    /*
     * If we have pending transfers, cancel them and jettison them
     * from the FCDevice. The Transfer objects themselves will be freed
     * once libusb completes them.
     */

    for (std::set<Transfer*>::iterator i = mPending.begin(), e = mPending.end(); i != e; ++i) {
        Transfer *fct = *i;
        libusb_cancel_transfer(fct->transfer);
        fct->device = 0;
    }
}
Esempio n. 25
0
int ReapTransfer(transfer_wrapper* wrapper, int timeout)
{
	void* context (wrapper->usb);
	libusb_transfer* transfer (&wrapper->libusb);
	if (transfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER)
	{
		libusb_free_transfer(transfer);
		return(0);
	}

	const int read = usb_reap_async_nocancel(context, timeout);
	bool processed (true);
	if (read > 0)
	{
		PreprocessTransfer(transfer, read);
	}
	else if (0 == read)
	{
		const int pkts (transfer->num_iso_packets);
		for (int i=0; i<pkts; ++i)
		{
			libusb_iso_packet_descriptor& desc (transfer->iso_packet_desc[i]);
			desc.actual_length = 0;
		}
	}
	else if (read < 0)
	{
		enum { ETIMEOUT = -116 };
		if (ETIMEOUT == read)
		{
			if (LIBUSB_TRANSFER_CANCELLED != transfer->status)
				processed = false;
		}
		else
		{
			libusb_cancel_transfer(transfer);
			processed = false;
		}
	}

	if (processed)
	{
		TListTransfers::Remove(wrapper);
		transfer->callback(transfer);
		if (read > 0)
			memset(transfer->buffer, 0, transfer->length);
	}

	return(read);
}
Esempio n. 26
0
void TransferPool::cancel()
{
  for(TransferQueue::iterator it = pending_transfers_.begin(); it != pending_transfers_.end(); ++it)
  {
    int r = libusb_cancel_transfer(*it);

    if(r != LIBUSB_SUCCESS)
    {
      // TODO: error reporting
    }
  }

  //idle_transfers_.insert(idle_transfers_.end(), pending_transfers_.begin(), pending_transfers_.end());
}
Esempio n. 27
0
void LibUsbDevice::closeDevice()
{
    if(isDeviceConnected)
    {
        if(usbDeviceToPcTransfer)
        {
            libusb_cancel_transfer(usbDeviceToPcTransfer);
        }
        if(pcToUsbDeviceTransfer)
        {
            libusb_cancel_transfer(pcToUsbDeviceTransfer);
        }
        enableEventThread = false;
        if(hasHotPlugSupport)
        {
//            libusb_hotplug_deregister_callback(context, hotplugHandle[0]);
//            libusb_hotplug_deregister_callback(context, hotplugHandle[1]);
        }
        future.waitForFinished();
        saveDeviceSettings();
        libusb_release_interface(deviceHandle, INTERFACE_NUMBER);
        libusb_close(deviceHandle);
        libusb_exit(context);
    }
    else if(isInitialiazed)
    {
        enableEventThread = false;
        if(hasHotPlugSupport)
        {
//            libusb_hotplug_deregister_callback(context, hotplugHandle[0]);
//            libusb_hotplug_deregister_callback(context, hotplugHandle[1]);
        }
        future.waitForFinished();
        libusb_exit(context);
    }

}
Esempio n. 28
0
USBInterface::~USBInterface()
{
  // cancel all transfer that might still be running
  for(Endpoints::iterator it = m_endpoints.begin(); it != m_endpoints.end(); ++it)
  {
    if (it->second)
    {
      libusb_cancel_transfer(it->second);
      libusb_free_transfer(it->second);
    }
  }
  m_endpoints.clear();

  libusb_release_interface(m_handle, m_interface);
}
Esempio n. 29
0
void
USBInterface::cancel_transfer(int endpoint)
{
  Endpoints::iterator it = m_endpoints.find(endpoint);
  if (it == m_endpoints.end())
  {
    raise_exception(std::runtime_error, "endpoint " << (endpoint & LIBUSB_ENDPOINT_ADDRESS_MASK) << "not found");
  }
  else
  {
    libusb_cancel_transfer(it->second);
    libusb_free_transfer(it->second);
    m_endpoints.erase(it);
  }
}
Esempio n. 30
0
File: uac.c Progetto: grpascal/GEO
/* Stop the audio capture by selecting the alternate settings 0 */
static int _mxuvc_audio_stop(audio_channel_t ch)
{
	int ret;
	unsigned int c=0, i;

	TRACE("Stopping audio\n");

	CHECK_ERROR(ch >= audio_num_channels, -1,
			"Unsupported channel number %d", ch);

	CHECK_ERROR(aud_started == 0, -1, "Unable to stop the audio: "
			"audio hasn't been started yet.");

	aud_started = 0;

	if(!audio_disconnected) {
		/* First try to wait for the transfer to complete instead of canceling them.
		 * Cancel the transfers if it takes more than 1 seconds for the transfers
		 * to complete.
		 * The reason why we don't directly cancel the transfers is that in ISOC
		 * mode, libusb sometimes seems to miss packets on other interfaces while
		 * transfers are being canceled on this interface */
		while(get_active_transfers()) {
			if(c >= 1000000) {
				for(i=0; i<num_transfers; i++)
					if(aud_cfg.xfers[i] != NULL)
						libusb_cancel_transfer(aud_cfg.xfers[i]);
			}
			usleep(3000);
			c+=3000;
		}

		/* Select alt settings 0 */
		ret = libusb_set_interface_alt_setting(audio_hdl,
				aud_cfg.interface, 0);
		CHECK_ERROR(ret < 0, -1,
				"Unable to stop the audio: could not set the "
				"alternate setting.");
	} else {
		while(get_active_transfers())
			usleep(3000);
	}

	TRACE("%u audio frames captured\n", aud_frame_count);
	aud_frame_count = 0;

	return 0;
}