Revision fe7df530 host/lib/transport/libusb1_control.cpp

b/host/lib/transport/libusb1_control.cpp
15 15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16
//
17 17

  
18
#include <uhd/types/usb_descriptor.hpp>
18
#include "libusb1_base.hpp"
19 19
#include <uhd/transport/usb_control.hpp>
20
#include <libusb-1.0/libusb.h>
21
#include <boost/asio.hpp>
22
#include <stdexcept>
23
#include <iostream>
24 20

  
25 21
using namespace uhd::transport;
26 22

  
27
static int libusb_debug_level = 0;
28
static int libusb_timeout = 0;
23
const int libusb_debug_level = 3;
24
const int libusb_timeout = 0;
29 25

  
30 26
/***********************************************************************
31 27
 * libusb-1.0 implementation of USB control transport
32 28
 **********************************************************************/
33 29
class libusb_control_impl : public usb_control {
34 30
public:
35
    libusb_control_impl(uhd::usb_descriptor_t descriptor);
31
    libusb_control_impl(usb_device_handle::sptr handle);
36 32
    ~libusb_control_impl();
37 33

  
38 34
    size_t submit(boost::uint8_t request_type,
......
42 38
                  unsigned char *buff,
43 39
                  boost::uint16_t length); 
44 40

  
45
    static uhd::usb_descriptor_t create_descriptor(libusb_device *dev);
46
    static std::string get_serial(libusb_device *dev);
47

  
48 41
private:
49
    uhd::usb_descriptor_t _descriptor;
50

  
51 42
    libusb_context       *_ctx;
52 43
    libusb_device_handle *_dev_handle;
53

  
54
    bool open_device();
55
    bool open_interface();
56
    bool compare_device(libusb_device *dev, uhd::usb_descriptor_t descriptor);
57 44
};
58 45

  
59 46

  
60
libusb_control_impl::libusb_control_impl(uhd::usb_descriptor_t descriptor)
61
 :  _descriptor(descriptor), _ctx(NULL), _dev_handle(NULL)
47
libusb_control_impl::libusb_control_impl(usb_device_handle::sptr handle)
62 48
{
63
    if (libusb_init(&_ctx) < 0)
64
        throw std::runtime_error("USB: failed to initialize libusb");
49
    libusb::init(&_ctx, libusb_debug_level);
65 50

  
66
    libusb_set_debug(_ctx, libusb_debug_level);
51
    _dev_handle = libusb::open_device(_ctx, handle);
67 52

  
68
    if (!open_device())
69
        throw std::runtime_error("USB: failed to open device");
70

  
71
    if (!open_interface())
72
        throw std::runtime_error("USB: failed to open device interface");
53
    libusb::open_interface(_dev_handle, 0);
73 54
}
74 55

  
75 56

  
......
80 61
}
81 62

  
82 63

  
83
uhd::usb_descriptor_t libusb_control_impl::create_descriptor(libusb_device *dev)
84
{
85
    libusb_device_descriptor desc;
86

  
87
    if (libusb_get_device_descriptor(dev, &desc) < 0)
88
        throw std::runtime_error("USB: failed to get device descriptor");
89

  
90
    uhd::usb_descriptor_t descriptor;
91

  
92
    descriptor.serial      = get_serial(dev); 
93
    descriptor.product_id  = desc.idProduct;   
94
    descriptor.vendor_id   = desc.idVendor;
95
    descriptor.device_addr = libusb_get_device_address(dev);
96

  
97
    return descriptor;
98
}
99

  
100

  
101
std::string libusb_control_impl::get_serial(libusb_device *dev)
102
{
103
    unsigned char buff[32];
104

  
105
    libusb_device_descriptor desc;
106
    if (libusb_get_device_descriptor(dev, &desc) < 0)
107
        return "";
108

  
109
    if (desc.iSerialNumber == 0)
110
        return "";
111

  
112
    //open the device because we have to
113
    libusb_device_handle *dev_handle;
114
    if (libusb_open(dev, &dev_handle) < 0)
115
        return "";
116

  
117
    if (libusb_get_string_descriptor_ascii(dev_handle, desc.iSerialNumber,
118
                                           buff, sizeof(buff)) < 0) {
119
        return "";
120
    }
121

  
122
    libusb_close(dev_handle);
123

  
124
    return (char*) buff;
125
}
126

  
127

  
128
bool libusb_control_impl::open_device()
129
{
130
    libusb_device **list;
131
    libusb_device *dev;
132

  
133
    ssize_t cnt = libusb_get_device_list(_ctx, &list);
134

  
135
    if (cnt < 0)
136
        return cnt;
137

  
138
    ssize_t i = 0;
139
    for (i = 0; i < cnt; i++) {
140
        dev = list[i];
141
        if (compare_device(dev, _descriptor))
142
            goto found;
143
    } 
144
    return false;
145

  
146
found:
147
    int ret;
148
    if ((ret = libusb_open(dev, &_dev_handle)) < 0)
149
        return false;
150
    else 
151
        return true;
152
}
153

  
154

  
155
bool libusb_control_impl::compare_device(libusb_device *dev,
156
                                         uhd::usb_descriptor_t descriptor)
157
{
158
    std::string serial         = descriptor.serial;
159
    boost::uint16_t vendor_id  = descriptor.vendor_id;
160
    boost::uint16_t product_id = descriptor.product_id;
161
    boost::uint8_t device_addr = descriptor.device_addr;
162

  
163
    libusb_device_descriptor libusb_desc;
164
    if (libusb_get_device_descriptor(dev, &libusb_desc) < 0)
165
        return false;
166
    if (serial != get_serial(dev))
167
        return false;
168
    if (vendor_id != libusb_desc.idVendor)
169
        return false;
170
    if (product_id != libusb_desc.idProduct)
171
        return false; 
172
    if (device_addr != libusb_get_device_address(dev))
173
        return false;
174

  
175
    return true;
176
}
177

  
178

  
179
bool libusb_control_impl::open_interface()
180
{
181
    if (libusb_claim_interface(_dev_handle, 0) < 0)
182
        return false;
183
    else
184
        return true;
185
}
186

  
187

  
188 64
size_t libusb_control_impl::submit(boost::uint8_t request_type,
189 65
                                   boost::uint8_t request,
190 66
                                   boost::uint16_t value,
......
206 82
/***********************************************************************
207 83
 * USB control public make functions
208 84
 **********************************************************************/
209
usb_control::sptr usb_control::make(uhd::usb_descriptor_t descriptor)
85
usb_control::sptr usb_control::make(usb_device_handle::sptr handle)
210 86
{
211
    return sptr(new libusb_control_impl(descriptor));
87
    return sptr(new libusb_control_impl(handle));
212 88
}
213

  
214
uhd::usb_descriptors_t usb_control::get_device_list()
215
{
216
    libusb_device **list;
217
    uhd::usb_descriptors_t descriptors;
218

  
219
    if (libusb_init(NULL) < 0)
220
        throw std::runtime_error("USB: failed to initialize libusb");
221

  
222
    ssize_t cnt = libusb_get_device_list(NULL, &list);
223

  
224
    if (cnt < 0)
225
        throw std::runtime_error("USB: failed to get device list");
226

  
227
    ssize_t i = 0;
228
    for (i = 0; i < cnt; i++) {
229
        libusb_device *dev = list[i];
230
        descriptors.push_back(libusb_control_impl::create_descriptor(dev));
231
    } 
232

  
233
    libusb_free_device_list(list, 0);
234
    libusb_exit(NULL);
235
    return descriptors;
236
}
237

  
238

  

Also available in: Unified diff