gccDppConsole Test C++ SDK  20170920
DPP C++ Console Demonstration
DeviceIO/DppLibUsb.cpp
Go to the documentation of this file.
00001 #include "DppLibUsb.h"
00002 
00003 CDppLibUsb::CDppLibUsb(void)
00004 {
00005 
00006 }
00007 CDppLibUsb::~CDppLibUsb(void)
00008 {
00009 
00010 }
00011 
00012 // InitializeLibusb must be call before any other libusb operations
00013 int CDppLibUsb::InitializeLibusb()
00014 {
00015         int iStatus=0;
00016         iStatus = libusb_init(NULL);
00017         if (iStatus != 0) {
00018                 fprintf(stderr, "Unable to initialize libusb. %s\n", libusb_strerror((libusb_error)iStatus));
00019         }
00020         return iStatus;
00021 }
00022 
00023 // DeinitializeLibusb must be called after all libusb operations 
00024 // have been completed and all devices/lists are closed
00025 void CDppLibUsb::DeinitializeLibusb()
00026 {
00027         libusb_exit(NULL);
00028 }
00029 
00030 // devices start at 1
00031 // Do only when no devices are connected
00032 libusb_device_handle * CDppLibUsb::FindUSBDevice(int idxAmptekDevice)
00033 {
00034         struct libusb_device **devs;
00035         struct libusb_device *found = NULL;
00036         struct libusb_device_handle *handle = NULL;
00037         struct libusb_device_descriptor desc;
00038         struct libusb_device *device = NULL;
00039         ssize_t devcnt = 0;
00040         ssize_t iDev = 0;
00041         int r;
00042         int idxDev=1;
00043 
00044         bDeviceConnected = false;
00045         devcnt = libusb_get_device_list(NULL, &devs);
00046         if (devcnt < 0) {
00047                 fprintf(stderr, "failed to get device list");
00048                 return NULL;
00049         }
00050         for (iDev = 0; iDev < devcnt; iDev++) {
00051                 device = devs[iDev];
00052                 int r = libusb_get_device_descriptor (device, &desc);
00053                 if (r < 0) {
00054                         fprintf(stderr, libusb_strerror((libusb_error)r));
00055                         goto out;
00056                         //continue;
00057                 }
00058                 if (isAmptekDP5Device(desc)) {
00059                         if (idxAmptekDevice==idxDev) {
00060                                 found = device;
00061                                 break;
00062                         } else {        // inc counter to next device
00063                                 idxDev++;
00064                         }
00065                 }
00066         }
00067         if (found) {
00068                 r = libusb_open(found, &handle);
00069                 if (r < 0) {
00070                         fprintf(stderr, libusb_strerror((libusb_error)r));
00071                         handle = NULL;
00072                 } else {
00073                         if (handle != NULL) {
00074                                 r = libusb_claim_interface(handle, INTERFACE_NUMBER);
00075                                 if (r >= 0) {
00076                                         bDeviceConnected = true; // have interface
00077                                 } else {
00078                                         fprintf(stderr, "libusb_claim_interface error %s\n", libusb_strerror((libusb_error)r));
00079                                 }
00080                         } else {
00081                                 fprintf(stderr, "Unable to find a dpp device.\n");
00082                         }
00083                 }
00084         }
00085 
00086 out:
00087         libusb_free_device_list(devs, 1);
00088         return handle;
00089 }
00090 
00091 void CDppLibUsb::CloseUSBDevice(libusb_device_handle * devh) 
00092 {
00093         int r;
00094         if (devh != NULL) {
00095                 r = libusb_release_interface(devh, INTERFACE_NUMBER);
00096                 if (r < 0) {
00097                         fprintf(stderr, "libusb_release_interface error %s\n", libusb_strerror((libusb_error)r));
00098                 }
00099                 libusb_close(devh);
00100         }
00101 }
00102 
00103 int CDppLibUsb::SendPacketUSB(libusb_device_handle *devh, unsigned char data_out[], unsigned char data_in[])
00104 {
00105         int bytes_transferred;
00106         unsigned int timeout = 5000;
00107         int result = 0;
00108         int length = 0; 
00109         
00110         if ((data_out[2] == PID1_REQ_SCOPE_MISC_TO) && data_out[3] == PID2_SEND_DIAGNOSTIC_DATA_TO) {
00111                 timeout = DP5_DIAGDATA_TIMEOUT;
00112         } else {
00113                 timeout = DP5_USB_TIMEOUT;
00114         }
00115 
00116         length = data_out[4];
00117         length *= 256;
00118         length += data_out[5];
00119         length += 8;
00120 
00121         result = libusb_bulk_transfer(devh, BULK_OUT_ENDPOINT, data_out, length, &bytes_transferred, timeout);
00122         if (result >= 0) {
00123                 result = libusb_bulk_transfer(devh, BULK_IN_ENDPOINT, data_in, MAX_BULK_IN_TRANSFER_SIZE, &bytes_transferred, timeout);
00124                 if (result >= 0) {
00125                         if (bytes_transferred > 0) {
00126                                 return bytes_transferred;
00127                         } else {
00128                                 fprintf(stderr, "No data received in bulk transfer (%d)\n", result);
00129                                 return -1;
00130                         }
00131                 } else {
00132                         fprintf(stderr, "Error receiving data via bulk transfer %d\n", result);
00133                         return result;
00134                 }
00135         } else {
00136                 fprintf(stderr, "Error sending data via bulk transfer %d\n", result);
00137                 return result;
00138         }
00139         return 0;
00140  }
00141 
00142 bool CDppLibUsb::isAmptekDP5Device(libusb_device_descriptor desc)
00143 {
00144         bool isDevice=false;
00145         if ((desc.idVendor == AMPTEK_DP5_VENDOR_ID) && (desc.idProduct == AMPTEK_DP5_PRODUCT_ID))
00146         {
00147                 isDevice=true;
00148         }
00149         return isDevice;
00150 }
00151 
00152 // Counts number of dpp devices
00153 // Do only when no devices are connected
00154 int CDppLibUsb::CountDP5LibusbDevices()
00155 {
00156         libusb_device **devs;
00157         int iDppCount=0;
00158 
00159         ssize_t cnt = libusb_get_device_list (NULL, &devs); 
00160         if (cnt < 0)
00161                 return (-1);
00162         int nr = 0, i = 0;
00163         struct libusb_device_descriptor desc;
00164         for (i = 0; i < cnt; ++i)
00165         {
00166                 int r = libusb_get_device_descriptor (devs[i], &desc);
00167                 if (r != 0) {
00168                         fprintf(stderr, libusb_strerror((libusb_error)r));
00169                         continue;
00170                 }
00171                 if (isAmptekDP5Device(desc)) { nr++; }
00172         }
00173         libusb_free_device_list (devs, 1);
00174         iDppCount = (int)nr;
00175         return iDppCount;
00176 }
00177 
00178 // Do only when no devices are connected
00179 void CDppLibUsb::PrintDevices()
00180 {
00181         struct libusb_device **devs;
00182         struct libusb_device *dev = NULL;
00183         int i = 0;
00184         ssize_t cnt = 0;
00185 
00186         cnt = libusb_get_device_list(NULL, &devs);
00187         if (cnt < 0) {
00188                 fprintf(stderr, "failed to get device list");
00189                 return;
00190         }
00191 
00192         while ((dev = devs[i++]) != NULL) {
00193                 struct libusb_device_descriptor desc;
00194                 int r = libusb_get_device_descriptor(dev, &desc);
00195                 if (r < 0) {
00196                         fprintf(stderr, "device descriptor error: %s", libusb_strerror((libusb_error)r));
00197                         return;
00198                 }
00199                 if (isAmptekDP5Device(desc)) {
00200                         printf("%04x:%04x (bus %d, device %d)\n", desc.idVendor, desc.idProduct, libusb_get_bus_number(dev), libusb_get_device_address(dev));
00201                 }
00202         }
00203         libusb_free_device_list(devs, 1);
00204 }
00205 
00206 #ifndef LIBUSB_WINUSB_BACKEND
00207 const char * CDppLibUsb::libusb_strerror(enum libusb_error error_code)
00208 {
00209         switch (error_code) {
00210         case LIBUSB_SUCCESS:
00211                 return "Success";
00212         case LIBUSB_ERROR_IO:
00213                 return "Input/output error";
00214         case LIBUSB_ERROR_INVALID_PARAM:
00215                 return "Invalid parameter";
00216         case LIBUSB_ERROR_ACCESS:
00217                 return "Access denied (insufficient permissions)";
00218         case LIBUSB_ERROR_NO_DEVICE:
00219                 return "No such device (it may have been disconnected)";
00220         case LIBUSB_ERROR_NOT_FOUND:
00221                 return "Entity not found";
00222         case LIBUSB_ERROR_BUSY:
00223                 return "Resource busy";
00224         case LIBUSB_ERROR_TIMEOUT:
00225                 return "Operation timed out";
00226         case LIBUSB_ERROR_OVERFLOW:
00227                 return "Overflow";
00228         case LIBUSB_ERROR_PIPE:
00229                 return "Pipe error";
00230         case LIBUSB_ERROR_INTERRUPTED:
00231                 return "System call interrupted (perhaps due to signal)";
00232         case LIBUSB_ERROR_NO_MEM:
00233                 return "Insufficient memory";
00234         case LIBUSB_ERROR_NOT_SUPPORTED:
00235                 return "Operation not supported or unimplemented on this platform";
00236         case LIBUSB_ERROR_OTHER:
00237                 return "Other error";
00238         }
00239         return "Unknown error";
00240 }
00241 #endif