/** @file ConnectionSTREAMEntry.cpp @author Lime Microsystems @brief Implementation of STREAM board connection. */ #include "ConnectionSTREAM.h" #include "Logger.h" using namespace lime; #ifdef __unix__ void ConnectionSTREAMEntry::handle_libusb_events() { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 250000; while(mProcessUSBEvents.load() == true) { int r = libusb_handle_events_timeout_completed(ctx, &tv, NULL); if(r != 0) lime::error("error libusb_handle_events %s", libusb_strerror(libusb_error(r))); } } #endif // __UNIX__ //! make a static-initialized entry in the registry void __loadConnectionSTREAMEntry(void) //TODO fixme replace with LoadLibrary/dlopen { static ConnectionSTREAMEntry STREAMEntry; } int USBTransferContext::idCounter = 0; ConnectionSTREAMEntry::ConnectionSTREAMEntry(void): ConnectionRegistryEntry("STREAM") { #ifdef __unix__ int r = libusb_init(&ctx); //initialize the library for the session we just declared if(r < 0) lime::error("Init Error %i", r); //there was an error libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation mProcessUSBEvents.store(true); mUSBProcessingThread = std::thread(&ConnectionSTREAMEntry::handle_libusb_events, this); #endif } ConnectionSTREAMEntry::ConnectionSTREAMEntry(const std::string entryName): ConnectionRegistryEntry(entryName) { #ifdef __unix__ int r = libusb_init(&ctx); //initialize the library for the session we just declared if(r < 0) lime::error("Init Error %i", r); //there was an error libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation mProcessUSBEvents.store(true); mUSBProcessingThread = std::thread(&ConnectionSTREAMEntry::handle_libusb_events, this); #endif } ConnectionSTREAMEntry::~ConnectionSTREAMEntry(void) { #ifdef __unix__ mProcessUSBEvents.store(false); mUSBProcessingThread.join(); libusb_exit(ctx); #endif } #ifndef __unix__ /** @return name of usb device as string. @param index device index in list */ std::string ConnectionSTREAMEntry::DeviceName(unsigned int index) { std::string name; char tempName[USB_STRING_MAXLEN]; CCyUSBDevice device; if (index >= device.DeviceCount()) return ""; for (int i = 0; i < USB_STRING_MAXLEN; ++i) tempName[i] = device.DeviceName[i]; if (device.bSuperSpeed == true) name = "USB 3.0"; else if (device.bHighSpeed == true) name = "USB 2.0"; else name = "USB"; name += " ("; name += tempName; name += ")"; return name; } #endif std::vector ConnectionSTREAMEntry::enumerate(const ConnectionHandle &hint) { std::vector handles; #ifndef __unix__ CCyUSBDevice device; if (device.DeviceCount()) { for (int i = 0; i= 0 && hint.index != i) continue; if (device.IsOpen()) device.Close(); device.Open(i); ConnectionHandle handle; handle.media = "USB"; handle.name = DeviceName(i); handle.index = i; std::wstring ws(device.SerialNumber); handle.serial = std::string(ws.begin(),ws.end()); if (hint.serial.empty() or hint.serial == handle.serial) { handles.push_back(handle); //filter on serial } device.Close(); } } #else libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices int usbDeviceCount = libusb_get_device_list(ctx, &devs); if (usbDeviceCount < 0) { lime::error("failed to get libusb device list: %s", libusb_strerror(libusb_error(usbDeviceCount))); return handles; } for(int i=0; i 0) handle.name = std::string(data, size_t(r)); r = std::sprintf(data, "%.4x:%.4x", int(vid), int(pid)); if (r > 0) handle.addr = std::string(data, size_t(r)); if (desc.iSerialNumber > 0) { r = libusb_get_string_descriptor_ascii(tempDev_handle,desc.iSerialNumber,(unsigned char*)data, sizeof(data)); if(r<0) lime::error("failed to get serial number"); else handle.serial = std::string(data, size_t(r)); } libusb_close(tempDev_handle); //add handle conditionally, filter by serial number if (hint.serial.empty() or hint.serial == handle.serial) { handles.push_back(handle); } } } libusb_free_device_list(devs, 1); #endif return handles; } IConnection *ConnectionSTREAMEntry::make(const ConnectionHandle &handle) { return new ConnectionSTREAM(ctx, handle.addr, handle.serial, handle.index); }