dsi_ant_device.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897
  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 in compliance
  4. with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2014
  6. All rights reserved.
  7. */
  8. #include "types.h"
  9. #include "dsi_framer_ant.hpp"
  10. #include "dsi_serial_generic.hpp"
  11. #include "dsi_thread.h"
  12. #include "config.h"
  13. #include "dsi_debug.hpp"
  14. #if defined(DEBUG_FILE)
  15. #include "macros.h"
  16. #endif
  17. #include "dsi_ant_device.hpp"
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <time.h>
  22. //////////////////////////////////////////////////////////////////////////////////
  23. // Public Functions
  24. //////////////////////////////////////////////////////////////////////////////////
  25. DSIANTDevice::DSIANTDevice()
  26. {
  27. bInitFailed = FALSE;
  28. bOpened = FALSE;
  29. hRequestThread = (DSI_THREAD_ID)NULL; // Handle for the Request thread
  30. hReceiveThread = (DSI_THREAD_ID)NULL;
  31. bKillThread = FALSE;
  32. bReceiveThreadRunning = FALSE;
  33. bRequestThreadRunning = FALSE;
  34. bCancel = FALSE;
  35. ucUSBDeviceNum = 0;
  36. usBaudRate = 0;
  37. ulUSBSerialNumber = 0;
  38. bAutoInit = FALSE;
  39. bPollUSB = FALSE;
  40. memset(apclChannelList, 0, sizeof(apclChannelList));
  41. eState = ANT_USB_STATE_OFF;
  42. eRequest = REQUEST_NONE;
  43. #if defined(DEBUG_FILE)
  44. DSIDebug::Init();
  45. #endif
  46. pclSerialObject = new DSISerialGeneric();
  47. pclANT = new DSIFramerANT();
  48. if (pclANT->Init(pclSerialObject) == FALSE)
  49. {
  50. bInitFailed = TRUE;
  51. }
  52. pclANT->SetCancelParameter(&bCancel);
  53. pclSerialObject->SetCallback(pclANT);
  54. if (DSIThread_MutexInit(&stMutexCriticalSection) != DSI_THREAD_ENONE)
  55. {
  56. bInitFailed = TRUE;
  57. }
  58. if (DSIThread_MutexInit(&stMutexResponseQueue) != DSI_THREAD_ENONE)
  59. {
  60. bInitFailed = TRUE;
  61. }
  62. if (DSIThread_MutexInit(&stMutexChannelListAccess) != DSI_THREAD_ENONE)
  63. {
  64. bInitFailed = TRUE;
  65. }
  66. if (DSIThread_CondInit(&stCondRequestThreadExit) != DSI_THREAD_ENONE)
  67. {
  68. bInitFailed = TRUE;
  69. }
  70. if (DSIThread_CondInit(&stCondReceiveThreadExit) != DSI_THREAD_ENONE)
  71. {
  72. bInitFailed = TRUE;
  73. }
  74. if (DSIThread_CondInit(&stCondRequest) != DSI_THREAD_ENONE)
  75. {
  76. bInitFailed = TRUE;
  77. }
  78. if (DSIThread_CondInit(&stCondWaitForResponse) != DSI_THREAD_ENONE)
  79. {
  80. bInitFailed = TRUE;
  81. }
  82. //If the init fails, something is broken and nothing is going to work anyway
  83. //additionally the logging isn't even setup at this point
  84. //so we throw an exception so we know something is broken right away
  85. if(bInitFailed == TRUE)
  86. throw "ANTFS constructor: init failed";
  87. }
  88. ///////////////////////////////////////////////////////////////////////
  89. DSIANTDevice::~DSIANTDevice()
  90. {
  91. this->Close();
  92. delete pclSerialObject;
  93. delete pclANT;
  94. if (bInitFailed == FALSE)
  95. {
  96. DSIThread_MutexDestroy(&stMutexCriticalSection);
  97. DSIThread_MutexDestroy(&stMutexResponseQueue);
  98. DSIThread_MutexDestroy(&stMutexChannelListAccess);
  99. DSIThread_CondDestroy(&stCondReceiveThreadExit);
  100. DSIThread_CondDestroy(&stCondRequestThreadExit);
  101. DSIThread_CondDestroy(&stCondRequest);
  102. DSIThread_CondDestroy(&stCondWaitForResponse);
  103. }
  104. #if defined(DEBUG_FILE)
  105. DSIDebug::Close();
  106. #endif
  107. }
  108. ///////////////////////////////////////////////////////////////////////
  109. BOOL DSIANTDevice::Init(BOOL bPollUSB_)
  110. {
  111. #if defined(DEBUG_FILE)
  112. DSIDebug::ThreadInit("Application");
  113. #endif
  114. if (bInitFailed == TRUE)
  115. {
  116. #if defined(DEBUG_FILE)
  117. DSIDebug::ThreadWrite("DSIANTDevice::Init(): bInitFailed == TRUE");
  118. #endif
  119. return FALSE;
  120. }
  121. bAutoInit = TRUE;
  122. bPollUSB = bPollUSB_;
  123. return ReInitDevice();
  124. }
  125. ///////////////////////////////////////////////////////////////////////
  126. BOOL DSIANTDevice::Init(UCHAR ucUSBDeviceNum_, USHORT usBaudRate_, BOOL bPollUSB_)
  127. {
  128. #if defined(DEBUG_FILE)
  129. DSIDebug::ThreadInit("Application");
  130. #endif
  131. bAutoInit = FALSE;
  132. ucUSBDeviceNum = ucUSBDeviceNum_;
  133. usBaudRate = usBaudRate_;
  134. bPollUSB = bPollUSB_;
  135. return ReInitDevice();
  136. }
  137. ///////////////////////////////////////////////////////////////////////
  138. void DSIANTDevice::Close()
  139. {
  140. #if defined(DEBUG_FILE)
  141. DSIDebug::ThreadWrite("DSIANTDevice::Close(): Closing...");
  142. #endif
  143. DSIThread_MutexLock(&stMutexCriticalSection);
  144. // Stop the threads.
  145. bKillThread = TRUE;
  146. #if defined(DEBUG_FILE)
  147. DSIDebug::ThreadWrite("DSIANTDevice::Close(): SetEvent(stCondWaitForResponse).");
  148. #endif
  149. DSIThread_MutexLock(&stMutexResponseQueue);
  150. DSIThread_CondSignal(&stCondWaitForResponse);
  151. clResponseQueue.Clear();
  152. DSIThread_MutexUnlock(&stMutexResponseQueue);
  153. ClearManagedChannelList();
  154. if (hRequestThread)
  155. {
  156. if (bRequestThreadRunning == TRUE)
  157. {
  158. #if defined(DEBUG_FILE)
  159. DSIDebug::ThreadWrite("DSIANTDevice::Close(): SetEvent(stCondRequest).");
  160. #endif
  161. DSIThread_CondSignal(&stCondRequest);
  162. #if defined(DEBUG_FILE)
  163. DSIDebug::ThreadWrite("DSIANTDevice::Close(): Killing thread.");
  164. #endif
  165. if (DSIThread_CondTimedWait(&stCondRequestThreadExit, &stMutexCriticalSection, 9000) != DSI_THREAD_ENONE)
  166. {
  167. #if defined(DEBUG_FILE)
  168. DSIDebug::ThreadWrite("DSIANTDevice::Close(): Thread not dead.");
  169. DSIDebug::ThreadWrite("DSIANTDevice::Close(): Forcing thread termination...");
  170. #endif
  171. DSIThread_DestroyThread(hRequestThread);
  172. }
  173. else
  174. {
  175. #if defined(DEBUG_FILE)
  176. DSIDebug::ThreadWrite("DSIANTDevice::Close(): Thread terminated successfully.");
  177. #endif
  178. }
  179. }
  180. DSIThread_ReleaseThreadID(hRequestThread);
  181. hRequestThread = (DSI_THREAD_ID)NULL;
  182. }
  183. if (hReceiveThread)
  184. {
  185. if (bReceiveThreadRunning == TRUE)
  186. {
  187. #if defined(DEBUG_FILE)
  188. DSIDebug::ThreadWrite("DSIANTDevice::Close(): Killing receive thread.");
  189. #endif
  190. if (DSIThread_CondTimedWait(&stCondReceiveThreadExit, &stMutexCriticalSection, 2000) == DSI_THREAD_ENONE)
  191. {
  192. #if defined(DEBUG_FILE)
  193. DSIDebug::ThreadWrite("DSIANTDevice::Close(): Receive thread not dead.");
  194. DSIDebug::ThreadWrite("DSIANTDevice::Close(): Forcing thread termination...");
  195. #endif
  196. DSIThread_DestroyThread(hReceiveThread);
  197. }
  198. else
  199. {
  200. #if defined(DEBUG_FILE)
  201. DSIDebug::ThreadWrite("DSIANTDevice::Close(): Thread terminated successfully.");
  202. #endif
  203. }
  204. }
  205. DSIThread_ReleaseThreadID(hReceiveThread);
  206. hReceiveThread = (DSI_THREAD_ID)NULL;
  207. }
  208. DSIThread_MutexUnlock(&stMutexCriticalSection);
  209. CloseDevice(FALSE);
  210. eState = ANT_USB_STATE_OFF;
  211. #if defined(DEBUG_FILE)
  212. DSIDebug::ThreadWrite("DSIANTDevice::Close(): Closed.");
  213. #endif
  214. }
  215. ///////////////////////////////////////////////////////////////////////
  216. ULONG DSIANTDevice::GetSerialNumber(void)
  217. {
  218. return ulUSBSerialNumber;
  219. }
  220. ///////////////////////////////////////////////////////////////////////
  221. ANT_USB_STATE DSIANTDevice::GetStatus(void)
  222. {
  223. return eState;
  224. }
  225. ///////////////////////////////////////////////////////////////////////
  226. ANT_USB_RESPONSE DSIANTDevice::WaitForResponse(ULONG ulMilliseconds_)
  227. {
  228. ANT_USB_RESPONSE eResponse = ANT_USB_RESPONSE_NONE;
  229. if (bKillThread == TRUE)
  230. return ANT_USB_RESPONSE_NONE;
  231. //Wait for response
  232. DSIThread_MutexLock(&stMutexResponseQueue);
  233. if(clResponseQueue.isEmpty())
  234. {
  235. UCHAR ucResult = DSIThread_CondTimedWait(&stCondWaitForResponse, &stMutexResponseQueue, ulMilliseconds_);
  236. switch(ucResult)
  237. {
  238. case DSI_THREAD_ENONE:
  239. eResponse = clResponseQueue.GetResponse();
  240. break;
  241. case DSI_THREAD_ETIMEDOUT:
  242. eResponse = ANT_USB_RESPONSE_NONE;
  243. break;
  244. case DSI_THREAD_EOTHER:
  245. #if defined(DEBUG_FILE)
  246. DSIDebug::ThreadWrite("DSIANTDevice:WaitForResponse(): CondTimedWait() Failed!");
  247. #endif
  248. eResponse = ANT_USB_RESPONSE_NONE;
  249. break;
  250. default:
  251. #if defined(DEBUG_FILE)
  252. DSIDebug::ThreadWrite("DSIANTDevice:WaitForResponse(): Error Unknown...");
  253. #endif
  254. eResponse = ANT_USB_RESPONSE_NONE;
  255. break;
  256. }
  257. }
  258. else
  259. {
  260. eResponse = clResponseQueue.GetResponse();
  261. }
  262. DSIThread_MutexUnlock(&stMutexResponseQueue);
  263. return eResponse;
  264. }
  265. ///////////////////////////////////////////////////////////////////////
  266. BOOL DSIANTDevice::AddMessageProcessor(UCHAR ucChannelNumber_, DSIANTMessageProcessor* pclChannel_)
  267. {
  268. DSIThread_MutexLock(&stMutexChannelListAccess);
  269. if(ucChannelNumber_ >= MAX_ANT_CHANNELS)
  270. {
  271. #if defined(DEBUG_FILE)
  272. DSIDebug::ThreadWrite("DSIANTDevice::AddManagedChannel(): Invalid channel number");
  273. #endif
  274. DSIThread_MutexUnlock(&stMutexChannelListAccess);
  275. return FALSE;
  276. }
  277. if(apclChannelList[ucChannelNumber_] != (DSIANTMessageProcessor*) NULL)
  278. {
  279. #if defined(DEBUG_FILE)
  280. DSIDebug::ThreadWrite("DSIANTDevice::AddManagedChannel(): Managed channel already registered for this channel number. Unregister first.");
  281. #endif
  282. DSIThread_MutexUnlock(&stMutexChannelListAccess);
  283. return FALSE;
  284. }
  285. apclChannelList[ucChannelNumber_] = pclChannel_;
  286. pclChannel_->Init(pclANT, ucChannelNumber_);
  287. DSIThread_MutexUnlock(&stMutexChannelListAccess);
  288. return TRUE;
  289. }
  290. ///////////////////////////////////////////////////////////////////////
  291. BOOL DSIANTDevice::RemoveMessageProcessor(DSIANTMessageProcessor* pclChannel_)
  292. {
  293. UCHAR ucChannel;
  294. DSIThread_MutexLock(&stMutexChannelListAccess);
  295. if(pclChannel_ == (DSIANTMessageProcessor*) NULL)
  296. {
  297. DSIThread_MutexUnlock(&stMutexChannelListAccess);
  298. return FALSE;
  299. }
  300. // Find the handle in the list
  301. ucChannel = pclChannel_->GetChannelNumber();
  302. if(apclChannelList[ucChannel] == (DSIANTMessageProcessor*) NULL)
  303. {
  304. #if defined(DEBUG_FILE)
  305. DSIDebug::ThreadWrite("DSIANTDevice::RemoveMessageProcessor(): No message processor registered.");
  306. #endif
  307. DSIThread_MutexUnlock(&stMutexChannelListAccess);
  308. return FALSE;
  309. }
  310. if(apclChannelList[ucChannel] != pclChannel_)
  311. {
  312. #if defined(DEBUG_FILE)
  313. DSIDebug::ThreadWrite("DSIANTDevice::RemoveMessageProcessor(): Message processor mismatch during removal.");
  314. #endif
  315. DSIThread_MutexUnlock(&stMutexChannelListAccess);
  316. return FALSE;
  317. }
  318. pclChannel_->Close();
  319. apclChannelList[ucChannel] = (DSIANTMessageProcessor*) NULL;
  320. DSIThread_MutexUnlock(&stMutexChannelListAccess);
  321. #if defined(DEBUG_FILE)
  322. DSIDebug::ThreadWrite("DSIANTDevice::RemoveMessageProcessor(): Message processor removed.");
  323. #endif
  324. return TRUE;
  325. }
  326. ///////////////////////////////////////////////////////////////////////
  327. void DSIANTDevice::ClearManagedChannelList(void)
  328. {
  329. DSIThread_MutexLock(&stMutexChannelListAccess);
  330. memset(apclChannelList, 0, sizeof(apclChannelList));
  331. DSIThread_MutexUnlock(&stMutexChannelListAccess);
  332. }
  333. #if defined(DEBUG_FILE)
  334. ///////////////////////////////////////////////////////////////////////
  335. void DSIANTDevice::SetDebug(BOOL bDebugOn_, const char *pcDirectory_)
  336. {
  337. if (pcDirectory_)
  338. DSIDebug::SetDirectory(pcDirectory_);
  339. DSIDebug::SetDebug(bDebugOn_);
  340. }
  341. #endif
  342. //////////////////////////////////////////////////////////////////////////////////
  343. // Private Functions
  344. //////////////////////////////////////////////////////////////////////////////////
  345. ///////////////////////////////////////////////////////////////////////
  346. BOOL DSIANTDevice::ReInitDevice(void)
  347. {
  348. if (eState != ANT_USB_STATE_OFF)
  349. this->Close();
  350. bCancel = FALSE;
  351. bKillThread = FALSE;
  352. #if defined(DEBUG_FILE)
  353. DSIDebug::ResetTime();
  354. DSIDebug::ThreadWrite(SW_VER);
  355. #endif
  356. if (pclANT->Init(pclSerialObject) == FALSE)
  357. {
  358. #if defined(DEBUG_FILE)
  359. DSIDebug::ThreadWrite("DSIANTDevice::ReInitDevice(): Failed to re-init pclANT.");
  360. #endif
  361. return FALSE;
  362. }
  363. if (hRequestThread == NULL)
  364. {
  365. hRequestThread = DSIThread_CreateThread(&DSIANTDevice::RequestThreadStart, this);
  366. if (hRequestThread == NULL)
  367. return FALSE;
  368. }
  369. if (hReceiveThread == NULL)
  370. {
  371. hReceiveThread = DSIThread_CreateThread(&DSIANTDevice::ReceiveThreadStart, this);
  372. if (hReceiveThread == NULL)
  373. return FALSE;
  374. }
  375. DSIThread_MutexLock(&stMutexResponseQueue);
  376. clResponseQueue.Clear();
  377. DSIThread_MutexUnlock(&stMutexResponseQueue);
  378. DSIThread_MutexLock(&stMutexCriticalSection);
  379. eRequest = REQUEST_OPEN;
  380. DSIThread_CondSignal(&stCondRequest);
  381. DSIThread_MutexUnlock(&stMutexCriticalSection);
  382. #if defined(DEBUG_FILE)
  383. DSIDebug::ThreadWrite("DSIANTDevice::ReInitDevice(): Initializing.");
  384. #endif
  385. return TRUE;
  386. }
  387. ///////////////////////////////////////////////////////////////////////
  388. BOOL DSIANTDevice::AttemptOpen(void)
  389. {
  390. if (bOpened)
  391. {
  392. pclSerialObject->Close();
  393. bOpened = FALSE;
  394. }
  395. if (bAutoInit)
  396. {
  397. if (pclSerialObject->AutoInit() == FALSE)
  398. {
  399. #if defined(DEBUG_FILE)
  400. DSIDebug::ThreadWrite("DSIANTDevice::AttemptOpen(): AutoInit Failed.");
  401. #endif
  402. return FALSE;
  403. }
  404. }
  405. else
  406. {
  407. if(pclSerialObject->Init(usBaudRate, ucUSBDeviceNum) == FALSE)
  408. return FALSE;
  409. }
  410. if (pclSerialObject->Open() == FALSE)
  411. return FALSE;
  412. ulUSBSerialNumber = pclSerialObject->GetDeviceSerialNumber();
  413. bOpened = TRUE;
  414. return TRUE;
  415. }
  416. ///////////////////////////////////////////////////////////////////////
  417. void DSIANTDevice::CloseDevice(BOOL bReset_)
  418. {
  419. #if defined(DEBUG_FILE)
  420. DSIDebug::ThreadWrite("DSIANTDevice::CloseDevice(): Closing..");
  421. #endif
  422. if ((bOpened == TRUE) && (eRequest != REQUEST_HANDLE_SERIAL_ERROR))
  423. {
  424. // Send reset command to ANT.
  425. pclANT->ResetSystem();
  426. #if defined(DEBUG_FILE)
  427. DSIDebug::ThreadWrite("DSIANTDevice::CloseDevice(): ANT_ResetSystem() complete.");
  428. #endif
  429. }
  430. #if defined(DEBUG_FILE)
  431. if (bReset_)
  432. {
  433. DSIDebug::ThreadWrite("DSIANTDevice::CloseDevice(): Calling serial object close with reset = TRUE.");
  434. }
  435. #endif
  436. pclSerialObject->Close(bReset_);
  437. bOpened = FALSE;
  438. #if defined(DEBUG_FILE)
  439. DSIDebug::ThreadWrite("DSIANTDevice::CloseDevice(): Closed");
  440. #endif
  441. }
  442. ///////////////////////////////////////////////////////////////////////
  443. //TODO //TTA Should change this to be like the managed side
  444. void DSIANTDevice::HandleSerialError(void)
  445. {
  446. UCHAR i;
  447. if (eState < ANT_USB_STATE_OPEN) // No need to process errors if already handled
  448. return;
  449. // Notify callbacks
  450. for(i = 0; i< MAX_ANT_CHANNELS; i++)
  451. {
  452. if(apclChannelList[i] != (DSIANTMessageProcessor*) NULL)
  453. apclChannelList[i]->ProcessDeviceNotification(ANT_DEVICE_NOTIFICATION_SHUTDOWN, (void*) NULL);
  454. }
  455. #if defined(DEBUG_FILE)
  456. DSIDebug::ThreadWrite("DSIANTDevice::HandleSerialError(): Closing USB Device");
  457. #endif
  458. CloseDevice(TRUE);
  459. DSIThread_MutexLock(&stMutexCriticalSection);
  460. eRequest = REQUEST_SERIAL_ERROR_HANDLED;
  461. DSIThread_CondSignal(&stCondRequest);
  462. DSIThread_MutexUnlock(&stMutexCriticalSection);
  463. AddResponse(ANT_USB_RESPONSE_SERIAL_FAIL); //TODO: can move this to the Request thread?
  464. }
  465. ///////////////////////////////////////////////////////////////////////
  466. DSI_THREAD_RETURN DSIANTDevice::RequestThreadStart(void *pvParameter_)
  467. {
  468. #if defined(DEBUG_FILE)
  469. DSIDebug::ThreadInit("DSIANTDevice");
  470. #endif
  471. ((DSIANTDevice*)pvParameter_)->RequestThread();
  472. return 0;
  473. }
  474. ///////////////////////////////////////////////////////////////////////
  475. //TODO //TTA Why use a polling state machine here? It just makes things complicated to trace.
  476. void DSIANTDevice::RequestThread(void)
  477. {
  478. ANT_USB_RESPONSE eResponse;
  479. bRequestThreadRunning = TRUE;
  480. while (bKillThread == FALSE)
  481. {
  482. eResponse = ANT_USB_RESPONSE_NONE;
  483. #if defined(DEBUG_FILE)
  484. DSIDebug::ThreadWrite("DSIANTDevice::RequestThread(): Awaiting Requests...");
  485. #endif
  486. DSIThread_MutexLock(&stMutexCriticalSection);
  487. if ((eRequest == REQUEST_NONE) && (bKillThread == FALSE))
  488. {
  489. UCHAR ucResult = DSIThread_CondTimedWait(&stCondRequest, &stMutexCriticalSection, 1000);
  490. if (ucResult != DSI_THREAD_ENONE) // Polling interval 1Hz
  491. {
  492. #if defined(DEBUG_FILE)
  493. if(ucResult == DSI_THREAD_EOTHER)
  494. DSIDebug::ThreadWrite("DSIANTDevice::RequestThread(): CondTimedWait() Failed!");
  495. #endif
  496. if (eRequest == REQUEST_NONE && eState == ANT_USB_STATE_IDLE_POLLING_USB && bPollUSB)
  497. {
  498. eRequest = REQUEST_OPEN;
  499. }
  500. DSIThread_MutexUnlock(&stMutexCriticalSection);
  501. continue;
  502. }
  503. }
  504. DSIThread_MutexUnlock(&stMutexCriticalSection);
  505. if (bKillThread)
  506. break;
  507. if (eRequest != REQUEST_NONE)
  508. {
  509. #if defined(DEBUG_FILE)
  510. DSIDebug::ThreadWrite("DSIANTDevice::RequestThread(): Request received");
  511. #endif
  512. switch (eRequest)
  513. {
  514. case REQUEST_OPEN:
  515. #if defined(DEBUG_FILE)
  516. DSIDebug::ThreadWrite("DSIANTDevice::RequestThread(): Opening...");
  517. #endif
  518. if (AttemptOpen())
  519. {
  520. #if defined(DEBUG_FILE)
  521. DSIDebug::ThreadWrite("DSIANTDevice::RequestThread(): Open passed.");
  522. #endif
  523. eState = ANT_USB_STATE_OPEN;
  524. eResponse = ANT_USB_RESPONSE_OPEN_PASS;
  525. }
  526. else
  527. {
  528. #if defined(DEBUG_FILE)
  529. DSIDebug::ThreadWrite("DSIANTDevice::RequestThread(): Open failed.");
  530. #endif
  531. if(bPollUSB)
  532. {
  533. eState = ANT_USB_STATE_IDLE_POLLING_USB;
  534. }
  535. else
  536. {
  537. eState = ANT_USB_STATE_IDLE;
  538. eResponse = ANT_USB_RESPONSE_OPEN_FAIL;
  539. }
  540. }
  541. break;
  542. default:
  543. break;
  544. }
  545. //This is where to handle the internal requests, because they can happen asyncronously.
  546. //We will also clear the request here.
  547. DSIThread_MutexLock(&stMutexCriticalSection);
  548. if (eResponse != ANT_USB_RESPONSE_NONE)
  549. AddResponse(eResponse);
  550. if (eRequest == REQUEST_HANDLE_SERIAL_ERROR)
  551. {
  552. #if defined(DEBUG_FILE)
  553. DSIDebug::ThreadWrite("DSIANTDevice::RequestThread(): Serial error!");
  554. #endif
  555. HandleSerialError();
  556. if(bPollUSB)
  557. {
  558. eState = ANT_USB_STATE_IDLE_POLLING_USB;
  559. eRequest = REQUEST_OPEN;
  560. }
  561. else
  562. {
  563. eState = ANT_USB_STATE_IDLE;
  564. eRequest = REQUEST_NONE;
  565. }
  566. }
  567. else if (eRequest == REQUEST_SERIAL_ERROR_HANDLED)
  568. {
  569. #if defined(DEBUG_FILE)
  570. DSIDebug::ThreadWrite("DSIANTDevice::RequestThread(): Serial error handled");
  571. #endif
  572. if(bPollUSB)
  573. {
  574. eState = ANT_USB_STATE_IDLE_POLLING_USB;
  575. eRequest = REQUEST_OPEN;
  576. }
  577. else
  578. {
  579. eState = ANT_USB_STATE_IDLE;
  580. eRequest = REQUEST_NONE;
  581. }
  582. }
  583. else
  584. {
  585. eRequest = REQUEST_NONE; //Clear any other request
  586. }
  587. DSIThread_MutexUnlock(&stMutexCriticalSection);
  588. }
  589. }//while()
  590. #if defined(DEBUG_FILE)
  591. DSIDebug::ThreadWrite("DSIANTDevice::RequestThread(): Exiting thread.");
  592. #endif
  593. eRequest = REQUEST_NONE;
  594. CloseDevice(FALSE); //Try to close the device if it was open. This is done because the device was opened in this thread, we should try to close the device before the thread terminates.
  595. DSIThread_MutexLock(&stMutexCriticalSection);
  596. bRequestThreadRunning = FALSE;
  597. DSIThread_CondSignal(&stCondRequestThreadExit);
  598. DSIThread_MutexUnlock(&stMutexCriticalSection);
  599. #if defined(__cplusplus)
  600. return;
  601. #else
  602. ExitThread(0);
  603. #if defined(DEBUG_FILE)
  604. DSIDebug::ThreadWrite("DSIANTDevice::RequestThread(): C code reaching return statement unexpectedly.");
  605. #endif
  606. return; // Code should not be reached.
  607. #endif
  608. }
  609. ///////////////////////////////////////////////////////////////////////
  610. DSI_THREAD_RETURN DSIANTDevice::ReceiveThreadStart(void *pvParameter_)
  611. {
  612. #if defined(DEBUG_FILE)
  613. DSIDebug::ThreadInit("ANTReceive");
  614. #endif
  615. ((DSIANTDevice*)pvParameter_)->ReceiveThread();
  616. return 0;
  617. }
  618. ///////////////////////////////////////////////////////////////////////
  619. // ANT Receive Thread
  620. ///////////////////////////////////////////////////////////////////////
  621. #define MESG_CHANNEL_OFFSET 0
  622. #define MESG_EVENT_ID_OFFSET 1
  623. #define MESG_EVENT_CODE_OFFSET 2
  624. void DSIANTDevice::ReceiveThread(void)
  625. {
  626. ANT_MESSAGE stMessage;
  627. USHORT usMesgSize = 0;
  628. bReceiveThreadRunning = TRUE;
  629. while (bKillThread == FALSE)
  630. {
  631. #if defined(DEBUG_FILEV2)
  632. DSIDebug::ThreadWrite("Rx:Wait");
  633. #endif
  634. usMesgSize = pclANT->WaitForMessage(1000);
  635. //TODO A: Legacy code, may be able to remove
  636. #if defined(DEBUG_FILEV2)
  637. {
  638. UCHAR aucString1[256];
  639. SNPRINTF((char *)aucString1,256, "Rx:%u", usMesgSize);
  640. DSIDebug::ThreadWrite((char *)aucString1);
  641. SNPRINTF((char *)aucString1,256, "Rx:(%lu/%lu)", ulTransferArrayIndex, ulTransferBufferSize);
  642. DSIDebug::ThreadWrite((char *)aucString1);
  643. }
  644. #endif
  645. if (bKillThread)
  646. break;
  647. if (usMesgSize == DSI_FRAMER_ERROR)
  648. {
  649. usMesgSize = pclANT->GetMessage(&stMessage, MESG_MAX_SIZE_VALUE); //get the message to clear the error
  650. #if defined(DEBUG_FILE)
  651. {
  652. UCHAR aucString[256];
  653. SNPRINTF((char *)aucString,256, "DSIANTDevice::RecvThread(): Framer Error %u .", stMessage.ucMessageID);
  654. DSIDebug::ThreadWrite((char *)aucString);
  655. if(stMessage.ucMessageID == DSI_FRAMER_ANT_ESERIAL)
  656. {
  657. SNPRINTF((char *)aucString,256, "DSIANTDevice::RecvThread(): Serial Error %u .", stMessage.aucData[0]);
  658. DSIDebug::ThreadWrite((char *)aucString);
  659. }
  660. }
  661. #endif
  662. DSIThread_MutexLock(&stMutexCriticalSection);
  663. //bCancel = TRUE;
  664. if (eRequest < REQUEST_HANDLE_SERIAL_ERROR)
  665. eRequest = REQUEST_HANDLE_SERIAL_ERROR;
  666. DSIThread_CondSignal(&stCondRequest);
  667. DSIThread_MutexUnlock(&stMutexCriticalSection);
  668. continue;
  669. }
  670. if (usMesgSize < DSI_FRAMER_TIMEDOUT) //if the return isn't DSI_FRAMER_TIMEDOUT or DSI_FRAMER_ERROR
  671. {
  672. UCHAR ucANTChannel;
  673. usMesgSize = pclANT->GetMessage(&stMessage, MESG_MAX_SIZE_VALUE);
  674. #if defined(DEBUG_FILE)
  675. if (usMesgSize == 0)
  676. {
  677. UCHAR aucString2[256];
  678. SNPRINTF((char *)aucString2,256, "Rx msg reported size 0, dump:%u[0x%02X]...[0x%02X][0x%02X][0x%02X][0x%02X][0x%02X][0x%02X][0x%02X][0x%02X]", usMesgSize , stMessage.ucMessageID, stMessage.aucData[0], stMessage.aucData[1], stMessage.aucData[2], stMessage.aucData[3], stMessage.aucData[4], stMessage.aucData[5], stMessage.aucData[6], stMessage.aucData[7]);
  679. DSIDebug::ThreadWrite((char *)aucString2);
  680. }
  681. #endif
  682. if(stMessage.ucMessageID == MESG_SERIAL_ERROR_ID)
  683. {
  684. #if defined(DEBUG_FILE)
  685. {
  686. UCHAR aucString[256];
  687. SNPRINTF((char *) aucString, 256, "DSIANTDevice::RecvThread(): Serial Error.");
  688. DSIDebug::ThreadWrite((char *) aucString);
  689. }
  690. #endif
  691. DSIThread_MutexLock(&stMutexCriticalSection);
  692. //bCancel = TRUE;
  693. if (eRequest < REQUEST_HANDLE_SERIAL_ERROR)
  694. eRequest = REQUEST_HANDLE_SERIAL_ERROR;
  695. DSIThread_CondSignal(&stCondRequest);
  696. DSIThread_MutexUnlock(&stMutexCriticalSection);
  697. continue;
  698. }
  699. // Figure out channel
  700. //ucANTChannel = stMessage.aucData[MESG_CHANNEL_OFFSET] & CHANNEL_NUMBER_MASK;
  701. ucANTChannel = pclANT->GetChannelNumber(&stMessage);
  702. // Send messages to appropriate handler
  703. if(ucANTChannel != 0xFF)
  704. {
  705. // TODO: Add general channel and protocol event callbacks?
  706. if(apclChannelList[ucANTChannel] != (DSIANTMessageProcessor*) NULL)
  707. {
  708. if(apclChannelList[ucANTChannel]->GetEnabled())
  709. apclChannelList[ucANTChannel]->ProcessMessage(&stMessage, usMesgSize);
  710. }
  711. }
  712. }
  713. } // while()
  714. DSIThread_MutexLock(&stMutexCriticalSection);
  715. bReceiveThreadRunning = FALSE;
  716. DSIThread_CondSignal(&stCondReceiveThreadExit);
  717. DSIThread_MutexUnlock(&stMutexCriticalSection);
  718. }
  719. ///////////////////////////////////////////////////////////////////////
  720. void DSIANTDevice::AddResponse(ANT_USB_RESPONSE eResponse_)
  721. {
  722. DSIThread_MutexLock(&stMutexResponseQueue);
  723. clResponseQueue.AddResponse(eResponse_);
  724. DSIThread_CondSignal(&stCondWaitForResponse);
  725. DSIThread_MutexUnlock(&stMutexResponseQueue);
  726. }