gfamininetmst.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <malloc.h>
  5. #include <fcntl.h>
  6. #include <errno.h>
  7. #include <termios.h>
  8. #include <unistd.h>
  9. #include <ctype.h>
  10. #include <sys/file.h>
  11. #include "gfamininetmst.h"
  12. /////////////////////////////////////////////////////////////////////////////
  13. // https://www.racom.eu/eng/support/prot/mininet/index.html
  14. /////////////////////////////////////////////////////////////////////////////
  15. #define STX ((uint8_t)0x02)
  16. #define ACK ((uint8_t)0x06)
  17. #define SLAVE_IND ((uint8_t)0x80)
  18. #define START_INDEX 0x40
  19. #define MIN_INDEX 0x3F
  20. #define MAX_INDEX 0x7F
  21. #define RESET_INDEX MIN_INDEX
  22. #define STATUS_INDEX_RESET_DONE 0xC0
  23. #define STATUS_INDEX_ERROR 0xC1
  24. #define STATUS_INDEX_CMD_ERROR 0xC2
  25. #define STATUS_INDEX_INVALID_PARAM 0xC3
  26. #define STATUS_INDEX_UNKNOWN_CMD 0xC4
  27. #define STATUS_INDEX_CMD_ALREADY_EX 0xC8
  28. #define MAX_DATA_PAYLOAD_LENGTH 250
  29. #define NODE_IS_BROADCAST(n) ((n) == 0)
  30. #define NODE_IS_GROUPCAST(n) ((((n) & 0xF0) != 0) && (((n) & 0x0F) == 0))
  31. /////////////////////////////////////////////////////////////////////////////
  32. typedef enum _GfaMininetRxStates
  33. {
  34. GfaRxMNS_Stx,
  35. GfaRxMNS_Len,
  36. GfaRxMNS_Node,
  37. GfaRxMNS_Index,
  38. GfaRxMNS_Data,
  39. GfaRxMNS_Zero,
  40. GfaRxMNS_Check
  41. }GfaMininetRxStates, *LPGfaMininetRxStates;
  42. /////////////////////////////////////////////////////////////////////////////
  43. typedef struct _GFA_MININET_MASTER
  44. {
  45. HMINETDEV hDev;
  46. struct timeval tvRXSave;
  47. struct timeval tvTXSave;
  48. uint8_t nIndexTable[256];
  49. }GFA_MININET_MASTER, *LPGFA_MININET_MASTER;
  50. typedef const GFA_MININET_MASTER *LPCGFA_MININET_MASTER;
  51. /////////////////////////////////////////////////////////////////////////////
  52. static bool _IsValidIndex(uint8_t nIndex)
  53. {
  54. return ((nIndex >= MIN_INDEX) && (nIndex <= MAX_INDEX));
  55. }
  56. static uint8_t _GetNextIndex(HGFAMINEMST hMst, uint8_t nNode)
  57. {
  58. if(hMst)
  59. {
  60. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  61. uint8_t idx = ++pMst->nIndexTable[nNode];
  62. if(idx > MAX_INDEX)
  63. {
  64. pMst->nIndexTable[nNode] = START_INDEX;
  65. idx = pMst->nIndexTable[nNode];
  66. }
  67. return idx;
  68. }
  69. return 0xFF;
  70. }
  71. static uint8_t _GetCurIndex(HGFAMINEMST hMst, uint8_t nNode)
  72. {
  73. if(hMst)
  74. {
  75. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  76. return pMst->nIndexTable[nNode];
  77. }
  78. return 0xFF;
  79. }
  80. /////////////////////////////////////////////////////////////////////////////
  81. HGFAMINEMST GfaMininetMasterOpen(LPGFA_MININET_MST_CFG_PARAMS pmmcp)
  82. {
  83. if(pmmcp)
  84. {
  85. HMINETDEV hDev = GfaMininetDeviceOpen(&pmmcp->devcfg);
  86. if(hDev)
  87. {
  88. LPGFA_MININET_MASTER pMst = malloc(sizeof(GFA_MININET_MASTER));
  89. memset(pMst, 0, sizeof(GFA_MININET_MASTER));
  90. memset(pMst->nIndexTable, START_INDEX, sizeof(pMst->nIndexTable));
  91. pMst->hDev = hDev;
  92. return (HGFAMINEMST)pMst;
  93. }
  94. return NULL;
  95. }
  96. errno = EINVAL;
  97. return NULL;
  98. }
  99. /////////////////////////////////////////////////////////////////////////////
  100. void GfaMininetMasterClose(HGFAMINEMST hMst)
  101. {
  102. if(hMst)
  103. {
  104. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  105. GfaMininetDeviceClose(pMst->hDev);
  106. free(pMst);
  107. }
  108. }
  109. /////////////////////////////////////////////////////////////////////////////
  110. bool GfaMininetMasterGetTimeouts(HGFAMINEMST hMst, struct timeval *ptvRX, struct timeval *ptvTX)
  111. {
  112. if(hMst)
  113. {
  114. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  115. return GfaMininetDeviceGetTimeouts(pMst->hDev, ptvRX, ptvTX);
  116. }
  117. errno = EINVAL;
  118. return false;
  119. }
  120. /////////////////////////////////////////////////////////////////////////////
  121. bool GfaMininetMasterSetTimeouts(HGFAMINEMST hMst, const struct timeval *ptvRX, const struct timeval *ptvTX)
  122. {
  123. if(hMst)
  124. {
  125. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  126. return GfaMininetDeviceSetTimeouts(pMst->hDev, ptvRX, ptvTX);
  127. }
  128. errno = EINVAL;
  129. return false;
  130. }
  131. /////////////////////////////////////////////////////////////////////////////
  132. bool GfaMininetMasterSaveTimeouts(HGFAMINEMST hMst)
  133. {
  134. if(hMst)
  135. {
  136. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  137. return GfaMininetMasterGetTimeouts(hMst, &pMst->tvRXSave, &pMst->tvTXSave);
  138. }
  139. errno = EINVAL;
  140. return false;
  141. }
  142. /////////////////////////////////////////////////////////////////////////////
  143. bool GfaMininetMasterRestoreTimeouts(HGFAMINEMST hMst)
  144. {
  145. if(hMst)
  146. {
  147. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  148. return GfaMininetMasterSetTimeouts(hMst, &pMst->tvRXSave, &pMst->tvTXSave);
  149. }
  150. errno = EINVAL;
  151. return false;
  152. }
  153. /////////////////////////////////////////////////////////////////////////////
  154. ssize_t GfaMininetMasterGetConfigParams(HGFAMINEMST hMst, void *pDevParams, size_t nSizeDevParams)
  155. {
  156. if(hMst)
  157. {
  158. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  159. return GfaMininetDeviceGetConfigParams(pMst->hDev, pDevParams, nSizeDevParams);
  160. }
  161. errno = EINVAL;
  162. return false;
  163. }
  164. /////////////////////////////////////////////////////////////////////////////
  165. int GfaMininetMasterSetConfigParams(HGFAMINEMST hMst, const void *pDevParams, size_t nSizeDevParams)
  166. {
  167. if(hMst)
  168. {
  169. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  170. return GfaMininetDeviceSetConfigParams(pMst->hDev, pDevParams, nSizeDevParams);
  171. }
  172. errno = EINVAL;
  173. return false;
  174. }
  175. /////////////////////////////////////////////////////////////////////////////
  176. uint8_t GfaMininetMasterCalcChk(const void *pData, size_t nCbData)
  177. {
  178. size_t i = 0;
  179. uint16_t chk = 0;
  180. uint8_t cc, lc = 0;
  181. const uint8_t *pszData = (const uint8_t*)pData;
  182. for(i = 0; i < nCbData; ++i)
  183. {
  184. cc = *pszData++;
  185. if(cc || (lc != STX))
  186. {
  187. chk <<= 1;
  188. if(chk & 0x0100)
  189. chk = (chk + 1) & 0x00FF;
  190. chk += cc;
  191. if(chk > 0x00FF)
  192. chk = (chk + 1) & 0x00FF;
  193. }
  194. if(i > 4)
  195. lc = cc;
  196. }
  197. if((uint8_t)chk == STX)
  198. chk = ~chk;
  199. return (uint8_t)chk;
  200. }
  201. /////////////////////////////////////////////////////////////////////////////
  202. size_t GfaMininetMasterBuildFrame(HGFAMINEMST hMst, uint8_t nNode, uint8_t nIndex, const void *pDataPayload, size_t nCbDataPayload, void *pFrameBuffer, size_t nCbFrameBuffer)
  203. {
  204. if(hMst && pFrameBuffer && (nCbFrameBuffer >= 5) && (nCbDataPayload <= MAX_DATA_PAYLOAD_LENGTH))
  205. {
  206. int i = 0;
  207. uint8_t b, c;
  208. size_t nLen = 4;
  209. const uint8_t *pszData = (const uint8_t*)pDataPayload;
  210. LPGFA_MININET_FRAME pf = (LPGFA_MININET_FRAME)pFrameBuffer;
  211. pf->stx = STX;
  212. pf->len = 5 + nCbDataPayload;
  213. pf->node = nNode;
  214. pf->index = _IsValidIndex(nIndex) ? nIndex : _GetNextIndex(hMst, nNode);
  215. if(pszData && nCbDataPayload)
  216. {
  217. while(nCbDataPayload--)
  218. {
  219. b = *pszData++;
  220. do
  221. {
  222. if(++nLen == nCbFrameBuffer)
  223. {
  224. errno = ENOMEM;
  225. return 0;
  226. }
  227. pf->data.by[i++] = b;
  228. c = b;
  229. b = 0;
  230. }
  231. while(c == STX);
  232. }
  233. }
  234. pf->data.by[i++] = GfaMininetMasterCalcChk(pFrameBuffer, nLen);
  235. ++nLen;
  236. return nLen;
  237. }
  238. errno = EINVAL;
  239. return 0;
  240. }
  241. /////////////////////////////////////////////////////////////////////////////
  242. ssize_t GfaMininetMasterResetSlaveIndex(HGFAMINEMST hMst, uint8_t nNode)
  243. {
  244. if(hMst)
  245. {
  246. ssize_t nRet;
  247. uint8_t nIndex;
  248. uint8_t txb[16];
  249. uint8_t rxb[16];
  250. if( (nRet = GfaMininetMasterBuildFrame(hMst, nNode, RESET_INDEX, "\x1b\x52", 2, txb, sizeof(txb))) > 0 &&
  251. (nRet = GfaMininetMasterTransmitFrame(hMst, txb, nRet)))
  252. {
  253. if(!NODE_IS_BROADCAST(nNode) && !NODE_IS_GROUPCAST(nNode))
  254. {
  255. // we expect a response
  256. if( (nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), false)) > 0 &&
  257. (nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, nNode, rxb, nRet, false, &nIndex)) == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  258. {
  259. if(nIndex == STATUS_INDEX_RESET_DONE)
  260. return GfaMininetMasterResetLocalIndex(hMst, nNode);
  261. else
  262. {
  263. errno = nIndex;
  264. return -1;
  265. }
  266. }
  267. }
  268. else
  269. {
  270. // we don't expect a response. so let's just hope that all slaves have received the request and have performed an index reset!
  271. return GfaMininetMasterResetLocalIndex(hMst, nNode);
  272. }
  273. }
  274. return nRet;
  275. }
  276. errno = EINVAL;
  277. return -1;
  278. }
  279. /////////////////////////////////////////////////////////////////////////////
  280. ssize_t GfaMininetMasterResetLocalIndex(HGFAMINEMST hMst, uint8_t nNode)
  281. {
  282. if(hMst)
  283. {
  284. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  285. if(NODE_IS_BROADCAST(nNode))
  286. memset(pMst->nIndexTable, START_INDEX, sizeof(pMst->nIndexTable));
  287. else if(NODE_IS_GROUPCAST(nNode))
  288. memset(&pMst->nIndexTable[nNode], START_INDEX, 10);
  289. else
  290. pMst->nIndexTable[nNode] = START_INDEX;
  291. return 0;
  292. }
  293. errno = EINVAL;
  294. return -1;
  295. }
  296. /////////////////////////////////////////////////////////////////////////////
  297. int GfaMininetMasterEvaluateSlaveResponse(HGFAMINEMST hMst, uint8_t nNode, const void *pFrame, size_t nCbFrame, bool bAckPossible, uint8_t *pbIndex)
  298. {
  299. if(hMst && pFrame && nCbFrame > 0)
  300. {
  301. bool bIsStatusIndex = false;
  302. LPCGFA_MININET_FRAME pf = (LPCGFA_MININET_FRAME)pFrame;
  303. /////////////////////////////////////////////////////////////////////
  304. if((nCbFrame < 6))
  305. {
  306. if(bAckPossible && (pf->stx == ACK))
  307. {
  308. return MINET_SLAVE_RESPONSE_ACK;
  309. }
  310. else
  311. {
  312. errno = MINET_SLAVE_RESPONSE_ERROR_INVALID_LENGTH;
  313. return -1;
  314. }
  315. }
  316. else
  317. {
  318. /////////////////////////////////////////////////////////////////
  319. // STX / ACK
  320. if(bAckPossible && (pf->stx == ACK))
  321. return MINET_SLAVE_RESPONSE_ACK;
  322. else if(pf->stx != STX)
  323. {
  324. errno = MINET_SLAVE_RESPONSE_ERROR_STX_ERROR;
  325. return -1;
  326. }
  327. /////////////////////////////////////////////////////////////////
  328. // Length
  329. if(pf->len > nCbFrame)
  330. {
  331. errno = MINET_SLAVE_RESPONSE_ERROR_INCOMPLETE_DATA;
  332. return -1;
  333. }
  334. /////////////////////////////////////////////////////////////////
  335. // Node address
  336. if(pf->node != (nNode & 0xF0))
  337. {
  338. errno = MINET_SLAVE_RESPONSE_ERROR_INVALID_NODE_ADDRESS;
  339. return -1;
  340. }
  341. /////////////////////////////////////////////////////////////////
  342. // Index range / match / status code
  343. if(pbIndex)
  344. *pbIndex = pf->index;
  345. if(_IsValidIndex(pf->index))
  346. {
  347. uint8_t nIndex = _GetCurIndex(hMst, nNode);
  348. if(pf->index != nIndex)
  349. {
  350. errno = MINET_SLAVE_RESPONSE_ERROR_INDEX_NO_MATCH;
  351. return -1;
  352. }
  353. }
  354. else if(pf->index < MIN_INDEX)
  355. {
  356. errno = MINET_SLAVE_RESPONSE_ERROR_INDEX_OUT_OF_RANGE;
  357. return -1;
  358. }
  359. else // pf->index > MAX_INDEX
  360. {
  361. switch(pf->index)
  362. {
  363. case STATUS_INDEX_RESET_DONE:
  364. case STATUS_INDEX_ERROR:
  365. case STATUS_INDEX_CMD_ERROR:
  366. case STATUS_INDEX_INVALID_PARAM:
  367. case STATUS_INDEX_UNKNOWN_CMD:
  368. case STATUS_INDEX_CMD_ALREADY_EX:
  369. bIsStatusIndex = true;
  370. break;
  371. default:
  372. errno = MINET_SLAVE_RESPONSE_ERROR_INDEX_OUT_OF_RANGE;
  373. return -1;
  374. }
  375. }
  376. /////////////////////////////////////////////////////////////////
  377. // Data / Slave indicator
  378. if(pf->data.by[0] != SLAVE_IND)
  379. {
  380. errno = MINET_SLAVE_RESPONSE_ERROR_INVALID_SLAVE_INDICATOR;
  381. return -1;
  382. }
  383. /////////////////////////////////////////////////////////////////
  384. // Checksum
  385. if(pf->data.by[pf->len - 5] != GfaMininetMasterCalcChk(pf, pf->len - 1))
  386. {
  387. errno = MINET_SLAVE_RESPONSE_ERROR_INVALID_CHECKSUM;
  388. return -1;
  389. }
  390. else
  391. {
  392. return bIsStatusIndex ? MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE : MINET_SLAVE_RESPONSE_SUCCESS;
  393. }
  394. }
  395. }
  396. errno = MINET_SLAVE_RESPONSE_ERROR_INVALID_ARGUMENT;
  397. return -1;
  398. }
  399. /////////////////////////////////////////////////////////////////////////////
  400. ssize_t GfaMininetMasterTransmitFrame(HGFAMINEMST hMst, const void *pData, size_t nCbData)
  401. {
  402. if(hMst && pData && nCbData)
  403. {
  404. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  405. return GfaMininetDeviceTransmit(pMst->hDev, pData, nCbData);
  406. }
  407. errno = EINVAL;
  408. return -1;
  409. }
  410. /////////////////////////////////////////////////////////////////////////////
  411. ssize_t GfaMininetMasterReceiveFrame(HGFAMINEMST hMst, void *pBuffer, size_t nCbBuffer, bool bAckPossible)
  412. {
  413. if(hMst && pBuffer && nCbBuffer)
  414. {
  415. uint8_t b, c, buf[256] = {0};
  416. bool bLoop = true;
  417. GfaMininetRxStates nState = GfaRxMNS_Stx;
  418. ssize_t nRet, nCbDataPayloadExp = 0, nCbDataPayloadRcv = 0;
  419. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  420. LPGFA_MININET_FRAME pFrameRx = (LPGFA_MININET_FRAME)buf;
  421. if(!pBuffer || !nCbBuffer)
  422. {
  423. errno = EINVAL;
  424. return -1;
  425. }
  426. do
  427. {
  428. switch(nState)
  429. {
  430. ////////////////////////////////////////////////////////////////////////
  431. // handle STX
  432. case GfaRxMNS_Stx:
  433. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  434. {
  435. bLoop = false;
  436. break;
  437. }
  438. if(b != STX)
  439. {
  440. if(bAckPossible && (b == ACK))
  441. {
  442. *(uint8_t*)pBuffer = b;
  443. nRet = 1;
  444. bLoop = false;
  445. break;
  446. }
  447. continue;
  448. }
  449. pFrameRx->stx = b;
  450. ++nState;
  451. // fall through
  452. ////////////////////////////////////////////////////////////////////////
  453. // handle length
  454. case GfaRxMNS_Len:
  455. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  456. {
  457. bLoop = false;
  458. break;
  459. }
  460. if(b < 5)
  461. {
  462. if(b == STX)
  463. continue;
  464. else
  465. {
  466. nState = GfaRxMNS_Stx;
  467. continue;
  468. }
  469. }
  470. pFrameRx->len = b;
  471. nCbDataPayloadExp = b - 5;
  472. ++nState;
  473. // fall through
  474. ////////////////////////////////////////////////////////////////////////
  475. // handle node
  476. case GfaRxMNS_Node:
  477. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  478. {
  479. bLoop = false;
  480. break;
  481. }
  482. if(b == STX)
  483. {
  484. nState = GfaRxMNS_Len;
  485. continue;
  486. }
  487. pFrameRx->node = b;
  488. ++nState;
  489. // fall through
  490. ////////////////////////////////////////////////////////////////////////
  491. // handle index
  492. case GfaRxMNS_Index:
  493. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  494. {
  495. bLoop = false;
  496. break;
  497. }
  498. if(b == STX)
  499. {
  500. nState = GfaRxMNS_Len;
  501. continue;
  502. }
  503. else if(b < MIN_INDEX)
  504. {
  505. nState = GfaRxMNS_Stx;
  506. continue;
  507. }
  508. pFrameRx->index = b;
  509. ++nState;
  510. // fall through
  511. ////////////////////////////////////////////////////////////////////////
  512. // handle data, if any
  513. case GfaRxMNS_Data:
  514. if(nCbDataPayloadExp > nCbDataPayloadRcv)
  515. {
  516. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  517. {
  518. bLoop = false;
  519. break;
  520. }
  521. if(b == STX)
  522. ++nState;
  523. pFrameRx->data.by[nCbDataPayloadRcv++] = b;
  524. continue;
  525. }
  526. else
  527. {
  528. nState = GfaRxMNS_Check;
  529. continue;
  530. }
  531. ////////////////////////////////////////////////////////////////////////
  532. // handle 0
  533. case GfaRxMNS_Zero:
  534. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  535. {
  536. bLoop = false;
  537. break;
  538. }
  539. if(b == 0)
  540. {
  541. nState = GfaRxMNS_Data;
  542. continue;
  543. }
  544. else if(b == STX)
  545. {
  546. nCbDataPayloadRcv = nCbDataPayloadExp = 0;
  547. nState = GfaRxMNS_Len;
  548. continue;
  549. }
  550. else if(b >= 5)
  551. {
  552. pFrameRx->len = b;
  553. nCbDataPayloadRcv = 0;
  554. nCbDataPayloadExp = b - 5;
  555. nState = GfaRxMNS_Node;
  556. continue;
  557. }
  558. else
  559. {
  560. nCbDataPayloadRcv = nCbDataPayloadExp = 0;
  561. nState = GfaRxMNS_Stx;
  562. continue;
  563. }
  564. ////////////////////////////////////////////////////////////////////////
  565. // handle Checksum
  566. case GfaRxMNS_Check:
  567. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  568. {
  569. bLoop = false;
  570. break;
  571. }
  572. if(b == STX)
  573. {
  574. nCbDataPayloadRcv = nCbDataPayloadExp = 0;
  575. nState = GfaRxMNS_Len;
  576. continue;
  577. }
  578. c = GfaMininetMasterCalcChk(pFrameRx, pFrameRx->len - 1);
  579. if(b == c)
  580. {
  581. if((size_t)pFrameRx->len <= nCbBuffer)
  582. {
  583. pFrameRx->data.by[nCbDataPayloadRcv] = b;
  584. nRet = pFrameRx->len;
  585. memcpy(pBuffer, pFrameRx, nRet);
  586. }
  587. else
  588. {
  589. errno = ENOMEM;
  590. nRet = -1;
  591. }
  592. }
  593. else
  594. {
  595. errno = EPROTO;
  596. nRet = -1;
  597. }
  598. bLoop = false;
  599. break;
  600. ////////////////////////////////////////////////////////////////////////
  601. default:
  602. nRet = -1;
  603. bLoop = false;
  604. break;
  605. }
  606. }
  607. while(bLoop);
  608. return nRet;
  609. }
  610. errno = EINVAL;
  611. return -1;
  612. }
  613. /////////////////////////////////////////////////////////////////////////////
  614. void GfaMininetMasterDumpFrame(FILE *pf, LPCGFA_MININET_FRAME pFrame)
  615. {
  616. if(pf)
  617. {
  618. if(pFrame && pFrame->len >= 5)
  619. {
  620. int i, nCbData = pFrame->len - 5;
  621. fprintf(pf, "\nSTX: %02hhX (%hhu)\n", pFrame->stx, pFrame->stx);
  622. fprintf(pf, "Length: %02hhX (%hhu)\n", pFrame->len, pFrame->len);
  623. fprintf(pf, "Node: %02hhX (%hhu)\n", pFrame->node, pFrame->node);
  624. fprintf(pf, "Index: %02hhX (%hhu)\n", pFrame->index, pFrame->index);
  625. fprintf(pf, "Data: ");
  626. for(i = 0; i < nCbData; i++)
  627. {
  628. if(pFrame->data.by[i] >= 0x41 && pFrame->data.by[i] <= 0x5A)
  629. fprintf(pf, "<%c>", (char)pFrame->data.by[i]);
  630. else
  631. fprintf(pf, "[%02hhX]", (char)pFrame->data.by[i]);
  632. }
  633. fprintf(pf, "\nCRC: %02hhX (%hhu)\n\n", pFrame->data.by[i], pFrame->data.by[i]);
  634. }
  635. else
  636. {
  637. fprintf(pf, "\nInvalid Mininet-Frame!\n");
  638. }
  639. fflush(pf);
  640. }
  641. }