Revision fe7df530 host/lib/transport/libusb1_zero_copy.cpp
| b/host/lib/transport/libusb1_zero_copy.cpp | ||
|---|---|---|
| 15 | 15 |
// along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 16 | 16 |
// |
| 17 | 17 |
|
| 18 |
|
|
| 18 |
#include "libusb1_base.hpp" |
|
| 19 | 19 |
#include <uhd/transport/usb_zero_copy.hpp> |
| 20 | 20 |
#include <uhd/utils/assert.hpp> |
| 21 |
#include <libusb-1.0/libusb.h> |
|
| 22 | 21 |
#include <boost/asio.hpp> |
| 23 | 22 |
#include <boost/format.hpp> |
| 24 | 23 |
#include <iostream> |
| ... | ... | |
| 26 | 25 |
|
| 27 | 26 |
using namespace uhd::transport; |
| 28 | 27 |
|
| 29 |
static int libusb_debug_level = 3; |
|
| 28 |
const int libusb_debug_level = 3; |
|
| 29 |
const int libusb_timeout = 0; |
|
| 30 | 30 |
|
| 31 | 31 |
/*********************************************************************** |
| 32 | 32 |
* Helper functions |
| ... | ... | |
| 347 | 347 |
std::cerr << "USB: transfer timed out" << std::endl; |
| 348 | 348 |
break; |
| 349 | 349 |
case LIBUSB_TRANSFER_STALL: |
| 350 |
std::cerr << "USB: halt condition detected (endpoint stalled)" << std::endl;
|
|
| 350 |
std::cerr << "USB: halt condition detected (stalled)" << std::endl; |
|
| 351 | 351 |
break; |
| 352 | 352 |
case LIBUSB_TRANSFER_ERROR: |
| 353 | 353 |
std::cerr << "USB: transfer failed" << std::endl; |
| ... | ... | |
| 606 | 606 |
libusb_device_handle *_rx_dev_handle; |
| 607 | 607 |
libusb_device_handle *_tx_dev_handle; |
| 608 | 608 |
|
| 609 |
int _rx_endpoint; |
|
| 610 |
int _tx_endpoint; |
|
| 611 |
|
|
| 612 | 609 |
size_t _recv_buff_size; |
| 613 | 610 |
size_t _send_buff_size; |
| 614 | 611 |
size_t _num_frames; |
| 615 | 612 |
|
| 616 |
bool open_device(uhd::usb_descriptor_t descriptor); |
|
| 617 |
bool open_interface(libusb_device_handle *dev_handle, int interface); |
|
| 618 |
bool compare_device(libusb_device *dev, uhd::usb_descriptor_t descriptor); |
|
| 619 |
|
|
| 620 |
std::string get_serial(libusb_device *dev); |
|
| 621 |
|
|
| 622 | 613 |
public: |
| 623 | 614 |
typedef boost::shared_ptr<libusb_zero_copy_impl> sptr; |
| 624 | 615 |
|
| 625 | 616 |
/* |
| 626 | 617 |
* Structors |
| 627 | 618 |
*/ |
| 628 |
libusb_zero_copy_impl(uhd::usb_descriptor_t descriptor,
|
|
| 619 |
libusb_zero_copy_impl(usb_device_handle::sptr handle,
|
|
| 629 | 620 |
unsigned int rx_endpoint, |
| 630 | 621 |
unsigned int tx_endpoint, |
| 631 | 622 |
size_t recv_buff_size, |
| ... | ... | |
| 641 | 632 |
}; |
| 642 | 633 |
|
| 643 | 634 |
|
| 644 |
libusb_zero_copy_impl::libusb_zero_copy_impl(uhd::usb_descriptor_t descriptor,
|
|
| 635 |
libusb_zero_copy_impl::libusb_zero_copy_impl(usb_device_handle::sptr handle,
|
|
| 645 | 636 |
unsigned int rx_endpoint, |
| 646 | 637 |
unsigned int tx_endpoint, |
| 647 | 638 |
size_t buff_size, |
| ... | ... | |
| 650 | 641 |
_recv_buff_size(block_size), _send_buff_size(block_size), |
| 651 | 642 |
_num_frames(buff_size / block_size) |
| 652 | 643 |
{
|
| 653 |
if (libusb_init(&_rx_ctx) < 0)
|
|
| 654 |
std::cerr << "error: libusb_init" << std::endl;
|
|
| 644 |
libusb::init(&_rx_ctx, libusb_debug_level);
|
|
| 645 |
libusb::init(&_tx_ctx, libusb_debug_level);
|
|
| 655 | 646 |
|
| 656 |
if (libusb_init(&_tx_ctx) < 0) |
|
| 657 |
std::cerr << "error: libusb_init" << std::endl; |
|
| 647 |
UHD_ASSERT_THROW((_rx_ctx != NULL) && (_tx_ctx != NULL)); |
|
| 658 | 648 |
|
| 659 |
libusb_set_debug(_rx_ctx, libusb_debug_level);
|
|
| 660 |
libusb_set_debug(_tx_ctx, libusb_debug_level);
|
|
| 649 |
_rx_dev_handle = libusb::open_device(_rx_ctx, handle);
|
|
| 650 |
_tx_dev_handle = libusb::open_device(_tx_ctx, handle);
|
|
| 661 | 651 |
|
| 662 |
open_device(descriptor); |
|
| 663 |
|
|
| 664 |
open_interface(_rx_dev_handle, 2); |
|
| 665 |
open_interface(_tx_dev_handle, 1); |
|
| 652 |
libusb::open_interface(_rx_dev_handle, 2); |
|
| 653 |
libusb::open_interface(_tx_dev_handle, 1); |
|
| 666 | 654 |
|
| 667 | 655 |
_rx_ep = new usb_endpoint(_rx_dev_handle, |
| 668 | 656 |
_rx_ctx, |
| ... | ... | |
| 693 | 681 |
} |
| 694 | 682 |
|
| 695 | 683 |
|
| 696 |
bool libusb_zero_copy_impl::open_device(uhd::usb_descriptor_t descriptor) |
|
| 697 |
{
|
|
| 698 |
libusb_device **rx_list; |
|
| 699 |
libusb_device **tx_list; |
|
| 700 |
|
|
| 701 |
bool rx_found = false; |
|
| 702 |
bool tx_found = false; |
|
| 703 |
|
|
| 704 |
ssize_t rx_cnt = libusb_get_device_list(_rx_ctx, &rx_list); |
|
| 705 |
ssize_t tx_cnt = libusb_get_device_list(_tx_ctx, &tx_list); |
|
| 706 |
|
|
| 707 |
if ((rx_cnt < 0) | (tx_cnt < 0) | (rx_cnt != tx_cnt)) |
|
| 708 |
return false; |
|
| 709 |
|
|
| 710 |
//find and open the receive device |
|
| 711 |
for (ssize_t i = 0; i < rx_cnt; i++) {
|
|
| 712 |
libusb_device *dev = rx_list[i]; |
|
| 713 |
|
|
| 714 |
if (compare_device(dev, descriptor)) {
|
|
| 715 |
libusb_open(dev, &_rx_dev_handle); |
|
| 716 |
rx_found = true; |
|
| 717 |
break; |
|
| 718 |
} |
|
| 719 |
} |
|
| 720 |
|
|
| 721 |
//find and open the transmit device |
|
| 722 |
for (ssize_t i = 0; i < tx_cnt; i++) {
|
|
| 723 |
libusb_device *dev = tx_list[i]; |
|
| 724 |
|
|
| 725 |
if (compare_device(dev, descriptor)) {
|
|
| 726 |
libusb_open(dev, &_tx_dev_handle); |
|
| 727 |
tx_found = true; |
|
| 728 |
} |
|
| 729 |
} |
|
| 730 |
|
|
| 731 |
libusb_free_device_list(rx_list, 0); |
|
| 732 |
libusb_free_device_list(tx_list, 0); |
|
| 733 |
|
|
| 734 |
if (tx_found && rx_found) |
|
| 735 |
return true; |
|
| 736 |
else |
|
| 737 |
return false; |
|
| 738 |
} |
|
| 739 |
|
|
| 740 |
bool libusb_zero_copy_impl::compare_device(libusb_device *dev, |
|
| 741 |
uhd::usb_descriptor_t descriptor) |
|
| 742 |
{
|
|
| 743 |
std::string serial = descriptor.serial; |
|
| 744 |
boost::uint16_t vendor_id = descriptor.vendor_id; |
|
| 745 |
boost::uint16_t product_id = descriptor.product_id; |
|
| 746 |
boost::uint8_t device_addr = descriptor.device_addr; |
|
| 747 |
|
|
| 748 |
libusb_device_descriptor desc; |
|
| 749 |
libusb_get_device_descriptor(dev, &desc); |
|
| 750 |
|
|
| 751 |
if (serial.compare(get_serial(dev))) |
|
| 752 |
return false; |
|
| 753 |
if (vendor_id != desc.idVendor) |
|
| 754 |
return false; |
|
| 755 |
if (product_id != desc.idProduct) |
|
| 756 |
return false; |
|
| 757 |
if (device_addr != libusb_get_device_address(dev)) |
|
| 758 |
return false; |
|
| 759 |
|
|
| 760 |
return true; |
|
| 761 |
} |
|
| 762 |
|
|
| 763 |
bool libusb_zero_copy_impl::open_interface(libusb_device_handle *dev_handle, |
|
| 764 |
int interface) |
|
| 765 |
{
|
|
| 766 |
int ret = libusb_claim_interface(dev_handle, interface); |
|
| 767 |
if (ret < 0) {
|
|
| 768 |
std::cerr << "error: libusb_claim_interface() " << ret << std::endl; |
|
| 769 |
return false; |
|
| 770 |
} |
|
| 771 |
else {
|
|
| 772 |
return true; |
|
| 773 |
} |
|
| 774 |
} |
|
| 775 |
|
|
| 776 |
std::string libusb_zero_copy_impl::get_serial(libusb_device *dev) |
|
| 777 |
{
|
|
| 778 |
unsigned char buff[32]; |
|
| 779 |
|
|
| 780 |
libusb_device_descriptor desc; |
|
| 781 |
if (libusb_get_device_descriptor(dev, &desc) < 0) {
|
|
| 782 |
std::cerr << "error: libusb_get_device_descriptor()" << std::endl; |
|
| 783 |
return ""; |
|
| 784 |
} |
|
| 785 |
|
|
| 786 |
if (desc.iSerialNumber == 0) |
|
| 787 |
return ""; |
|
| 788 |
|
|
| 789 |
//open the device because we have to |
|
| 790 |
libusb_device_handle *dev_handle; |
|
| 791 |
if (libusb_open(dev, &dev_handle) < 0) {
|
|
| 792 |
return ""; |
|
| 793 |
} |
|
| 794 |
|
|
| 795 |
if (libusb_get_string_descriptor_ascii(dev_handle, desc.iSerialNumber, |
|
| 796 |
buff, sizeof(buff)) < 0) {
|
|
| 797 |
std::cerr << "error: libusb_get_string_descriptor_ascii()" << std::endl; |
|
| 798 |
return ""; |
|
| 799 |
} |
|
| 800 |
|
|
| 801 |
libusb_close(dev_handle); |
|
| 802 |
|
|
| 803 |
return (char*) buff; |
|
| 804 |
} |
|
| 805 |
|
|
| 806 |
|
|
| 807 | 684 |
managed_recv_buffer::sptr libusb_zero_copy_impl::get_recv_buff() |
| 808 | 685 |
{
|
| 809 | 686 |
libusb_transfer *lut = _rx_ep->get_completed_transfer(); |
| ... | ... | |
| 836 | 713 |
/*********************************************************************** |
| 837 | 714 |
* USB zero_copy make functions |
| 838 | 715 |
**********************************************************************/ |
| 839 |
usb_zero_copy::sptr usb_zero_copy::make(uhd::usb_descriptor_t descriptor,
|
|
| 716 |
usb_zero_copy::sptr usb_zero_copy::make(usb_device_handle::sptr handle,
|
|
| 840 | 717 |
unsigned int rx_endpoint, |
| 841 | 718 |
unsigned int tx_endpoint, |
| 842 | 719 |
size_t buff_size, |
| 843 | 720 |
size_t block_size) |
| 844 | 721 |
|
| 845 | 722 |
{
|
| 846 |
return sptr(new libusb_zero_copy_impl(descriptor,
|
|
| 723 |
return sptr(new libusb_zero_copy_impl(handle,
|
|
| 847 | 724 |
rx_endpoint, |
| 848 | 725 |
tx_endpoint, |
| 849 | 726 |
buff_size, |
Also available in: Unified diff