OptTCP.cs 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading;
  5. using System.IO;
  6. using System.Net;
  7. using System.Net.Sockets;
  8. using Wayne.Lib;
  9. using Wayne.ForecourtControl.OptBridge;
  10. using Wayne.FDCPOSLibrary;
  11. using Wayne.ForecourtControl.OptBridge.Fusion;
  12. namespace Wayne.ForecourtControl.Fusion
  13. {
  14. enum MsgType
  15. {
  16. Unknown,
  17. Polling,
  18. Present,
  19. Ack,
  20. Nack,
  21. Data,
  22. }
  23. internal class OptPollerThreadObj
  24. {
  25. public bool bTerminate = false;
  26. string name = "";
  27. OptTCP optTCP;
  28. private FUSIONOpt opt;
  29. private int iOnDataReadTimeout = 4;
  30. public bool bDataReadTimeout = false;
  31. System.Threading.Timer timerOnDataRead = null;
  32. System.Threading.Timer timerOnRestartPolling = null;
  33. public OptPollerThreadObj(OptTCP optTCP, FUSIONOpt opt)
  34. {
  35. this.optTCP = optTCP;
  36. this.opt = opt;
  37. iOnDataReadTimeout = 4 * 1000;
  38. }
  39. public void optPollerThreadProc()
  40. {
  41. Thread.Sleep(1000); // gives time to AddOPT metods (the original caller) to return and register events
  42. Trace.WriteLine(string.Format("optPollerThreadProc Opt IPAddress={0}, IPPort={1}: init tp={2}", this.optTCP.sIPAddress, this.optTCP.IPPort, opt.Id));
  43. int iOnDataReadTimeout = 4, iDartPollingInterval = 300;
  44. try
  45. {
  46. try
  47. {
  48. string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "OPT" + opt.Id.ToString(), "OPTDataReadTimeout");
  49. if (sValue.Length == 0)
  50. sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "Config", "DataReadTimeout");
  51. if (sValue.Length > 0)
  52. iOnDataReadTimeout = Convert.ToInt32(sValue);
  53. if (iOnDataReadTimeout <= 10)
  54. iOnDataReadTimeout *= 1000;
  55. Trace.WriteLine(string.Format("iOnDataReadTimeout={0}", iOnDataReadTimeout));
  56. }
  57. catch (Exception ex)
  58. {
  59. Trace.WriteLine("EXCEPTION! " + ex.Message);
  60. }
  61. try
  62. {
  63. string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "OPT" + opt.Id.ToString(), "OPTDartPollingInterval");
  64. if (sValue.Length > 0)
  65. iDartPollingInterval = Convert.ToInt32(sValue);
  66. Trace.WriteLine(string.Format("iDartPollingInterval={0}", iDartPollingInterval));
  67. }
  68. catch (Exception ex)
  69. {
  70. Trace.WriteLine("EXCEPTION! " + ex.Message);
  71. }
  72. IPAddress serverIPAddress = null;
  73. IPEndPoint endPoint = null;
  74. optTCP.OptSocket = new TcpClient();
  75. //optTCP.OptSocket.ReceiveTimeout = iOnDataReadTimeout;
  76. //optTCP.OptSocket.SendTimeout = iOnDataReadTimeout;
  77. bTerminate = false;
  78. bool bConnected = false;
  79. while (!bConnected && !bTerminate)
  80. {
  81. try
  82. {
  83. Trace.WriteLine(string.Format("Connect socket"));
  84. optTCP.OptSocket.Connect(optTCP.sIPAddress, optTCP.IPPort);
  85. bConnected = true;
  86. }
  87. catch (Exception ex)
  88. {
  89. Trace.WriteLine("optPollerThreadProc EXCEPTION on Connect socket!" + ex.Message + " - " + ex.StackTrace);
  90. try
  91. {
  92. if (optTCP.OptSocket != null && optTCP.OptSocket.GetStream() != null)
  93. optTCP.OptSocket.GetStream().Close();
  94. }
  95. catch (Exception ex1)
  96. {
  97. Trace.WriteLine("optPollerThreadProc EXCEPTION on socket getStream!" + ex1.Message + " - " + ex1.StackTrace);
  98. }
  99. Thread.Sleep(1000);
  100. }
  101. }
  102. optTCP.ConnectionState = DeviceConnectionState.Connected;
  103. }
  104. catch (Exception ex)
  105. {
  106. Trace.WriteLine(string.Format("end: EXCEPTION! Stack chiamate: {0} Messaggio: {1}, tp={2}", ex.StackTrace, ex.Message, opt.Id));
  107. bTerminate = true;
  108. return;
  109. }
  110. this.optTCP.bPollerRunning = true;
  111. int iReconnectTimeout = 3000;
  112. try
  113. {
  114. string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "OPT" + opt.Id.ToString(), "ReconnectTimeout");
  115. if (sValue.Length > 0)
  116. iReconnectTimeout = Convert.ToInt32(sValue);
  117. Trace.WriteLine(string.Format("iReconnectTimeout={0}", iReconnectTimeout));
  118. }
  119. catch (Exception ex)
  120. {
  121. Trace.WriteLine("EXCEPTION! " + ex.Message);
  122. }
  123. string sbuffer = "";
  124. OverallResult result = OverallResult.Success;
  125. NetworkStream networkStream = null;
  126. System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
  127. MsgType responseType = MsgType.Unknown;
  128. bool bRespOk = false, bSendOk = false, bEnd = false;
  129. byte txNum = 0x00;
  130. byte rxNum = 0x00;
  131. byte[] dataRequest = null;
  132. byte[] dataResponse = null;
  133. int nretry = 0;
  134. int nWaitForDataResponse = 0;
  135. int nMaxWaitForDataResponse = 100;
  136. int ndartpoll = 0;
  137. int res = 0;
  138. bool bRestoredConnection = false;
  139. bool bFirstPoll = true;
  140. while (!bTerminate)
  141. {
  142. try
  143. {
  144. ndartpoll++;
  145. result = OverallResult.Success;
  146. networkStream = optTCP.OptSocket.GetStream();
  147. //Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("tp={0} PendingRequest={1}, ndartpoll={2}", opt.Id, IsPendingRequest(), ndartpoll));
  148. bRespOk = false;
  149. bSendOk = false;
  150. this.bDataReadTimeout = false;
  151. // check if there are pending request
  152. if ((dataRequest != null || IsPendingRequest()) && ndartpoll > 4)
  153. {
  154. if (!bRestoredConnection || dataRequest == null)
  155. dataRequest = GetPendingRequest();
  156. else
  157. {
  158. Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("tp={0} was restored connection", opt.Id));
  159. bRestoredConnection = false;
  160. }
  161. // if there are pending data send them
  162. if (dataResponse != null && bFirstPoll)
  163. {
  164. Trace.WriteLine(string.Format("tp={0} first poll - data pending", opt.Id));
  165. this.opt.FireOnDataRead(dataResponse);
  166. bRespOk = true;
  167. dataRequest = null;
  168. continue;
  169. }
  170. bFirstPoll = false;
  171. nretry = 0;
  172. nWaitForDataResponse = 0;
  173. // attiva timer per timeout su ricezione risposta - non deve essere periodico, parte una sola volta dopo iOnDataReadTimeout secondi
  174. Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("tp={0} PendingRequest, create timer timerOnDataReadList", opt.Id));
  175. this.timerOnDataRead = new System.Threading.Timer(new System.Threading.TimerCallback(OnDataReadTimerProc),
  176. this, iOnDataReadTimeout * 1000, Timeout.Infinite);
  177. do
  178. {
  179. nretry++;
  180. if (!bSendOk)
  181. res = Write(PreparePendingRequest(dataRequest, txNum));
  182. else if (responseType == MsgType.Data && !bRespOk)
  183. res = Write(PreparePollingRequest(MsgType.Nack, txNum));
  184. else
  185. res = Write(PreparePollingRequest(MsgType.Polling, 0));
  186. bool crcok = false;
  187. if (res >= 0)
  188. dataResponse = ReadResponse(out responseType, out rxNum, out crcok, false);
  189. else
  190. responseType = MsgType.Unknown;
  191. if (responseType == MsgType.Ack)
  192. bSendOk = true;
  193. else if (responseType == MsgType.Nack)
  194. {
  195. if (nretry > 3)
  196. txNum = 0;
  197. }
  198. else if (responseType == MsgType.Data)
  199. {
  200. // if crc fails do not send the Ack; a new poll will be sent and the tp should resend data
  201. if (CheckResponse(dataResponse) && crcok)
  202. {
  203. lock (timerOnDataRead)
  204. {
  205. if (timerOnDataRead != null)
  206. {
  207. timerOnDataRead.Dispose();
  208. timerOnDataRead = null;
  209. }
  210. }
  211. res = Write(PreparePollingRequest(MsgType.Ack, rxNum));
  212. this.opt.FireOnDataRead(dataResponse);
  213. bRespOk = true;
  214. dataRequest = null;
  215. // read if there are pending data to discard
  216. if (ReadResponse(out responseType, out rxNum, out crcok, true) != null)
  217. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} ERROR DISCARD DATA!", opt.Id));
  218. res = Write(PreparePollingRequest(MsgType.Polling, 0));
  219. dataResponse = ReadResponse(out responseType, out rxNum, out crcok, false);
  220. if (responseType != MsgType.Present)
  221. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} ERROR Wrong Response {1} (should be 'Present')", opt.Id, responseType));
  222. }
  223. else if (!crcok)
  224. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} ERROR CRC FAILS!", opt.Id));
  225. }
  226. else if (responseType == MsgType.Present)
  227. {
  228. bSendOk = true; // set to true so that request msg is not sent again
  229. nWaitForDataResponse++;
  230. if (nWaitForDataResponse > 30)
  231. bDataReadTimeout = true;
  232. }
  233. else
  234. {
  235. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} ERROR unexpected Response '{1}'", opt.Id, responseType));
  236. nWaitForDataResponse++;
  237. // try call GetStream to check if socket is still valid; it wiil arise an exception catched below
  238. if (optTCP.OptSocket.GetStream() == null)
  239. bDataReadTimeout = true;
  240. else
  241. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} stream is valid, continue", opt.Id));
  242. }
  243. if (!bRespOk) Thread.Sleep(100);
  244. if (bDataReadTimeout)
  245. {
  246. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} ERROR Data Response not arrived ! Disconnecting OPT !", opt.Id));
  247. bTerminate = true;
  248. Thread.Sleep(iReconnectTimeout);
  249. }
  250. } while (!bRespOk && !bDataReadTimeout);
  251. if (responseType != MsgType.Nack)
  252. {
  253. if (txNum < 0x0F)
  254. txNum++;
  255. else
  256. txNum = 0x01;
  257. }
  258. }
  259. else
  260. {
  261. bool crcok;
  262. do
  263. {
  264. res = Write(PreparePollingRequest(MsgType.Polling, 0));
  265. dataResponse = ReadResponse(out responseType, out rxNum, out crcok, false);
  266. if (responseType == MsgType.Data)
  267. {
  268. //if crc fails do not send the Ack; a new poll will be sent and the tp should resend data
  269. if (CheckResponse(dataResponse) && crcok)
  270. {
  271. res = Write(PreparePollingRequest(MsgType.Ack, rxNum));
  272. // read if there are pending data to discard
  273. if (ReadResponse(out responseType, out rxNum, out crcok, true) != null)
  274. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} ERROR DISCARD DATA!", opt.Id));
  275. }
  276. else if (!crcok)
  277. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} ERROR CRC FAILS!", opt.Id));
  278. // at first polling after connection could happens that tp has data to send
  279. // needs to store data and send to SINP with first request
  280. if (ndartpoll > 1)
  281. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} ERROR Wrong Response DATA !!??", opt.Id));
  282. else
  283. {
  284. bRespOk = true;
  285. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} First Polling - DATA received !", opt.Id));
  286. }
  287. }
  288. else if (responseType == MsgType.Unknown)
  289. {
  290. if (optTCP.OptSocket.GetStream() == null)
  291. {
  292. bDataReadTimeout = true;
  293. bTerminate = true;
  294. }
  295. }
  296. else if (responseType == MsgType.Present)
  297. bRespOk = true;
  298. else
  299. Trace.WriteLine(string.Format("optPollerThreadProc: tp={0} ERROR Wrong Response {1} !!??", opt.Id, responseType));
  300. } while (!bRespOk || bDataReadTimeout);
  301. }
  302. Thread.Sleep(iDartPollingInterval);
  303. }
  304. catch (Exception ex)
  305. {
  306. Trace.WriteLine(string.Format("tp={0} IOException in optPollerThreadProc! {1} - {2}", optTCP.Id, ex.Message, ex.StackTrace));
  307. optTCP.CloseSocket(networkStream);
  308. if (!bTerminate)
  309. {
  310. bool bConnected = false;
  311. int nretries = 0;
  312. while (!bConnected && nretries <= 1)
  313. {
  314. try
  315. {
  316. if (nretries == 1)
  317. {
  318. optTCP.OptSocket = new TcpClient();
  319. //optTCP.OptSocket.ReceiveTimeout = iOnDataReadTimeout;
  320. //optTCP.OptSocket.SendTimeout = iOnDataReadTimeout;
  321. Thread.Sleep(iReconnectTimeout);
  322. }
  323. Trace.WriteLine(string.Format("try reconnect socket: nretries={0}", nretries));
  324. optTCP.OptSocket.Connect(optTCP.sIPAddress, optTCP.IPPort);
  325. bConnected = true;
  326. }
  327. catch (Exception ex2)
  328. {
  329. Trace.WriteLine(string.Format("tp={0} optPollerThreadProc EXCEPTION on Connect socket! {1} - {2}", optTCP.Id, ex2.Message, ex2.StackTrace));
  330. optTCP.CloseSocket(networkStream);
  331. }
  332. nretries++;
  333. }
  334. if (!bConnected)
  335. bTerminate = true;
  336. else
  337. {
  338. bRestoredConnection = true;
  339. // set ndartpoll=3 so that it starts with a dart poll request needed to read a pending response from tp
  340. ndartpoll = 3;
  341. //optTCP.ConnectionState = DeviceConnectionState.Connected;
  342. }
  343. }
  344. }
  345. }
  346. this.optTCP.bPollerRunning = false;
  347. this.optTCP.Disconnect();
  348. //this.optTCP.Connect();
  349. int iOPTDartRestartPollingTimeout = 30000;
  350. try
  351. {
  352. string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "OPT" + opt.Id.ToString(), "OPTDartRestartPollingTimeout");
  353. if (sValue.Length > 0)
  354. iOPTDartRestartPollingTimeout = Convert.ToInt32(sValue);
  355. Trace.WriteLine(string.Format("iOPTDartRestartPollingTimeout={0}", iOPTDartRestartPollingTimeout));
  356. }
  357. catch (Exception ex)
  358. {
  359. Trace.WriteLine("EXCEPTION! " + ex.Message);
  360. }
  361. this.timerOnRestartPolling = new System.Threading.Timer(new System.Threading.TimerCallback(OnRestartPollingTimerProc),
  362. this, iOPTDartRestartPollingTimeout, Timeout.Infinite);
  363. Trace.WriteLine(string.Format("optPollerThreadProc tp={0} end", this.optTCP.Id));
  364. }
  365. public void OnRestartPollingTimerProc(Object me)
  366. {
  367. lock (timerOnRestartPolling)
  368. {
  369. try
  370. {
  371. Trace.WriteLine(string.Format("optPollerThreadProc OnRestartPollingTimerProc tp={0}, manager={1}, forecourtcontrol={2}, ConnectionState={3}",
  372. this.optTCP.Id,
  373. (optTCP.Opt.optBridge.manager != null) ? "!null":"null",
  374. (optTCP.Opt.optBridge.manager != null && optTCP.Opt.optBridge.manager.forecourtControl != null) ? "!null":"null",
  375. (optTCP.Opt.optBridge.manager != null && optTCP.Opt.optBridge.manager.forecourtControl != null) ? optTCP.Opt.optBridge.manager.forecourtControl.ConnectionState : DeviceConnectionState.Unknown));
  376. if (optTCP.Opt.optBridge.manager == null || optTCP.Opt.optBridge.manager.forecourtControl == null ||
  377. (optTCP.Opt.optBridge.manager != null && optTCP.Opt.optBridge.manager.forecourtControl != null && (optTCP.Opt.optBridge.manager.forecourtControl.ConnectionState == DeviceConnectionState.Connected || optTCP.Opt.managedBy == OPTManagedBy.SINP)))
  378. {
  379. if (timerOnRestartPolling != null)
  380. {
  381. timerOnRestartPolling.Dispose();
  382. timerOnRestartPolling = null;
  383. this.bDataReadTimeout = true;
  384. Trace.WriteLine(string.Format("optPollerThreadProc OnRestartPollingTimerProc tp={0} call connect", this.optTCP.Id));
  385. this.optTCP.Connect();
  386. }
  387. }
  388. else
  389. Trace.WriteLine(string.Format("optPollerThreadProc OnRestartPollingTimerProc tp={0} not restarted - forecourtControl is not connected", this.optTCP.Id));
  390. }
  391. catch (Exception ex)
  392. {
  393. Trace.WriteLine("Exception optPollerThreadProc OnRestartPollingTimerProc! " + ex.Message + " - " + ex.StackTrace);
  394. }
  395. }
  396. }
  397. public void OnDataReadTimerProc(Object me)
  398. {
  399. lock (timerOnDataRead)
  400. {
  401. if (timerOnDataRead != null)
  402. {
  403. timerOnDataRead.Dispose();
  404. timerOnDataRead = null;
  405. this.bDataReadTimeout = true;
  406. Trace.WriteLine(string.Format("optPollerThreadProc OnDataReadTimerProc tp={0}", this.optTCP.Id));
  407. }
  408. }
  409. }
  410. private byte[] PreparePollingRequest(MsgType pollingType, int txNum)
  411. {
  412. try
  413. {
  414. Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("optPollerThreadProc PreparePollingRequest tp={0}, pollingType={1}, txNum={2}", optTCP.Id, pollingType, txNum));
  415. byte[] pollRequest = null;
  416. pollRequest = new byte[OptTCP.PollRequestLength];
  417. // ??? che indirizzo va messo ?
  418. pollRequest[0] = (byte)(0x30 + optTCP.Id-1);
  419. if (pollingType == MsgType.Polling)
  420. pollRequest[1] = 0x20;
  421. else if (pollingType == MsgType.Ack)
  422. pollRequest[1] = (byte)(0xC0 + txNum);
  423. else
  424. pollRequest[1] = (byte)(0x50 + txNum);
  425. pollRequest[2] = 0xFA;
  426. return pollRequest;
  427. }
  428. catch (Exception ex)
  429. {
  430. Trace.WriteLine("Exception optPollerThreadProc! " + ex.Message + " - " + ex.StackTrace);
  431. }
  432. return null;
  433. }
  434. private byte[] PreparePendingRequest(byte[] data, int txNum)
  435. {
  436. try
  437. {
  438. if (data == null)
  439. {
  440. Trace.WriteLine(string.Format("optPollerThreadProc PreparePendingRequest tp={0}, invalid data !", optTCP.Id));
  441. return null;
  442. }
  443. byte[] pollRequest = null;
  444. //pollRequest = new byte[2 + data.Length + OptTCP.FooterLength+2];
  445. pollRequest = new byte[2 + data.Length];
  446. pollRequest[0] = (byte)(0x30 + optTCP.Id - 1);
  447. pollRequest[1] = (byte)(0x30 + txNum);
  448. Array.Copy(data, 0, pollRequest, 2, data.Length);
  449. ushort checksum = Crc.CalcWayneCrc(0x0000, pollRequest, 2 + data.Length);
  450. Trace.WriteLine(string.Format("optPollerThreadProc PreparePendingRequest tp={0}, checksum={1}, dataLength={2}, pollRequest={3}", optTCP.Id, checksum, 2 + data.Length, pollRequest));
  451. byte[] footer = new byte[OptTCP.FooterLength+2];
  452. int index=0;
  453. if ((byte)(checksum) == 0xFA)
  454. footer[index++] = 0x10;
  455. footer[index++] = (byte)(checksum);
  456. if (((byte)(checksum >> 8)) == 0xFA)
  457. footer[index++] = 0x10;
  458. footer[index++] = (byte)(checksum >> 8);
  459. footer[index++] = 0x03;
  460. footer[index++] = 0xFA;
  461. //Array.Copy(footer, 0, pollRequest, 2 + data.Length, OptTCP.FooterLength);
  462. //Array.Copy(footer, 0, pollRequest, 2 + data.Length, index);
  463. byte[] returnRequest = null;
  464. returnRequest = new byte[2 + data.Length + index];
  465. Array.Copy(pollRequest, 0, returnRequest, 0, 2 + data.Length);
  466. Array.Copy(footer, 0, returnRequest, 2 + data.Length, index);
  467. return returnRequest;
  468. }
  469. catch (Exception ex)
  470. {
  471. Trace.WriteLine("Exception PreparePendingRequest! " + ex.Message + " - " + ex.StackTrace);
  472. }
  473. return null;
  474. }
  475. private bool CheckResponse(byte[] pollingResponse)
  476. {
  477. return true;
  478. }
  479. private byte[] ReadByte(NetworkStream networkStream, out int nread, int iDartRWTimeout)
  480. {
  481. byte[] b = new byte[1];
  482. int timeout = 0;
  483. nread = 0;
  484. try
  485. {
  486. // waits 200 msec 10*10 + 2*50
  487. int retries = 0;
  488. while (timeout < iDartRWTimeout)
  489. {
  490. if (networkStream.DataAvailable)
  491. {
  492. nread = networkStream.Read(b, 0, 1);
  493. return b;
  494. }
  495. else if (retries < 10)
  496. {
  497. Thread.Sleep(10);
  498. timeout += 10;
  499. }
  500. else
  501. {
  502. Thread.Sleep(50);
  503. timeout += 50;
  504. }
  505. retries++;
  506. Trace.WriteLineIf(Trace.CheckTraceLevel(5), string.Format("ReadByte retries={0}", retries));
  507. }
  508. }
  509. catch (IOException ex)
  510. {
  511. Trace.WriteLine(string.Format("IOException in ReadByte! networkStream.Connected={0}: {1} - {2}", this.optTCP.OptSocket.Client.Connected, ex.Message, ex.StackTrace));
  512. networkStream.Write(new byte[0], 0, 0);
  513. if (ex.InnerException != null)
  514. Trace.WriteLine("IOException InnerException: " + ex.InnerException.Message+ " - " + ex.InnerException.StackTrace);
  515. }
  516. return null;
  517. }
  518. private byte[] ReadResponse(out MsgType responseType, out byte rxNum, out bool crcresult, bool bOnlyCheckDataPresent)
  519. {
  520. rxNum = 0;
  521. crcresult = true;
  522. try
  523. {
  524. int nreadzero = 0;
  525. responseType = MsgType.Present;
  526. NetworkStream networkStream = null;
  527. networkStream = this.optTCP.OptSocket.GetStream();
  528. int iDartRWTimeout = 1500;
  529. string sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "OPT" + opt.Id.ToString(), "OPTDartRWTimeout");
  530. if (sValue.Length > 0)
  531. iDartRWTimeout = Convert.ToInt32(sValue);
  532. if (bOnlyCheckDataPresent)
  533. iDartRWTimeout = 200;
  534. //networkStream.ReadTimeout = iDartRWTimeout;
  535. networkStream.WriteTimeout = iDartRWTimeout;
  536. Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TPRead init: tp={0}, read timeout={1}", optTCP.Id, iDartRWTimeout));
  537. int iRetryReadZero = 1;
  538. //sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "OPT" + opt.Id.ToString(), "OPTNumRetryZeroReading");
  539. //if (sValue.Length > 0)
  540. // iRetryReadZero = Convert.ToInt32(sValue);
  541. //bool bSimulateReadTimeout;
  542. //sValue = IniFile.IniReadValue(ConfigurationParams.inifile, "OPT" + opt.Id.ToString(), "SimulateReadTimeout");
  543. //if (sValue.Length > 0 && sValue == "1")
  544. //{
  545. // Trace.WriteLine(string.Format("TPRead tp={0} SimulateReadTimeout", optTCP.Id));
  546. // IniFile.IniWriteValue(ConfigurationParams.inifile, "OPT" + opt.Id.ToString(), "SimulateReadTimeout", "0");
  547. // return null;
  548. //}
  549. // read 2 bytes header
  550. byte[] header = null;
  551. byte[] b = new byte[1];
  552. int i;
  553. header = new byte[OptTCP.HeaderLength];
  554. int nread = 0, nreadtot = 0;
  555. do
  556. {
  557. //Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("optPollerThreadProc: reading ..."));
  558. b = ReadByte(networkStream, out nread, iDartRWTimeout);
  559. if (nread > 0)
  560. header[nreadtot] = b[0];
  561. else if (bOnlyCheckDataPresent)
  562. {
  563. return null;
  564. }
  565. nreadtot += nread;
  566. if (nread == 0)
  567. {
  568. nreadzero++;
  569. Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TPRead tp={0} read 0 bytes nreadzero={1}", optTCP.Id, nreadzero));
  570. if (nreadzero == iRetryReadZero)
  571. {
  572. responseType = MsgType.Unknown;
  573. Trace.WriteLine(string.Format("TPRead tp={0} read 0 bytes ! return NULL!", optTCP.Id));
  574. return null;
  575. }
  576. }
  577. else
  578. nreadzero = 0;
  579. }
  580. while (nreadtot < OptTCP.HeaderLength);
  581. // recognize response type
  582. if (header[1] == 0x20)
  583. responseType = MsgType.Polling;
  584. else if (header[1] == 0x70)
  585. responseType = MsgType.Present;
  586. else if (header[1] >= 0xC0 && header[1] <= 0xCF)
  587. {
  588. responseType = MsgType.Ack;
  589. rxNum = (byte)(header[1] - 0xC0);
  590. }
  591. else if (header[1] >= 0x50 && header[1] <= 0x5F)
  592. {
  593. responseType = MsgType.Nack;
  594. rxNum = (byte)(header[1] - 0x50);
  595. }
  596. else if (header[1] >= 0x30 && header[1] <= 0x3F)
  597. {
  598. responseType = MsgType.Data;
  599. rxNum = (byte)(header[1] - 0x30);
  600. }
  601. else
  602. {
  603. Trace.WriteLine(string.Format("TPRead tp={0} code='{1}' is INVALID ! Close socket!", optTCP.Id, header[1]));
  604. optTCP.CloseSocket(networkStream);
  605. responseType = MsgType.Unknown;
  606. return null;
  607. }
  608. Trace.WriteLineIf(Trace.CheckTraceLevel(2), string.Format("TPRead tp={0} code={1}, rxNum={2}", optTCP.Id, responseType, rxNum));
  609. byte[] buffer = null;
  610. int bufferLength;
  611. if (responseType != MsgType.Data)
  612. bufferLength = 1;
  613. else
  614. bufferLength = 2;
  615. buffer = new byte[bufferLength];
  616. nread = 0;
  617. nreadtot = 0;
  618. do
  619. {
  620. //Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("optPollerThreadProc: reading ..."));
  621. b = ReadByte(networkStream, out nread, iDartRWTimeout);
  622. if (nread > 0)
  623. buffer[nreadtot] = b[0];
  624. nreadtot += nread;
  625. if (nread == 0)
  626. {
  627. nreadzero++;
  628. Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TPRead tp={0} read 0 bytes nreadzero={1}", optTCP.Id, nreadzero));
  629. if (nreadzero == iRetryReadZero)
  630. {
  631. responseType = MsgType.Unknown;
  632. Trace.WriteLine(string.Format("TPRead tp={0} read 0 bytes ! return NULL!", optTCP.Id));
  633. return null;
  634. }
  635. }
  636. else
  637. nreadzero = 0;
  638. }
  639. while (nreadtot < bufferLength);
  640. byte[] data = null;
  641. byte[] optResponse = null;
  642. int msglength = 0;
  643. if (responseType == MsgType.Data)
  644. {
  645. msglength = GetMsgLength(buffer);
  646. //--data = new byte[msglength - 2 + OptTCP.FooterLength];
  647. data = new byte[msglength - bufferLength];
  648. Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("TPRead tp={0} data msg length={1}, msglength={2}, bufferLength={3}", optTCP.Id, data.GetLength(0), msglength, bufferLength));
  649. nread = 0;
  650. nreadtot = 0;
  651. do
  652. {
  653. //Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("optPollerThreadProc: reading ..."));
  654. b = ReadByte(networkStream, out nread, iDartRWTimeout);
  655. if (nread > 0)
  656. data[nreadtot] = b[0];
  657. nreadtot += nread;
  658. if (nread == 0)
  659. {
  660. nreadzero++;
  661. Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TPRead tp={0} read 0 bytes nreadzero={1}", optTCP.Id, nreadzero));
  662. if (nreadzero == iRetryReadZero)
  663. {
  664. responseType = MsgType.Unknown;
  665. Trace.WriteLine(string.Format("TPRead tp={0} read 0 bytes ! return NULL!", optTCP.Id));
  666. return null;
  667. }
  668. }
  669. else
  670. nreadzero = 0;
  671. }
  672. //--while (nreadtot < msglength - 2 + OptTCP.FooterLength);
  673. while (nreadtot < msglength - bufferLength);
  674. Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TPRead tp={0}, nreadtot={1} ", optTCP.Id, nreadtot));
  675. // remove 2 bytes header (leave the length) and the footer for the response message
  676. optResponse = new byte[msglength];
  677. Array.Copy(buffer, 0, optResponse, 0, bufferLength);
  678. //--Array.Copy(data, 0, optResponse, 2, msglength-2);
  679. Array.Copy(data, 0, optResponse, bufferLength, msglength-bufferLength);
  680. Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TPRead copiato tp={0}, nreadtot={1} ", optTCP.Id, nreadtot));
  681. //-- read the footer
  682. bool exit = false;
  683. nread = 0;
  684. nreadtot = 0;
  685. byte[] footer = new byte[OptTCP.FooterLength + 2];
  686. do
  687. {
  688. b = ReadByte(networkStream, out nread, iDartRWTimeout);
  689. if (nread > 0)
  690. {
  691. footer[nreadtot] = b[0];
  692. if (nreadtot > 1 && footer[nreadtot] == 0xFA && footer[nreadtot - 1] != 0x10)
  693. exit = true;
  694. }
  695. nreadtot += nread;
  696. if (nread == 0)
  697. {
  698. nreadzero++;
  699. Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TPRead tp={0} read 0 bytes nreadzero={1}", optTCP.Id, nreadzero));
  700. if (nreadzero == iRetryReadZero)
  701. {
  702. responseType = MsgType.Unknown;
  703. Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TPRead tp={0} read 0 bytes ! return NULL!", optTCP.Id));
  704. return null;
  705. }
  706. }
  707. else
  708. nreadzero = 0;
  709. }
  710. while (!exit);
  711. int footerlength = nreadtot;
  712. Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("TPRead tp={0}, footerlength={1}", optTCP.Id, footerlength));
  713. //--byte[] message = new byte[OptTCP.HeaderLength + bufferLength + msglength];
  714. byte[] message = new byte[OptTCP.HeaderLength + msglength + footerlength];
  715. Array.Copy(header, 0, message, 0, OptTCP.HeaderLength);
  716. Array.Copy(buffer, 0, message, OptTCP.HeaderLength, bufferLength);
  717. //--Array.Copy(data, 0, message, OptTCP.HeaderLength, msglength - 2 + OptTCP.FooterLength);
  718. Array.Copy(data, 0, message, OptTCP.HeaderLength + bufferLength, msglength-bufferLength);
  719. Array.Copy(footer, 0, message, OptTCP.HeaderLength + msglength, footerlength); // check crc
  720. //--bool crcresult = this.CheckCrc(message, message.Length - 4);
  721. crcresult = this.CheckCrc(message, message.Length - footerlength);
  722. Trace.WriteLine(string.Format("TPRead tp={0}, message={1}, crcresult={2}", optTCP.Id, ASCIIEncoding.ASCII.GetString(message, 0, message.GetLength(0)), crcresult));
  723. //Trace.WriteLine(string.Format("TPRead tp={0}, response={1}", optTCP.Id, ASCIIEncoding.ASCII.GetString(optResponse, 0, optResponse.GetLength(0))));
  724. }
  725. else
  726. {
  727. // check transmission number
  728. // ...
  729. }
  730. return optResponse;
  731. }
  732. catch (SocketException sex)
  733. {
  734. Trace.WriteLine(string.Format("tp={0} socket Exception in ReadResponse! {1}: {2} - {3}", optTCP.Id, sex.ErrorCode, sex.Message, sex.StackTrace));
  735. responseType = MsgType.Unknown;
  736. }
  737. catch (IOException ex)
  738. {
  739. Trace.WriteLine(string.Format("tp={0} IOException in ReadResponse! {1} - {2}", optTCP.Id, ex.Message, ex.StackTrace));
  740. if (ex.InnerException != null)
  741. Trace.WriteLine(string.Format("tp={0} IOException InnerException: {1} - {2}", optTCP.Id, ex.InnerException.Message, ex.InnerException.StackTrace));
  742. responseType = MsgType.Unknown;
  743. }
  744. catch (Exception ex)
  745. {
  746. Trace.WriteLine(string.Format("tp={0} Exception in ReadResponse! {1} - {2}", optTCP.Id, ex.Message, ex.StackTrace));
  747. responseType = MsgType.Unknown;
  748. }
  749. return null;
  750. }
  751. private int GetMsgLength(byte[] header)
  752. {
  753. int length = 0;
  754. length = (int)((header[0] & 0x0F) + ((header[1] & 0x0F) << 4));
  755. //switch (responseCode)
  756. //{
  757. // case 0x3a: length = 2; break;
  758. // case 0x3d: length = 33; break;
  759. // case 0x3f: length = 21; break;
  760. // case 0x5a: length = 48; break;
  761. // case 0x3d: length = 111; break;
  762. // case 0x40: length = 5; break;
  763. // case 0x53: length = 186; break;
  764. // case 0x56: length = 63; break;
  765. // case 0x59: length = 203; break;
  766. // case 0x5b: length = 80; break;
  767. // case 0x5c: length = 16; break;
  768. // case 0x5d: length = 11; break;
  769. // case 0x66: length = 4; break;
  770. //}
  771. Trace.WriteLineIf(Trace.CheckTraceLevel(3), string.Format("optPollerThreadProc: getMsgLength length={0}", length));
  772. return length;
  773. }
  774. private bool IsPendingRequest()
  775. {
  776. return (optTCP.OptRequestQueue.Count > 0);
  777. }
  778. private byte[] GetPendingRequest()
  779. {
  780. return optTCP.OptRequestQueue.Dequeue();
  781. }
  782. private int Write(byte[] message)
  783. {
  784. //return optTCP.OptSocket.Client.Send(message);
  785. try
  786. {
  787. if (message == null)
  788. {
  789. Trace.WriteLine(string.Format("TPWrite tp={0}, msg='null'", optTCP.Id));
  790. return -2;
  791. }
  792. Trace.WriteLine(string.Format("TPWrite tp={0}, msg='{1}'", optTCP.Id, ASCIIEncoding.ASCII.GetString(message, 0, message.GetLength(0))));
  793. this.optTCP.OptSocket.GetStream().Write(message, 0, message.Length);
  794. }
  795. catch (SocketException sex)
  796. {
  797. Trace.WriteLine(string.Format("tp={0} socket Exception in Write! {1}: {2} - {3}", optTCP.Id, sex.ErrorCode, sex.Message, sex.StackTrace));
  798. return -1;
  799. }
  800. catch (IOException ex)
  801. {
  802. Trace.WriteLine("IOException in Write! " + ex.Message + " - " + ex.StackTrace);
  803. if (ex.InnerException != null)
  804. Trace.WriteLine(string.Format("tp={0} IOException InnerException: {1} - {2}", optTCP.Id, ex.InnerException.Message, ex.InnerException.StackTrace));
  805. return -1;
  806. }
  807. catch (Exception ex)
  808. {
  809. Trace.WriteLine(string.Format("tp={0} Exception in Write! {1} - {2}", optTCP.Id, ex.Message, ex.StackTrace));
  810. return -1;
  811. }
  812. return 0;
  813. }
  814. private bool CheckCrc(byte[] bufferToCheck, int len)
  815. {
  816. UInt16 crc = Crc.CalcWayneCrc(0x0000, bufferToCheck, len);
  817. int posLow = 0, posHigh = 1;
  818. if (bufferToCheck[len] == 0x10 && bufferToCheck[len + 1] == 0xFA)
  819. {
  820. posLow++;
  821. posHigh++;
  822. }
  823. if (bufferToCheck[len + posHigh] == 0x10 && bufferToCheck[len + posHigh + 1] == 0xFA)
  824. posHigh++;
  825. return (((byte)(crc >> 8) == bufferToCheck[len + posHigh]) && ((byte)(crc) == bufferToCheck[len + posLow]));
  826. }
  827. }
  828. internal class OptTCP
  829. {
  830. public static int HeaderLength = 2;
  831. public static int FooterLength = 4;
  832. public static int PollResponseLength = 3;
  833. public static int PollRequestLength = 3;
  834. public bool bPollerRunning = false;
  835. private string _sIPAddress = "";
  836. public string sIPAddress
  837. {
  838. get { return _sIPAddress; }
  839. }
  840. private int _IPPort = 0;
  841. public int IPPort
  842. {
  843. get { return _IPPort; }
  844. }
  845. private TcpClient _OptSocket = null;
  846. public TcpClient OptSocket
  847. {
  848. get { return _OptSocket; }
  849. set { _OptSocket = value; }
  850. }
  851. public int Id;
  852. private FUSIONOpt _opt;
  853. public FUSIONOpt Opt
  854. {
  855. get { return _opt; }
  856. }
  857. public OptPollerThreadObj optPollerThreadObj;
  858. public Thread optPollerThread;
  859. private Queue<byte[]> _OptRequestQueue = null;
  860. public Queue<byte[]> OptRequestQueue
  861. {
  862. get { return _OptRequestQueue; }
  863. }
  864. private AsyncResponseManager _asyncResponseManager;
  865. public AsyncResponseManager asyncResponseManager
  866. {
  867. get
  868. {
  869. return this._asyncResponseManager;
  870. }
  871. }
  872. //private DeviceConnectionState _ConnectionState = DeviceConnectionState.Disconnected;
  873. public DeviceConnectionState ConnectionState
  874. {
  875. get { return this._opt.ConnectionState; }
  876. set
  877. {
  878. if (this._opt.ConnectionState != value)
  879. {
  880. this._opt.WritableConnectionState = value;
  881. //if (this._opt.WritableConnectionState == DeviceConnectionState.Disconnected)
  882. // Connect();
  883. }
  884. }
  885. }
  886. public event EventHandler<ConnectionChangedEventArgs> OnConnectionStateChange;
  887. public OptTCP(int Id, string sIPAddress, int IPPort, FUSIONOpt opt)
  888. {
  889. this.Id = Id;
  890. _sIPAddress = sIPAddress;
  891. _IPPort = IPPort;
  892. _OptRequestQueue = new Queue<byte[]>();
  893. _opt = opt;
  894. bPollerRunning = false;
  895. //this._asyncResponseManager = new AsyncResponseManager();
  896. //this._asyncResponseManager.OnResponseTimeout += new EventHandler(asyncResponseManager_OnResponseTimeout);
  897. //OnMessageEnqueuing += new EventHandler<MessageEnqueuedEventArgs>(this.asyncResponseManager.OnMessageEnqueuing);
  898. }
  899. public bool Connect()
  900. {
  901. Trace.WriteLine(string.Format("OptTCP tp={0} Connect", this.Id));
  902. if ((this.ConnectionState == DeviceConnectionState.Disconnected) || (this.ConnectionState == DeviceConnectionState.Disconnecting))
  903. {
  904. if (optPollerThreadObj != null && !optPollerThreadObj.bTerminate)
  905. optPollerThreadObj.bTerminate = true;
  906. this.ConnectionState = DeviceConnectionState.Connecting;
  907. optPollerThreadObj = new OptPollerThreadObj(this, this._opt);
  908. optPollerThread = new Thread(new ThreadStart(optPollerThreadObj.optPollerThreadProc));
  909. optPollerThread.Start();
  910. }
  911. return true;
  912. }
  913. public void CloseSocket(NetworkStream networkStream)
  914. {
  915. try
  916. {
  917. if (networkStream != null)
  918. {
  919. networkStream.Close();
  920. Trace.WriteLine("optPollerThreadProc networkStream closed");
  921. }
  922. }
  923. catch (Exception ex3)
  924. {
  925. Trace.WriteLine("optPollerThreadProc EXCEPTION on closing networkStream!" + ex3.Message + " - " + ex3.StackTrace);
  926. }
  927. try
  928. {
  929. if (this.OptSocket != null)
  930. {
  931. this.OptSocket.Client.Close();
  932. Trace.WriteLine("optPollerThreadProc optTCP.OptSocket.Client closed");
  933. }
  934. }
  935. catch (Exception ex3)
  936. {
  937. Trace.WriteLine("optPollerThreadProc EXCEPTION on closing socket!" + ex3.Message + " - " + ex3.StackTrace);
  938. }
  939. try
  940. {
  941. if (this.OptSocket != null)
  942. {
  943. this.OptSocket.Close();
  944. Trace.WriteLine("optPollerThreadProc optTCP.OptSocket closed");
  945. }
  946. }
  947. catch (Exception ex3)
  948. {
  949. Trace.WriteLine("optPollerThreadProc EXCEPTION on closing socket!" + ex3.Message + " - " + ex3.StackTrace);
  950. }
  951. }
  952. public void Disconnect()
  953. {
  954. try
  955. {
  956. if (OptSocket != null)
  957. {
  958. this.optPollerThreadObj.bTerminate = true;
  959. Trace.WriteLine(string.Format("OptTCP tp={0} Disconnect - closing stream", this.Id));
  960. OptSocket.GetStream().Close();
  961. Trace.WriteLine(string.Format("OptTCP tp={0} Disconnect - closing socket", this.Id));
  962. this.OptSocket.Close();
  963. }
  964. }
  965. catch(Exception ex)
  966. {
  967. Trace.WriteLine("Exception in Disconnect! " + ex.Message + " - " + ex.StackTrace);
  968. }
  969. this._OptSocket = null;
  970. this.OptRequestQueue.Clear();
  971. this.ConnectionState = DeviceConnectionState.Disconnected;
  972. }
  973. public void OptWrite(byte[] message, EventHandler<OptWriteCompletedEventArgs> requestCompleted, object userToken, object src)
  974. {
  975. try
  976. {
  977. EnqueueMessage(message, requestCompleted, userToken, src, true, null);//, new OptWriteCompletedEventArgs(true, userToken, 0));
  978. }
  979. catch (Exception ex)
  980. {
  981. Trace.WriteLine("Exception! " + ex.Message + " - " + ex.StackTrace);
  982. }
  983. }
  984. public void EnqueueMessage(byte[] request, EventHandler<OptWriteCompletedEventArgs> requestCompleted, object userToken, object src, bool responseRequired, OptWriteCompletedEventArgs resultOptWrite)
  985. {
  986. //Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("EnqueueMessage(opt) init: tp={0}", this._opt.Id));
  987. // enqueue the object in the socket elaboration queue
  988. Monitor.Enter(OptRequestQueue);
  989. OptRequestQueue.Enqueue(request);
  990. Monitor.Exit(OptRequestQueue);
  991. //Trace.WriteLineIf(Trace.CheckTraceLevel(4), string.Format("EnqueueMessage(opt) end: tp={0}", this._opt.Id));
  992. }
  993. }
  994. }