FinsDataDevice.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net.Sockets;
  5. using System.Runtime.InteropServices;
  6. using Aitex.Core.RT.IOCore;
  7. using Aitex.Core.RT.Log;
  8. using Aitex.Core.Util;
  9. using Aitex.Triton160.RT;
  10. using Aitex.Triton160.RT.PLC;
  11. namespace Aitex.Core.RT.PLC
  12. {
  13. public enum BlockType
  14. {
  15. CIO = 0x30,
  16. WR = 0x31,
  17. D = 0x82,
  18. }
  19. public class GroupFinsDataDevice : IDataDevice
  20. {
  21. private Dictionary<string, FinsDataDevice> _devices = new Dictionary<string, FinsDataDevice>()
  22. {
  23. {"local", new FinsDataDevice(RtInstance.LocalPlcIpAddress,
  24. RtInstance.LocalPlcIoBaseDi, RtInstance.LocalPlcDiBlockLength, RtInstance.LocalPlcDiType,
  25. RtInstance.LocalPlcIoBaseDo, RtInstance.LocalPlcDoBlockLength, RtInstance.LocalPlcDoType,
  26. RtInstance.LocalPlcIoBaseAi, RtInstance.LocalPlcAiBlockLength, RtInstance.LocalPlcAiType,
  27. RtInstance.LocalPlcIoBaseAo, RtInstance.LocalPlcAoBlockLength, RtInstance.LocalPlcAoType )},
  28. };
  29. public bool IsOpened
  30. {
  31. get
  32. {
  33. foreach (var device in _devices)
  34. {
  35. if (!device.Value.IsOpened)
  36. return false;
  37. }
  38. return true;
  39. }
  40. }
  41. public bool Open()
  42. {
  43. foreach (var device in _devices)
  44. {
  45. if (!device.Value.Open())
  46. return false;
  47. }
  48. return true;
  49. }
  50. public void Close()
  51. {
  52. foreach (var device in _devices)
  53. {
  54. device.Value.Close();
  55. }
  56. }
  57. public object Read<T>(string type)
  58. {
  59. if (!_devices.ContainsKey(type))
  60. {
  61. LOG.Error("read undefined PLC type " + type);
  62. return null;
  63. }
  64. return _devices[type].Read<T>();
  65. }
  66. public bool Write<T>(string type, T buffer)
  67. {
  68. if (!_devices.ContainsKey(type))
  69. {
  70. LOG.Error("write undefined PLC type " + type);
  71. return false;
  72. }
  73. return _devices[type].Write<T>(buffer);
  74. }
  75. public List<string> GetTypes()
  76. {
  77. return _devices.Keys.ToList();
  78. }
  79. public bool IsOpen(string type)
  80. {
  81. return _devices[type].IsOpen(type);
  82. }
  83. public bool Open(string type)
  84. {
  85. return _devices[type].Open(type);
  86. }
  87. public void Close(string type)
  88. {
  89. _devices[type].Close(type);
  90. }
  91. }
  92. public class FinsDataDevice : IDataDevice
  93. {
  94. public bool IsOpened
  95. {
  96. get
  97. {
  98. return _isOpened;
  99. }
  100. }
  101. private TcpClient msender;
  102. private Socket msock;
  103. private byte[] Client, Server;
  104. private bool _isOpened = false;
  105. private string _ip = "192.168.10.10";
  106. private int port = 9600;
  107. private int _diStartPosition;
  108. private int _diLength;
  109. private BlockType _diBlockType;
  110. private int _doStartPosition;
  111. private int _doLength;
  112. private BlockType _doBlockType;
  113. private int _aiStartPosition;
  114. private int _aiLength;
  115. private BlockType _aiBlockType;
  116. private int _aoStartPosition;
  117. private int _aoLength;
  118. private BlockType _aoBlockType;
  119. private R_TRIG _failedTrigger = new R_TRIG();
  120. private DeviceTimer _timerWrite = new DeviceTimer();
  121. private DeviceTimer _timerRead = new DeviceTimer();
  122. public FinsDataDevice(string ip, int diStartPosition, int diLength, BlockType diBlockType,
  123. int doStartPosition, int doLength, BlockType doBlockType,
  124. int aiStartPosition, int aiLength, BlockType aiBlockType,
  125. int aoStartPosition, int aoLength, BlockType aoBlockType)
  126. {
  127. _ip = ip;
  128. _diStartPosition = diStartPosition;
  129. _diLength = diLength;
  130. _diBlockType = diBlockType;
  131. _doStartPosition = doStartPosition;
  132. _doLength = doLength;
  133. _doBlockType = doBlockType;
  134. _aiStartPosition = aiStartPosition;
  135. _aiLength = aiLength;
  136. _aiBlockType = aiBlockType;
  137. _aoStartPosition = aoStartPosition;
  138. _aoLength = aoLength;
  139. _aoBlockType = aoBlockType;
  140. }
  141. public bool Open()
  142. {
  143. if (string.IsNullOrEmpty(_ip))
  144. return true;
  145. try
  146. {
  147. Close();
  148. _isOpened = false;
  149. msender = new TcpClient(_ip, port);
  150. msock = msender.Client;
  151. msock.Send(HandShake());
  152. byte[] buffer = new byte[24];
  153. msock.Receive(buffer, SocketFlags.None);
  154. {
  155. Client = new byte[4];
  156. Client[0] = buffer[16];
  157. Client[1] = buffer[17];
  158. Client[2] = buffer[18];
  159. Client[3] = buffer[19];
  160. Server = new byte[4];
  161. Server[0] = buffer[20];
  162. Server[1] = buffer[21];
  163. Server[2] = buffer[22];
  164. Server[3] = buffer[23];
  165. }
  166. _isOpened = true;
  167. }
  168. catch (Exception ex)
  169. {
  170. _failedTrigger.CLK = true;
  171. if (_failedTrigger.Q)
  172. {
  173. LOG.Write(ex, String.Format("Communication failed with PLC {0}:{1}", _ip, port));
  174. }
  175. return false;
  176. }
  177. _failedTrigger.RST = true;
  178. _isOpened = true;
  179. LOG.Write(String.Format("连接成功,PLC {0}:{1}", _ip, port));
  180. return true;
  181. }
  182. public void Close()
  183. {
  184. if (string.IsNullOrEmpty(_ip))
  185. return;
  186. try
  187. {
  188. if (_isOpened)
  189. {
  190. LOG.Write(String.Format("关闭连接,PLC {0}:{1}", _ip, port));
  191. _isOpened = false;
  192. msender.Close();
  193. }
  194. }
  195. catch (Exception ex)
  196. {
  197. LOG.Write(ex);
  198. }
  199. }
  200. public object Read<T>()
  201. {
  202. PLC_INPUT_DATA buf = new PLC_INPUT_DATA();
  203. buf.DI = new Byte[IOGroupManager.DioBlockLength];
  204. buf.AI = new float[IOGroupManager.AioBlockLength];
  205. if (string.IsNullOrEmpty(_ip))
  206. return buf;
  207. try
  208. {
  209. ReadBlock<byte>(_diBlockType, (ushort)_diStartPosition, (ushort)_diLength, ref buf.DI);
  210. ReadBlock_float(_aiBlockType, (ushort)_aiStartPosition, (ushort)_aiLength, ref buf.AI);
  211. return buf;
  212. }
  213. catch (Exception ex)
  214. {
  215. LOG.Error(String.Format("PLC ({0}) Read exception.", _ip), ex);
  216. Close();
  217. }
  218. return null;
  219. }
  220. public bool Write<T>(T buffer)
  221. {
  222. if (string.IsNullOrEmpty(_ip))
  223. return true;
  224. try
  225. {
  226. _timerWrite.Start(0);
  227. PLC_OUTPUT_DATA buf = (PLC_OUTPUT_DATA)(object)buffer;
  228. WriteBlock_hex(_aoBlockType, (ushort)_aoStartPosition, (ushort)_aoLength, buf.AO);
  229. WriteBlock_Byte(_doBlockType, (ushort)_doStartPosition, (ushort)_doLength, buf.DO);
  230. //WriteBlock_float(_aoBlockType, (ushort)_aoStartPosition, (ushort)_aoLength, buf.AO);
  231. //double interval = _timerWrite.GetElapseTime();
  232. //if (interval > _averageWriteTime)
  233. //{
  234. // LOG.Write(_ip + ":Max write PLC interval : " + interval);
  235. // _averageWriteTime = interval;
  236. //}
  237. return true;
  238. }
  239. catch (Exception ex)
  240. {
  241. LOG.Error(String.Format("PLC ({0})Write exception.", _ip), ex);
  242. Close();
  243. return false;
  244. }
  245. }
  246. private void ReadBlock<T>(BlockType type, ushort addr, ushort len, ref T[] data)
  247. {
  248. byte[] FullCmd = new byte[34];
  249. //TCP FINS header
  250. FullCmd[0] = 0x46;//F
  251. FullCmd[1] = 0x49;//I
  252. FullCmd[2] = 0x4e;//N
  253. FullCmd[3] = 0x53;//S
  254. FullCmd[4] = 0;//cmd length
  255. FullCmd[5] = 0;
  256. FullCmd[6] = 0;
  257. FullCmd[7] = 0x1A;
  258. FullCmd[8] = 0;//frame command
  259. FullCmd[9] = 0;
  260. FullCmd[10] = 0;
  261. FullCmd[11] = 0x02;
  262. FullCmd[12] = 0;//err
  263. FullCmd[13] = 0;
  264. FullCmd[14] = 0;
  265. FullCmd[15] = 0;
  266. //command frame header
  267. FullCmd[16] = 0x80;//ICF
  268. FullCmd[17] = 0x00;//RSV
  269. FullCmd[18] = 0x02;//GCT, less than 8 network layers
  270. FullCmd[19] = 0x00;//DNA, local network
  271. FullCmd[20] = Server[3];//DA1
  272. FullCmd[21] = 0x00;//DA2, CPU unit
  273. FullCmd[22] = 0x00;//SNA, local network
  274. FullCmd[23] = Client[3];//SA1
  275. FullCmd[24] = 0x00;//SA2, CPU unit
  276. FullCmd[25] = Convert.ToByte(21);//SID
  277. FullCmd[26] = 0x01; //FINS CMD Main Request Code 0101 Read IO Area
  278. FullCmd[27] = 0x01; //Sub Request Code
  279. //Parameter
  280. FullCmd[28] = (byte)type;
  281. FullCmd[29] = (byte)((addr >> 8) & 0xFF); //Block Add
  282. FullCmd[30] = (byte)(addr & 0xFF);
  283. FullCmd[31] = 0; //Bit Add
  284. FullCmd[32] = (byte)((len >> 8) & 0xFF); ; //Read Count
  285. FullCmd[33] = (byte)(len & 0xFF);
  286. msock.Send(FullCmd, SocketFlags.None);
  287. byte[] buffer = new byte[len + 30];
  288. msock.Receive(buffer);
  289. bool Succeed = true;
  290. if (buffer[11] == 3)
  291. Succeed = CheckHeadError(buffer[15]);
  292. if (Succeed)//no header error
  293. {
  294. T[] buf = new T[len];
  295. Array.Copy(buffer, 30, buf, 0, len);
  296. if (CheckEndCode(buffer[28], buffer[29]))
  297. {
  298. for (int i = 0; i < len; i++)
  299. {
  300. data[i] = buf[i];
  301. }
  302. }
  303. }
  304. }
  305. private void ReadBlock_float(BlockType type, ushort addr, ushort len, ref float[] data)
  306. {
  307. byte[] FullCmd = new byte[34];
  308. //TCP FINS header
  309. FullCmd[0] = 0x46;//F
  310. FullCmd[1] = 0x49;//I
  311. FullCmd[2] = 0x4e;//N
  312. FullCmd[3] = 0x53;//S
  313. FullCmd[4] = 0;//cmd length
  314. FullCmd[5] = 0;
  315. FullCmd[6] = 0;
  316. FullCmd[7] = 0x1A;
  317. FullCmd[8] = 0;//frame command
  318. FullCmd[9] = 0;
  319. FullCmd[10] = 0;
  320. FullCmd[11] = 0x02;
  321. FullCmd[12] = 0;//err
  322. FullCmd[13] = 0;
  323. FullCmd[14] = 0;
  324. FullCmd[15] = 0;
  325. //command frame header
  326. FullCmd[16] = 0x80;//ICF
  327. FullCmd[17] = 0x00;//RSV
  328. FullCmd[18] = 0x02;//GCT, less than 8 network layers
  329. FullCmd[19] = 0x00;//DNA, local network
  330. FullCmd[20] = Server[3];//DA1
  331. FullCmd[21] = 0x00;//DA2, CPU unit
  332. FullCmd[22] = 0x00;//SNA, local network
  333. FullCmd[23] = Client[3];//SA1
  334. FullCmd[24] = 0x00;//SA2, CPU unit
  335. FullCmd[25] = Convert.ToByte(21);//SID
  336. FullCmd[26] = 0x01; //FINS CMD Main Request Code 0101 Read IO Area
  337. FullCmd[27] = 0x01; //Sub Request Code
  338. //Parameter
  339. FullCmd[28] = (byte)type;
  340. FullCmd[29] = (byte)((addr >> 8) & 0xFF); //Block Add
  341. FullCmd[30] = (byte)(addr & 0xFF);
  342. FullCmd[31] = 0; //Bit Add
  343. int count = len * 2;
  344. FullCmd[32] = (byte)((count >> 8) & 0xFF); ; //Read Count
  345. FullCmd[33] = (byte)(count & 0xFF);
  346. msock.Send(FullCmd, SocketFlags.None);
  347. byte[] buffer = new byte[31 + len * 4];
  348. msock.Receive(buffer);
  349. bool Succeed = true;
  350. if (buffer[11] == 3)
  351. Succeed = CheckHeadError(buffer[15]);
  352. if (Succeed)//no header error
  353. {
  354. if (CheckEndCode(buffer[28], buffer[29]))
  355. {
  356. byte[] buf = new byte[4];
  357. for (int i = 0; i < len; i++)
  358. {
  359. buf[0] = buffer[30 + i * 4 + 1];
  360. buf[1] = buffer[30 + i * 4 + 0];
  361. buf[2] = buffer[30 + i * 4 + 3];
  362. buf[3] = buffer[30 + i * 4 + 2];
  363. data[i] = BitConverter.ToSingle(buf, 0);
  364. }
  365. }
  366. }
  367. }
  368. private void WriteBlock_Byte(BlockType type, ushort addr, ushort len, byte[] data)
  369. {
  370. byte[] FullCmd = new byte[34 + len];
  371. //TCP FINS header
  372. FullCmd[0] = 0x46;//F
  373. FullCmd[1] = 0x49;//I
  374. FullCmd[2] = 0x4e;//N
  375. FullCmd[3] = 0x53;//S
  376. int cmdLen = 26 + len;
  377. FullCmd[4] = 0;//cmd length
  378. FullCmd[5] = 0;
  379. FullCmd[6] = (byte)((cmdLen >> 8) & 0xFF);
  380. FullCmd[7] = (byte)(cmdLen & 0xFF);
  381. FullCmd[8] = 0;//frame command
  382. FullCmd[9] = 0;
  383. FullCmd[10] = 0;
  384. FullCmd[11] = 0x02;
  385. FullCmd[12] = 0;//err
  386. FullCmd[13] = 0;
  387. FullCmd[14] = 0;
  388. FullCmd[15] = 0;
  389. //command frame header
  390. FullCmd[16] = 0x80;//ICF
  391. FullCmd[17] = 0x00;//RSV
  392. FullCmd[18] = 0x02;//GCT, less than 8 network layers
  393. FullCmd[19] = 0x00;//DNA, local network
  394. FullCmd[20] = Server[3];//DA1
  395. FullCmd[21] = 0x00;//DA2, CPU unit
  396. FullCmd[22] = 0x00;//SNA, local network
  397. FullCmd[23] = Client[3];//SA1
  398. FullCmd[24] = 0x00;//SA2, CPU unit
  399. FullCmd[25] = Convert.ToByte(21);//SID
  400. FullCmd[26] = 0x01; //FINS CMD Main Request Code 0101 Read IO Area
  401. FullCmd[27] = 0x02; //Sub Request Code
  402. //Parameter
  403. FullCmd[28] = (byte)type;
  404. FullCmd[29] = (byte)((addr >> 8) & 0xFF); //Block Add
  405. FullCmd[30] = (byte)(addr & 0xFF);
  406. FullCmd[31] = 0; //Bit Add
  407. FullCmd[32] = (byte)((len >> 8) & 0xFF); ; //Write Count
  408. FullCmd[33] = (byte)(len & 0xFF);
  409. for (int i = 0; i < len; i++)
  410. {
  411. FullCmd[34 + i] = data[i];
  412. }
  413. msock.Send(FullCmd, SocketFlags.None);
  414. byte[] buffer = new byte[len + 34];
  415. msock.Receive(buffer);
  416. bool Succeed = true;
  417. if (buffer[11] == 3)
  418. Succeed = CheckHeadError(buffer[15]);
  419. if (Succeed)//no header error
  420. {
  421. if (CheckEndCode(buffer[28], buffer[29]))
  422. {
  423. //do nothing
  424. }
  425. }
  426. }
  427. private void WriteBlock_float(BlockType type, ushort addr, ushort len, float[] data)
  428. {
  429. byte[] FullCmd = new byte[34 + len * 4];
  430. //TCP FINS header
  431. FullCmd[0] = 0x46;//F
  432. FullCmd[1] = 0x49;//I
  433. FullCmd[2] = 0x4e;//N
  434. FullCmd[3] = 0x53;//S
  435. int cmdLen = 26 + len * 4;
  436. FullCmd[4] = 0;//cmd length
  437. FullCmd[5] = 0;
  438. FullCmd[6] = (byte)((cmdLen >> 8) & 0xFF);
  439. FullCmd[7] = (byte)(cmdLen & 0xFF);
  440. FullCmd[8] = 0;//frame command
  441. FullCmd[9] = 0;
  442. FullCmd[10] = 0;
  443. FullCmd[11] = 0x02;
  444. FullCmd[12] = 0;//err
  445. FullCmd[13] = 0;
  446. FullCmd[14] = 0;
  447. FullCmd[15] = 0;
  448. //command frame header
  449. FullCmd[16] = 0x80;//ICF
  450. FullCmd[17] = 0x00;//RSV
  451. FullCmd[18] = 0x02;//GCT, less than 8 network layers
  452. FullCmd[19] = 0x00;//DNA, local network
  453. FullCmd[20] = Server[3];//DA1
  454. FullCmd[21] = 0x00;//DA2, CPU unit
  455. FullCmd[22] = 0x00;//SNA, local network
  456. FullCmd[23] = Client[3];//SA1
  457. FullCmd[24] = 0x00;//SA2, CPU unit
  458. FullCmd[25] = Convert.ToByte(21);//SID
  459. FullCmd[26] = 0x01; //FINS CMD Main Request Code 0101 Read IO Area
  460. FullCmd[27] = 0x02; //Sub Request Code
  461. //Parameter
  462. FullCmd[28] = (byte)type;
  463. FullCmd[29] = (byte)((addr >> 8) & 0xFF); //Block Add
  464. FullCmd[30] = (byte)(addr & 0xFF);
  465. FullCmd[31] = 0; //Bit Add
  466. int count = len * 2;
  467. FullCmd[32] = (byte)((count >> 8) & 0xFF); ; //Write Count
  468. FullCmd[33] = (byte)(count & 0xFF);
  469. try
  470. {
  471. for (int i = 0; i < len; i++)
  472. {
  473. byte[] buf = BitConverter.GetBytes(data[i]);
  474. FullCmd[34 + i * 4 + 0] = buf[1];
  475. FullCmd[34 + i * 4 + 1] = buf[0];
  476. FullCmd[34 + i * 4 + 2] = buf[3];
  477. FullCmd[34 + i * 4 + 3] = buf[2];
  478. }
  479. }
  480. catch (Exception ex)
  481. {
  482. LOG.Write(ex);
  483. }
  484. msock.Send(FullCmd, SocketFlags.None);
  485. byte[] buffer = new byte[31 + len * 4];
  486. msock.Receive(buffer);
  487. bool Succeed = true;
  488. if (buffer[11] == 3)
  489. Succeed = CheckHeadError(buffer[15]);
  490. if (Succeed)//no header error
  491. {
  492. if (CheckEndCode(buffer[28], buffer[29]))
  493. {
  494. //do nothing
  495. }
  496. }
  497. }
  498. private void WriteBlock_hex(BlockType type, ushort addr, ushort len, float[] data)
  499. {
  500. byte[] FullCmd = new byte[34 + len * 4];
  501. //TCP FINS header
  502. FullCmd[0] = 0x46;//F
  503. FullCmd[1] = 0x49;//I
  504. FullCmd[2] = 0x4e;//N
  505. FullCmd[3] = 0x53;//S
  506. int cmdLen = 26 + len * 4;
  507. FullCmd[4] = 0;//cmd length
  508. FullCmd[5] = 0;
  509. FullCmd[6] = (byte)((cmdLen >> 8) & 0xFF);
  510. FullCmd[7] = (byte)(cmdLen & 0xFF);
  511. FullCmd[8] = 0;//frame command
  512. FullCmd[9] = 0;
  513. FullCmd[10] = 0;
  514. FullCmd[11] = 0x02;
  515. FullCmd[12] = 0;//err
  516. FullCmd[13] = 0;
  517. FullCmd[14] = 0;
  518. FullCmd[15] = 0;
  519. //command frame header
  520. FullCmd[16] = 0x80;//ICF
  521. FullCmd[17] = 0x00;//RSV
  522. FullCmd[18] = 0x02;//GCT, less than 8 network layers
  523. FullCmd[19] = 0x00;//DNA, local network
  524. FullCmd[20] = Server[3];//DA1
  525. FullCmd[21] = 0x00;//DA2, CPU unit
  526. FullCmd[22] = 0x00;//SNA, local network
  527. FullCmd[23] = Client[3];//SA1
  528. FullCmd[24] = 0x00;//SA2, CPU unit
  529. FullCmd[25] = Convert.ToByte(21);//SID
  530. FullCmd[26] = 0x01; //FINS CMD Main Request Code 0101 Read IO Area
  531. FullCmd[27] = 0x02; //Sub Request Code
  532. //Parameter
  533. FullCmd[28] = (byte)type;
  534. FullCmd[29] = (byte)((addr >> 8) & 0xFF); //Block Add
  535. FullCmd[30] = (byte)(addr & 0xFF);
  536. FullCmd[31] = 0; //Bit Add
  537. int count = len * 2;
  538. FullCmd[32] = (byte)((count >> 8) & 0xFF); ; //Write Count
  539. FullCmd[33] = (byte)(count & 0xFF);
  540. try
  541. {
  542. for (int i = 0; i < len; i++)
  543. {
  544. byte[] buf = BitConverter.GetBytes(data[i]);
  545. FullCmd[34 + i * 4 + 0] = buf[1];
  546. FullCmd[34 + i * 4 + 1] = buf[0];
  547. FullCmd[34 + i * 4 + 2] = buf[3];
  548. FullCmd[34 + i * 4 + 3] = buf[2];
  549. }
  550. }
  551. catch (Exception ex)
  552. {
  553. LOG.Write(ex);
  554. }
  555. msock.Send(FullCmd, SocketFlags.None);
  556. byte[] buffer = new byte[31 + len * 4];
  557. msock.Receive(buffer);
  558. bool Succeed = true;
  559. if (buffer[11] == 3)
  560. Succeed = CheckHeadError(buffer[15]);
  561. if (Succeed)//no header error
  562. {
  563. if (CheckEndCode(buffer[28], buffer[29]))
  564. {
  565. //do nothing
  566. }
  567. }
  568. }
  569. private byte[] HandShake()
  570. {
  571. //handshake
  572. byte[] Handshake = new byte[20];
  573. Handshake[0] = 0x46;
  574. Handshake[1] = 0x49;
  575. Handshake[2] = 0x4e;
  576. Handshake[3] = 0x53;
  577. Handshake[4] = 0;
  578. Handshake[5] = 0;
  579. Handshake[6] = 0;
  580. Handshake[7] = 0x0c;
  581. Handshake[8] = 0;
  582. Handshake[9] = 0;
  583. Handshake[10] = 0;
  584. Handshake[11] = 0;
  585. Handshake[12] = 0;
  586. Handshake[13] = 0;
  587. Handshake[14] = 0;
  588. Handshake[15] = 0;
  589. Handshake[16] = 0;
  590. Handshake[17] = 0;
  591. Handshake[18] = 0;
  592. Handshake[19] = 0;//ask for client and server node number, the client node will allocated automatically
  593. return Handshake;
  594. }
  595. /// <summary>
  596. /// (若返回的头指令为3)检查命令头中的错误代码
  597. /// </summary>
  598. /// <param name="Code">错误代码</param>
  599. /// <returns>指示程序是否可以继续进行</returns>
  600. bool CheckHeadError(byte Code)
  601. {
  602. switch (Code)
  603. {
  604. case 0x00: return true;
  605. case 0x01: RaiseException("the head is not 'FINS'"); return false;
  606. case 0x02: RaiseException("the data length is too long"); return false;
  607. case 0x03: RaiseException("the command is not supported"); return false;
  608. }
  609. //no hit
  610. RaiseException("unknown exception"); return false;
  611. }
  612. private void RaiseException(string p)
  613. {
  614. _isOpened = false;
  615. }
  616. /// <summary>
  617. /// 检查命令帧中的EndCode
  618. /// </summary>
  619. /// <param name="Main">主码</param>
  620. /// <param name="Sub">副码</param>
  621. /// <returns>指示程序是否可以继续进行</returns>
  622. bool CheckEndCode(byte Main, byte Sub)
  623. {
  624. switch (Main)
  625. {
  626. case 0x00:
  627. switch (Sub)
  628. {
  629. case 0x00: return true;//the only situation of success
  630. case 0x01: RaiseException("service canceled"); return false;
  631. }
  632. break;
  633. case 0x01:
  634. switch (Sub)
  635. {
  636. case 0x01: RaiseException("local node not in network"); return false;
  637. case 0x02: RaiseException("token timeout"); return false;
  638. case 0x03: RaiseException("retries failed"); return false;
  639. case 0x04: RaiseException("too many send frames"); return false;
  640. case 0x05: RaiseException("node address range error"); return false;
  641. case 0x06: RaiseException("node address duplication"); return false;
  642. }
  643. break;
  644. case 0x02:
  645. switch (Sub)
  646. {
  647. case 0x01: RaiseException("destination node not in network"); return false;
  648. case 0x02: RaiseException("unit missing"); return false;
  649. case 0x03: RaiseException("third node missing"); return false;
  650. case 0x04: RaiseException("destination node busy"); return false;
  651. case 0x05: RaiseException("response timeout"); return false;
  652. }
  653. break;
  654. case 0x03:
  655. switch (Sub)
  656. {
  657. case 0x01: RaiseException("communications controller error"); return false;
  658. case 0x02: RaiseException("CPU unit error"); return false;
  659. case 0x03: RaiseException("controller error"); return false;
  660. case 0x04: RaiseException("unit number error"); return false;
  661. }
  662. break;
  663. case 0x04:
  664. switch (Sub)
  665. {
  666. case 0x01: RaiseException("undefined command"); return false;
  667. case 0x02: RaiseException("not supported by model/version"); return false;
  668. }
  669. break;
  670. case 0x05:
  671. switch (Sub)
  672. {
  673. case 0x01: RaiseException("destination address setting error"); return false;
  674. case 0x02: RaiseException("no routing tables"); return false;
  675. case 0x03: RaiseException("routing table error"); return false;
  676. case 0x04: RaiseException("too many relays"); return false;
  677. }
  678. break;
  679. case 0x10:
  680. switch (Sub)
  681. {
  682. case 0x01: RaiseException("command too long"); return false;
  683. case 0x02: RaiseException("command too short"); return false;
  684. case 0x03: RaiseException("elements/data don't match"); return false;
  685. case 0x04: RaiseException("command format error"); return false;
  686. case 0x05: RaiseException("header error"); return false;
  687. }
  688. break;
  689. case 0x11:
  690. switch (Sub)
  691. {
  692. case 0x01: RaiseException("area classification missing"); return false;
  693. case 0x02: RaiseException("access size error"); return false;
  694. case 0x03: RaiseException("address range error"); return false;
  695. case 0x04: RaiseException("address range exceeded"); return false;
  696. case 0x06: RaiseException("program missing"); return false;
  697. case 0x09: RaiseException("relational error"); return false;
  698. case 0x0a: RaiseException("duplicate data access"); return false;
  699. case 0x0b: RaiseException("response too long"); return false;
  700. case 0x0c: RaiseException("parameter error"); return false;
  701. }
  702. break;
  703. case 0x20:
  704. switch (Sub)
  705. {
  706. case 0x02: RaiseException("protected"); return false;
  707. case 0x03: RaiseException("table missing"); return false;
  708. case 0x04: RaiseException("data missing"); return false;
  709. case 0x05: RaiseException("program missing"); return false;
  710. case 0x06: RaiseException("file missing"); return false;
  711. case 0x07: RaiseException("data mismatch"); return false;
  712. }
  713. break;
  714. case 0x21:
  715. switch (Sub)
  716. {
  717. case 0x01: RaiseException("read-only"); return false;
  718. case 0x02: RaiseException("protected , cannot write data link table"); return false;
  719. case 0x03: RaiseException("cannot register"); return false;
  720. case 0x05: RaiseException("program missing"); return false;
  721. case 0x06: RaiseException("file missing"); return false;
  722. case 0x07: RaiseException("file name already exists"); return false;
  723. case 0x08: RaiseException("cannot change"); return false;
  724. }
  725. break;
  726. case 0x22:
  727. switch (Sub)
  728. {
  729. case 0x01: RaiseException("not possible during execution"); return false;
  730. case 0x02: RaiseException("not possible while running"); return false;
  731. case 0x03: RaiseException("wrong PLC mode"); return false;
  732. case 0x04: RaiseException("wrong PLC mode"); return false;
  733. case 0x05: RaiseException("wrong PLC mode"); return false;
  734. case 0x06: RaiseException("wrong PLC mode"); return false;
  735. case 0x07: RaiseException("specified node not polling node"); return false;
  736. case 0x08: RaiseException("step cannot be executed"); return false;
  737. }
  738. break;
  739. case 0x23:
  740. switch (Sub)
  741. {
  742. case 0x01: RaiseException("file device missing"); return false;
  743. case 0x02: RaiseException("memory missing"); return false;
  744. case 0x03: RaiseException("clock missing"); return false;
  745. }
  746. break;
  747. case 0x24:
  748. switch (Sub)
  749. { case 0x01: RaiseException("table missing"); return false; }
  750. break;
  751. case 0x25:
  752. switch (Sub)
  753. {
  754. case 0x02: RaiseException("memory error"); return false;
  755. case 0x03: RaiseException("I/O setting error"); return false;
  756. case 0x04: RaiseException("too many I/O points"); return false;
  757. case 0x05: RaiseException("CPU bus error"); return false;
  758. case 0x06: RaiseException("I/O duplication"); return false;
  759. case 0x07: RaiseException("CPU bus error"); return false;
  760. case 0x09: RaiseException("SYSMAC BUS/2 error"); return false;
  761. case 0x0a: RaiseException("CPU bus unit error"); return false;
  762. case 0x0d: RaiseException("SYSMAC BUS No. duplication"); return false;
  763. case 0x0f: RaiseException("memory error"); return false;
  764. case 0x10: RaiseException("SYSMAC BUS terminator missing"); return false;
  765. }
  766. break;
  767. case 0x26:
  768. switch (Sub)
  769. {
  770. case 0x01: RaiseException("no protection"); return false;
  771. case 0x02: RaiseException("incorrect password"); return false;
  772. case 0x04: RaiseException("protected"); return false;
  773. case 0x05: RaiseException("service already executing"); return false;
  774. case 0x06: RaiseException("service stopped"); return false;
  775. case 0x07: RaiseException("no execution right"); return false;
  776. case 0x08: RaiseException("settings required before execution"); return false;
  777. case 0x09: RaiseException("necessary items not set"); return false;
  778. case 0x0a: RaiseException("number already defined"); return false;
  779. case 0x0b: RaiseException("error will not clear"); return false;
  780. }
  781. break;
  782. case 0x30:
  783. switch (Sub)
  784. { case 0x01: RaiseException("no access right"); return false; }
  785. break;
  786. case 0x40:
  787. switch (Sub)
  788. { case 0x01: RaiseException("service aborted"); return false; }
  789. break;
  790. }
  791. //no hit
  792. RaiseException("unknown exception"); return false;
  793. }
  794. public object Read<T>(string type)
  795. {
  796. throw new NotImplementedException();
  797. }
  798. public bool Write<T>(string type, T buffer)
  799. {
  800. throw new NotImplementedException();
  801. }
  802. public List<string> GetTypes()
  803. {
  804. throw new NotImplementedException();
  805. }
  806. public bool IsOpen(string type)
  807. {
  808. if (string.IsNullOrEmpty(_ip))
  809. return true;
  810. return IsOpened;
  811. }
  812. public bool Open(string type)
  813. {
  814. if (string.IsNullOrEmpty(_ip))
  815. return true;
  816. return Open();
  817. }
  818. public void Close(string type)
  819. {
  820. if (string.IsNullOrEmpty(_ip))
  821. return;
  822. Close();
  823. }
  824. }
  825. public class Converter
  826. {
  827. public static byte[] StructToBytes(object obj)
  828. {
  829. int rawsize = Marshal.SizeOf(obj);
  830. IntPtr buffer = Marshal.AllocHGlobal(rawsize);
  831. Marshal.StructureToPtr(obj, buffer, false);
  832. byte[] rawdatas = new byte[rawsize];
  833. Marshal.Copy(buffer, rawdatas, 0, rawsize);
  834. Marshal.FreeHGlobal(buffer);
  835. return rawdatas;
  836. }
  837. public static object BytesToStruct(byte[] buf, int len, Type type)
  838. {
  839. object rtn;
  840. IntPtr buffer = Marshal.AllocHGlobal(len);
  841. Marshal.Copy(buf, 0, buffer, len);
  842. rtn = Marshal.PtrToStructure(buffer, type);
  843. Marshal.FreeHGlobal(buffer);
  844. return rtn;
  845. }
  846. public static void BytesToStruct(byte[] buf, int len, object rtn)
  847. {
  848. IntPtr buffer = Marshal.AllocHGlobal(len);
  849. Marshal.Copy(buf, 0, buffer, len);
  850. Marshal.PtrToStructure(buffer, rtn);
  851. Marshal.FreeHGlobal(buffer);
  852. }
  853. public static void BytesToStruct(byte[] buf, object rtn)
  854. {
  855. BytesToStruct(buf, buf.Length, rtn);
  856. }
  857. public static object BytesToStruct(byte[] buf, Type type)
  858. {
  859. return BytesToStruct(buf, buf.Length, type);
  860. }
  861. }
  862. }