PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/libusbK/bindings/examples_csharp/TestParameters.cs

http://usb-travis.googlecode.com/
C# | 540 lines | 446 code | 63 blank | 31 comment | 50 complexity | b38491f7835fdef5d2e23aa582926147 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, LGPL-2.0
  1. #region Copyright(c) Travis Robinson
  2. // Copyright (c) 2012 Travis Robinson <libusbdotnet@gmail.com>
  3. // All rights reserved.
  4. //
  5. // TestParameters.cs
  6. //
  7. // Created: 03.05.2012
  8. // Last Updated: 03.05.2012
  9. //
  10. // Redistribution and use in source and binary forms, with or without
  11. // modification, are permitted provided that the following conditions are met:
  12. //
  13. // * Redistributions of source code must retain the above copyright
  14. // notice, this list of conditions and the following disclaimer.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  17. // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  18. // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  19. // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL TRAVIS LEE ROBINSON
  20. // BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  24. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  26. // THE POSSIBILITY OF SUCH DAMAGE.
  27. #endregion
  28. using System;
  29. using System.Globalization;
  30. using System.IO;
  31. using System.Runtime.InteropServices;
  32. using System.Text.RegularExpressions;
  33. using Win32;
  34. namespace libusbK.Examples
  35. {
  36. internal abstract class TestParameters
  37. {
  38. protected TestParameters(int vid,
  39. int pid,
  40. int altInterfaceId,
  41. int pipeId,
  42. int maxTransfersTotal,
  43. string logFilename)
  44. {
  45. MI = -1;
  46. ;
  47. Vid = vid;
  48. Pid = pid;
  49. PipeId = pipeId;
  50. AltInterfaceId = altInterfaceId;
  51. MaxTransfersTotal = maxTransfersTotal;
  52. LogFilename = logFilename;
  53. }
  54. #region Public Members
  55. public int AltInterfaceId;
  56. public bool ConfigureDevice(out WINUSB_PIPE_INFORMATION pipeInfo,
  57. out UsbK usb,
  58. out USB_INTERFACE_DESCRIPTOR interfaceDescriptor)
  59. {
  60. bool success;
  61. Console.WriteLine("Finding usb device by VID/PID.. ({0:X4}h / {1:X4}h)",
  62. Vid,
  63. Pid);
  64. // Use a patttern match to include only matching devices.
  65. // NOTE: You can use the '*' and '?' chars as wildcards for all chars or a single char (respectively).
  66. KLST_PATTERN_MATCH patternMatch = new KLST_PATTERN_MATCH();
  67. if (MI != -1)
  68. patternMatch.DeviceID = String.Format("USB\\VID_{0:X4}&PID_{1:X4}&MI_{2:X2}*",
  69. Vid,
  70. Pid,
  71. MI);
  72. else
  73. patternMatch.DeviceID = String.Format("USB\\VID_{0:X4}&PID_{1:X4}*",
  74. Vid,
  75. Pid);
  76. LstK deviceList = new LstK(KLST_FLAG.NONE,
  77. ref patternMatch);
  78. KLST_DEVINFO_HANDLE deviceInfo;
  79. interfaceDescriptor = new USB_INTERFACE_DESCRIPTOR();
  80. pipeInfo = new WINUSB_PIPE_INFORMATION();
  81. usb = null;
  82. // Iterate the devices looking for a matching alt-interface and endpoint id.
  83. while (deviceList.MoveNext(out deviceInfo))
  84. {
  85. // libusbK class contructors can throw exceptions; For instance, if the device is
  86. // using the WinUsb driver and already in-use by another application.
  87. Console.WriteLine("Opening usb device..");
  88. usb = new UsbK(deviceInfo);
  89. Console.WriteLine("Finding interface and endpoint by PipeId..");
  90. success = FindPipeAndInterface(usb,
  91. out interfaceDescriptor,
  92. out pipeInfo);
  93. if (success) break;
  94. Console.WriteLine("PipeId {0:X2}h not found on this device.",
  95. PipeId);
  96. usb.Free();
  97. usb = null;
  98. }
  99. if (ReferenceEquals(usb,
  100. null))
  101. {
  102. Console.WriteLine("Usb device not found: {0}",
  103. patternMatch.DeviceID);
  104. success = false;
  105. goto Done;
  106. }
  107. MI = interfaceDescriptor.bInterfaceNumber;
  108. AltInterfaceId = interfaceDescriptor.bAlternateSetting;
  109. PipeId = pipeInfo.PipeId;
  110. // Set interface alt setting.
  111. Console.WriteLine("Setting interface #{0} to bAlternateSetting #{1}..",
  112. interfaceDescriptor.bInterfaceNumber,
  113. interfaceDescriptor.bAlternateSetting);
  114. success = usb.SetAltInterface(interfaceDescriptor.bInterfaceNumber,
  115. false,
  116. interfaceDescriptor.bAlternateSetting);
  117. if (!success)
  118. {
  119. Console.WriteLine("SetAltInterface failed. ErrorCode={0:X8}h",
  120. Marshal.GetLastWin32Error());
  121. Console.WriteLine(interfaceDescriptor.ToString());
  122. }
  123. Done:
  124. deviceList.Free();
  125. return success;
  126. }
  127. public HiPerfTimer Dcs = new HiPerfTimer();
  128. public void FillFromCommandLine(string commandLine)
  129. {
  130. commandLine = Regex.Replace(commandLine,
  131. "^(\".+?\"|\\S+)\\s*",
  132. "");
  133. string exp = String.Empty;
  134. exp += makeArgExpression("Vid",
  135. NumberStyles.HexNumber) + "|";
  136. exp += makeArgExpression("Pid",
  137. NumberStyles.HexNumber) + "|";
  138. exp += makeArgExpression("PipeId",
  139. NumberStyles.HexNumber) + "|";
  140. exp += makeArgExpression("AltId",
  141. NumberStyles.Integer) + "|";
  142. exp += makeArgExpression("MI",
  143. NumberStyles.Integer) + "|";
  144. exp += makeArgExpression("Log",
  145. NumberStyles.None);
  146. m_CommandArguments = Regex.Matches(commandLine,
  147. exp,
  148. RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase |
  149. RegexOptions.IgnorePatternWhitespace);
  150. foreach (Match m in m_CommandArguments)
  151. {
  152. Group gVid = m.Groups["Vid"];
  153. Group gPid = m.Groups["Pid"];
  154. Group gMI = m.Groups["MI"];
  155. Group gPipeId = m.Groups["PipeId"];
  156. Group gAltId = m.Groups["AltId"];
  157. Group gLog = m.Groups["Log"];
  158. Group gIsHex = m.Groups["IsHex"];
  159. if (gVid.Success)
  160. Vid = gIsHex.Success
  161. ? UInt16.Parse(gVid.Value,
  162. NumberStyles.HexNumber)
  163. : UInt16.Parse(gVid.Value);
  164. else if (gPid.Success)
  165. Pid = gIsHex.Success
  166. ? UInt16.Parse(gPid.Value,
  167. NumberStyles.HexNumber)
  168. : UInt16.Parse(gPid.Value);
  169. else if (gMI.Success)
  170. MI = gIsHex.Success
  171. ? UInt16.Parse(gMI.Value,
  172. NumberStyles.HexNumber)
  173. : UInt16.Parse(gMI.Value);
  174. else if (gPipeId.Success)
  175. PipeId = gIsHex.Success
  176. ? Byte.Parse(gPipeId.Value,
  177. NumberStyles.HexNumber)
  178. : Byte.Parse(gPipeId.Value);
  179. else if (gAltId.Success)
  180. AltInterfaceId = gIsHex.Success
  181. ? Byte.Parse(gAltId.Value,
  182. NumberStyles.HexNumber)
  183. : Byte.Parse(gAltId.Value);
  184. else if (gLog.Success)
  185. LogFilename = gLog.Value;
  186. else
  187. {
  188. throw new Exception("Invalid argument:" + m.Value);
  189. }
  190. }
  191. }
  192. public bool FindPipeAndInterface(UsbK usb,
  193. out USB_INTERFACE_DESCRIPTOR interfaceDescriptor,
  194. out WINUSB_PIPE_INFORMATION pipeInfo)
  195. {
  196. if (FindPipeAndInterface(usb,
  197. out interfaceDescriptor,
  198. out pipeInfo,
  199. AltInterfaceId,
  200. PipeId))
  201. {
  202. AltInterfaceId = interfaceDescriptor.bAlternateSetting;
  203. PipeId = pipeInfo.PipeId;
  204. return true;
  205. }
  206. return false;
  207. }
  208. public static bool FindPipeAndInterface(UsbK usb,
  209. out USB_INTERFACE_DESCRIPTOR interfaceDescriptor,
  210. out WINUSB_PIPE_INFORMATION pipeInfo,
  211. int altInterfaceId,
  212. int pipeId)
  213. {
  214. byte interfaceIndex = 0;
  215. interfaceDescriptor = new USB_INTERFACE_DESCRIPTOR();
  216. pipeInfo = new WINUSB_PIPE_INFORMATION();
  217. while (usb.SelectInterface(interfaceIndex,
  218. true))
  219. {
  220. byte altSettingNumber = 0;
  221. while (usb.QueryInterfaceSettings(altSettingNumber,
  222. out interfaceDescriptor))
  223. {
  224. if (altInterfaceId == -1 || altInterfaceId == altSettingNumber)
  225. {
  226. byte pipeIndex = 0;
  227. while (usb.QueryPipe(altSettingNumber,
  228. pipeIndex++,
  229. out pipeInfo))
  230. {
  231. if ((pipeInfo.MaximumPacketSize > 0) &&
  232. pipeId == -1 || pipeInfo.PipeId == pipeId ||
  233. ((pipeId & 0xF) == 0 && ((pipeId & 0x80) == (pipeInfo.PipeId & 0x80))))
  234. {
  235. goto FindInterfaceDone;
  236. }
  237. pipeInfo.PipeId = 0;
  238. }
  239. }
  240. altSettingNumber++;
  241. }
  242. interfaceIndex++;
  243. }
  244. FindInterfaceDone:
  245. return pipeInfo.PipeId != 0;
  246. }
  247. public void Free()
  248. {
  249. if (fileLoggingEnabled && logStream != null)
  250. {
  251. logStream.Flush();
  252. logStream.Close();
  253. logStream = null;
  254. }
  255. }
  256. public void Init()
  257. {
  258. if (!String.IsNullOrEmpty(LogFilename))
  259. {
  260. logStream = new StreamWriter(LogFilename);
  261. fileLoggingEnabled = true;
  262. }
  263. }
  264. public void Log(String text)
  265. {
  266. if (fileLoggingEnabled) logStream.Write(text);
  267. else Console.Write(text);
  268. }
  269. public void Log(String format,
  270. params object[] args)
  271. {
  272. if (fileLoggingEnabled)
  273. logStream.Write(format,
  274. args);
  275. else
  276. Console.Write(format,
  277. args);
  278. }
  279. public string LogFilename;
  280. public void LogLn(String text)
  281. {
  282. if (fileLoggingEnabled) logStream.WriteLine(text);
  283. else Console.WriteLine(text);
  284. }
  285. public void LogLn(String format,
  286. params object[] args)
  287. {
  288. if (fileLoggingEnabled)
  289. logStream.WriteLine(format,
  290. args);
  291. else
  292. Console.WriteLine(format,
  293. args);
  294. }
  295. public int MI;
  296. public int MaxTransfersTotal;
  297. public int Pid;
  298. public int PipeId;
  299. public bool ShowTestReady()
  300. {
  301. while (Console.KeyAvailable)
  302. Console.ReadKey(true);
  303. Console.WriteLine("Test ready:");
  304. Console.Write(ToString());
  305. if (!String.IsNullOrEmpty(LogFilename))
  306. Console.WriteLine("Logging output to file: {0}",
  307. LogFilename);
  308. Console.WriteLine("Press 'Q' to abort or any other key to continue..");
  309. ConsoleKeyInfo key = Console.ReadKey(true);
  310. if (key.KeyChar == 'q' || key.KeyChar == 'Q') return false;
  311. Console.WriteLine();
  312. Console.WriteLine("Starting test..");
  313. Console.WriteLine();
  314. return true;
  315. }
  316. public override string ToString()
  317. {
  318. return
  319. String.Format(
  320. "Vid: {0:X4}h\nPid: {1:X4}h\nMI: {2:X2}h\nPipeId: {3:X2}h\nMaxTransfersTotal: {4}\n\nLogFilename: {5}\n",
  321. Vid,
  322. Pid,
  323. MI,
  324. PipeId,
  325. MaxTransfersTotal,
  326. LogFilename);
  327. }
  328. public int Vid;
  329. #endregion
  330. #region Private Members
  331. private bool fileLoggingEnabled;
  332. private StreamWriter logStream;
  333. private MatchCollection m_CommandArguments;
  334. private string makeArgExpression(string argName,
  335. NumberStyles argType)
  336. {
  337. const string argsep = @"\W\s*";
  338. switch (argType)
  339. {
  340. case NumberStyles.None:
  341. return String.Format(@"(({0}{1}(?<{0}>{2}))\s*)",
  342. argName,
  343. argsep,
  344. "(\".+?\"|\\S+)");
  345. case NumberStyles.Integer:
  346. case NumberStyles.HexNumber:
  347. return String.Format(@"(({0}{1}(?<IsHex>0x)?(?<{0}>[0-9A-F]+))(?<IsHex>h)?\s*)",
  348. argName,
  349. argsep);
  350. default:
  351. throw new Exception();
  352. }
  353. }
  354. #endregion
  355. }
  356. internal class IsoTestParameters : TestParameters
  357. {
  358. #region Public Members
  359. public IsoTestParameters(int vid,
  360. int pid,
  361. int altInterfaceId,
  362. int pipeId,
  363. int maxOutstandingTransfers,
  364. int maxTransfersTotal,
  365. string logFilename,
  366. int isoPacketsPerTransfer)
  367. : base(vid,
  368. pid,
  369. altInterfaceId,
  370. pipeId,
  371. maxTransfersTotal,
  372. logFilename)
  373. {
  374. IsoPacketsPerTransfer = isoPacketsPerTransfer;
  375. MaxOutstandingTransfers = maxOutstandingTransfers;
  376. FillFromCommandLine(Environment.CommandLine);
  377. Init();
  378. }
  379. public int IsoPacketsPerTransfer;
  380. public int MaxOutstandingTransfers;
  381. public override string ToString()
  382. {
  383. string fmt = String.Empty;
  384. fmt += "IsoPacketsPerTransfer: {0}\n";
  385. fmt += "MaxOutstandingTransfers: {1}\n";
  386. object[] args = new object[]
  387. {
  388. IsoPacketsPerTransfer, MaxOutstandingTransfers
  389. };
  390. return base.ToString() + string.Format(fmt,
  391. args);
  392. }
  393. #endregion
  394. }
  395. internal class StmTestParameters : TestParameters
  396. {
  397. #region Public Members
  398. public StmTestParameters(int vid,
  399. int pid,
  400. int altInterfaceId,
  401. byte pipeId,
  402. int maxTransfersTotal,
  403. string logFilename,
  404. int transferBufferSize,
  405. int maxPendingIO,
  406. int maxPendingTransfers)
  407. : base(vid,
  408. pid,
  409. altInterfaceId,
  410. pipeId,
  411. maxTransfersTotal,
  412. logFilename)
  413. {
  414. TransferBufferSize = transferBufferSize;
  415. MaxPendingIO = maxPendingIO;
  416. MaxPendingTransfers = maxPendingTransfers;
  417. FillFromCommandLine(Environment.CommandLine);
  418. Init();
  419. }
  420. public int MaxPendingIO;
  421. public int MaxPendingTransfers;
  422. public override string ToString()
  423. {
  424. string fmt = String.Empty;
  425. fmt += "TransferBufferSize: {0}\n";
  426. fmt += "MaxPendingIO: {1}\n";
  427. fmt += "MaxPendingTransfers: {2}\n";
  428. object[] args = new object[]
  429. {
  430. TransferBufferSize, MaxPendingIO, MaxPendingTransfers
  431. };
  432. return base.ToString() + string.Format(fmt,
  433. args);
  434. }
  435. public int TransferBufferSize;
  436. #endregion
  437. }
  438. internal class AsyncTestParameters : TestParameters
  439. {
  440. #region Public Members
  441. public AsyncTestParameters(int vid,
  442. int pid,
  443. int altInterfaceId,
  444. byte pipeId,
  445. int maxTransfersTotal,
  446. string logFilename,
  447. int transferBufferSize,
  448. int maxPendingIO)
  449. : base(vid,
  450. pid,
  451. altInterfaceId,
  452. pipeId,
  453. maxTransfersTotal,
  454. logFilename)
  455. {
  456. TransferBufferSize = transferBufferSize;
  457. MaxPendingIO = maxPendingIO;
  458. FillFromCommandLine(Environment.CommandLine);
  459. Init();
  460. }
  461. public int MaxPendingIO;
  462. public override string ToString()
  463. {
  464. string fmt = String.Empty;
  465. fmt += "TransferBufferSize: {0}\n";
  466. fmt += "MaxPendingIO: {1}\n";
  467. object[] args = new object[]
  468. {
  469. TransferBufferSize, MaxPendingIO
  470. };
  471. return base.ToString() + string.Format(fmt,
  472. args);
  473. }
  474. public int TransferBufferSize;
  475. #endregion
  476. }
  477. }