static int linux_rx(struct bladerf *dev, bladerf_format format, void *samples, int n, struct bladerf_metadata *metadata) { ssize_t i, ret = 0; size_t bytes_read = 0; const size_t bytes_total = c16_samples_to_bytes(n); struct bladerf_linux *backend = (struct bladerf_linux *)dev->backend; int8_t *samples8 = (int8_t *)samples; while (bytes_read < bytes_total) { i = read(backend->fd, samples8 + bytes_read, bytes_total - bytes_read); if (i < 0 && errno != EINTR) { int errno_val = errno; bladerf_set_error(&dev->error, ETYPE_ERRNO, errno_val); ret = BLADERF_ERR_IO; log_error("Read failed with errno=%d: %s\n", errno_val, strerror(errno_val)); break; } else if (i > 0) { bytes_read += i; } } if (ret < 0) { return ret; } else { return bytes_to_c16_samples(bytes_read); } }
/* Precondition: A transfer is available. */ static int submit_transfer(struct bladerf_stream *stream, void *buffer) { int status; struct bladerf_lusb *lusb = lusb_backend(stream->dev); struct lusb_stream_data *stream_data = stream->backend_data; struct libusb_transfer *transfer; size_t bytes_per_buffer; const unsigned char ep = stream->module == BLADERF_MODULE_TX ? SAMPLE_EP_OUT : SAMPLE_EP_IN; assert(stream_data->transfer_status[stream_data->i] == TRANSFER_AVAIL); transfer = stream_data->transfers[stream_data->i]; switch (stream->format) { case BLADERF_FORMAT_SC16_Q11: bytes_per_buffer = c16_samples_to_bytes(stream->samples_per_buffer); break; default: assert(!"Unexpected format"); return BLADERF_ERR_INVAL; } assert(bytes_per_buffer <= INT_MAX); libusb_fill_bulk_transfer(transfer, lusb->handle, ep, buffer, (int)bytes_per_buffer, lusb_stream_cb, stream, stream->dev->transfer_timeout[stream->module]); status = libusb_submit_transfer(transfer); if (status == 0) { stream_data->transfer_status[stream_data->i] = TRANSFER_IN_FLIGHT; stream_data->i = (stream_data->i + 1) % stream_data->num_transfers; assert(stream_data->num_avail_transfers != 0); stream_data->num_avail_transfers--; } else { log_error("Failed to submit transfer in %s: %s\n", __FUNCTION__, libusb_error_name(status)); } return error_conv(status); }