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