usb_device_si.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. This software is subject to the license described in the License.txt file
  3. included with this software distribution. You may not use this file except
  4. in compliance with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2016
  6. All rights reserved.
  7. */
  8. #include "types.h"
  9. #if defined(DSI_TYPES_WINDOWS)
  10. #if defined(_MSC_VER)
  11. #include "WinDevice.h"
  12. #endif
  13. #include "usb_device_si.hpp"
  14. #include "macros.h"
  15. #include <windows.h>
  16. #include <memory>
  17. using namespace std;
  18. USBDeviceSI::USBDeviceSI(UCHAR ucDeviceNumber_)
  19. :
  20. ucDeviceNumber(ucDeviceNumber_),
  21. usVid(0),
  22. usPid(0),
  23. ulSerialNumber(0)
  24. {
  25. //initialize array
  26. szProductDescription[0] = '\0';
  27. szSerialString[0] = '\0';
  28. auto_ptr<const SiLabsLibrary> pclAutoSiLibrary(NULL);
  29. if(SiLabsLibrary::Load(pclAutoSiLibrary) == FALSE)
  30. return;
  31. const SiLabsLibrary& clSiLibrary = *pclAutoSiLibrary;
  32. char acTempString[SI_MAX_DEVICE_STRLEN];
  33. //Get device VID
  34. if(clSiLibrary.GetProductString(ucDeviceNumber_, acTempString, SI_RETURN_VID) == SI_SUCCESS)
  35. {
  36. usVid = (USHORT)strtoul(acTempString, NULL, 16);
  37. }
  38. else
  39. usVid = 0;
  40. //Get device PID
  41. if(clSiLibrary.GetProductString(ucDeviceNumber_, acTempString, SI_RETURN_PID) == SI_SUCCESS)
  42. {
  43. usPid = (USHORT)strtoul(acTempString, NULL, 16);
  44. }
  45. else
  46. usPid = 0;
  47. if(clSiLibrary.GetProductString(ucDeviceNumber_, szSerialString, SI_RETURN_SERIAL_NUMBER) == SI_SUCCESS)
  48. {
  49. USBDeviceSI::GetDeviceSerialNumber(ulSerialNumber);
  50. }
  51. else
  52. {
  53. szSerialString[0] = '\0';
  54. ulSerialNumber = 0;
  55. }
  56. if(clSiLibrary.GetProductString(ucDeviceNumber_, szProductDescription, SI_RETURN_DESCRIPTION) == SI_SUCCESS) //!!null terminated?
  57. {
  58. }
  59. else
  60. {
  61. szProductDescription[0] = '\0';
  62. }
  63. /*
  64. if(clSiLibrary.GetProductString(ucDeviceNumber_, acTempString, SI_RETURN_LINK_NAME) != SI_SUCCESS)
  65. {
  66. szLinkName[0] = '\0';
  67. }
  68. */
  69. /* //!!What do these give us?
  70. CP210x_RETURN_SERIAL_NUMBER 0x00
  71. CP210x_RETURN_DESCRIPTION 0x01
  72. CP210x_RETURN_FULL_PATH 0x02
  73. */
  74. return;
  75. }
  76. USBDeviceSI::USBDeviceSI(const USBDeviceSI& clDevice_)
  77. :
  78. ucDeviceNumber(clDevice_.ucDeviceNumber),
  79. usVid(clDevice_.usVid),
  80. usPid(clDevice_.usPid),
  81. ulSerialNumber(clDevice_.ulSerialNumber)
  82. {
  83. STRNCPY((char*)szProductDescription, (char*)clDevice_.szProductDescription, sizeof(szProductDescription));
  84. memcpy(szSerialString, clDevice_.szSerialString, sizeof(szSerialString));
  85. return;
  86. }
  87. USBDeviceSI& USBDeviceSI::operator=(const USBDeviceSI& clDevice_)
  88. {
  89. if(this == &clDevice_)
  90. return *this;
  91. ucDeviceNumber = clDevice_.ucDeviceNumber;
  92. usVid = clDevice_.usVid;
  93. usPid = clDevice_.usPid;
  94. ulSerialNumber = clDevice_.ulSerialNumber;
  95. STRNCPY((char*)szProductDescription, (char*)clDevice_.szProductDescription, sizeof(szProductDescription));
  96. memcpy(szSerialString, clDevice_.szSerialString, sizeof(szSerialString));
  97. return *this;
  98. }
  99. BOOL USBDeviceSI::GetProductDescription(UCHAR* pucProductDescription_, USHORT usBufferSize_) const
  100. {
  101. return(STRNCPY((char*) pucProductDescription_, (char*) szProductDescription, usBufferSize_));
  102. }
  103. BOOL USBDeviceSI::GetSerialString(UCHAR* pucSerialString_, USHORT usBufferSize_) const
  104. {
  105. if(sizeof(szSerialString) > usBufferSize_)
  106. {
  107. memcpy(pucSerialString_, szSerialString, usBufferSize_);
  108. return FALSE;
  109. }
  110. memcpy(pucSerialString_, szSerialString, sizeof(szSerialString));
  111. return TRUE;
  112. }
  113. BOOL USBDeviceSI::USBReset() const //!!make static?
  114. {
  115. #if defined(_MSC_VER)
  116. // !! Borland builder chokes on cfgmgr32
  117. TCHAR line1[64];
  118. TCHAR* argv_[2];
  119. //Only do the soft reset if we fail to open a device or it seems like theres no devices to open (device in a "hosed" state)
  120. //The soft reset will have no effect on devices currently opened by other applications.
  121. argv_[0] = line1;
  122. SNPRINTF(&(line1[0]),sizeof(line1), "@USB\\VID_%04X&PID_%04X\\*", usVid, usPid);
  123. WinDevice_Disable(1,argv_);
  124. WinDevice_Enable(1,argv_);
  125. #endif
  126. return TRUE;
  127. }
  128. //The serial number actually is not limited to a ULONG by USB specs,
  129. //so, our range here is determined by whatever we do in our products.
  130. //For now we have it defined as 1 to (ULONG_MAX-1)
  131. BOOL USBDeviceSI::GetDeviceSerialNumber(ULONG& ulSerialNumber_)
  132. {
  133. ULONG ulSerial = strtoul((char*)szSerialString, NULL, 10);
  134. if(ulSerial == 0 || ulSerial == ULONG_MAX)
  135. return FALSE;
  136. if((ulSerial > 10000) && (ulSerial < 10255)) //The real serial number is kept in the string
  137. memcpy(&ulSerial, &(szSerialString[56]), 4);
  138. ulSerialNumber_ = ulSerial;
  139. return TRUE;
  140. }
  141. #endif //defined(DSI_TYPES_WINDOWS)