gfamininetmst.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <malloc.h>
  5. #include <time.h>
  6. #include <fcntl.h>
  7. #include <errno.h>
  8. #include <termios.h>
  9. #include <unistd.h>
  10. #include <ctype.h>
  11. #include <sys/file.h>
  12. #include "gfamininetmst.h"
  13. #include "dbghlp.h"
  14. /////////////////////////////////////////////////////////////////////////////
  15. // https://www.racom.eu/eng/support/prot/mininet/index.html
  16. /////////////////////////////////////////////////////////////////////////////
  17. #define STX ((uint8_t)0x02)
  18. #define ACK ((uint8_t)0x06)
  19. #define SLAVE_IND ((uint8_t)0x80)
  20. #define START_INDEX 0x40
  21. #define MIN_INDEX 0x3F
  22. #define MAX_INDEX 0x7F
  23. #define RESET_INDEX MIN_INDEX
  24. #define MAX_DATA_PAYLOAD_LENGTH 250
  25. #define MAX_SAVE_TIMOUT_DEPTH 8
  26. /////////////////////////////////////////////////////////////////////////////
  27. typedef enum _GfaMininetRxStates
  28. {
  29. GfaRxMNS_Stx,
  30. GfaRxMNS_Len,
  31. GfaRxMNS_Node,
  32. GfaRxMNS_Index,
  33. GfaRxMNS_Data,
  34. GfaRxMNS_Zero,
  35. GfaRxMNS_Check
  36. }GfaMininetRxStates, *LPGfaMininetRxStates;
  37. /////////////////////////////////////////////////////////////////////////////
  38. typedef struct _GFA_MININET_MASTER
  39. {
  40. HMINETDEV hDev;
  41. struct timeval tvRXSave[MAX_SAVE_TIMOUT_DEPTH];
  42. struct timeval tvTXSave[MAX_SAVE_TIMOUT_DEPTH];
  43. struct timespec tsStart;
  44. int nVerbosity;
  45. int nSaveToIndex;
  46. FILE *pDumpCtx;
  47. uint8_t nIndexTable[256];
  48. }GFA_MININET_MASTER, *LPGFA_MININET_MASTER;
  49. typedef const GFA_MININET_MASTER *LPCGFA_MININET_MASTER;
  50. /////////////////////////////////////////////////////////////////////////////
  51. static bool _IsValidIndex(uint8_t nIndex)
  52. {
  53. return ((nIndex >= MIN_INDEX) && (nIndex <= MAX_INDEX));
  54. }
  55. static uint8_t _GetNextIndex(HGFAMINEMST hMst, uint8_t nNode)
  56. {
  57. if(hMst)
  58. {
  59. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  60. uint8_t idx = ++pMst->nIndexTable[nNode];
  61. if(idx > MAX_INDEX)
  62. {
  63. pMst->nIndexTable[nNode] = START_INDEX;
  64. idx = pMst->nIndexTable[nNode];
  65. }
  66. return idx;
  67. }
  68. return 0xFF;
  69. }
  70. static uint8_t _GetCurIndex(HGFAMINEMST hMst, uint8_t nNode)
  71. {
  72. if(hMst)
  73. {
  74. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  75. return pMst->nIndexTable[nNode];
  76. }
  77. return 0xFF;
  78. }
  79. /////////////////////////////////////////////////////////////////////////////
  80. HGFAMINEMST GfaMininetMasterOpen(LPCGFA_MININET_MST_CFG_PARAMS pmmcp)
  81. {
  82. if(pmmcp)
  83. {
  84. HMINETDEV hDev = GfaMininetDeviceOpen(&pmmcp->devcfg);
  85. if(hDev)
  86. {
  87. LPGFA_MININET_MASTER pMst = malloc(sizeof(GFA_MININET_MASTER));
  88. memset(pMst, 0, sizeof(GFA_MININET_MASTER));
  89. memset(pMst->nIndexTable, START_INDEX, sizeof(pMst->nIndexTable));
  90. pMst->hDev = hDev;
  91. pMst->pDumpCtx = stdout;
  92. clock_gettime(CLOCK_MONOTONIC, &pMst->tsStart);
  93. return (HGFAMINEMST)pMst;
  94. }
  95. return NULL;
  96. }
  97. errno = EINVAL;
  98. return NULL;
  99. }
  100. /////////////////////////////////////////////////////////////////////////////
  101. void GfaMininetMasterClose(HGFAMINEMST hMst)
  102. {
  103. if(hMst)
  104. {
  105. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  106. GfaMininetDeviceClose(pMst->hDev);
  107. free(pMst);
  108. }
  109. }
  110. /////////////////////////////////////////////////////////////////////////////
  111. bool GfaMininetMasterGetTimeouts(HGFAMINEMST hMst, struct timeval *ptvRX, struct timeval *ptvTX)
  112. {
  113. if(hMst)
  114. {
  115. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  116. return GfaMininetDeviceGetTimeouts(pMst->hDev, ptvRX, ptvTX);
  117. }
  118. errno = EINVAL;
  119. return false;
  120. }
  121. /////////////////////////////////////////////////////////////////////////////
  122. bool GfaMininetMasterSetTimeouts(HGFAMINEMST hMst, const struct timeval *ptvRX, const struct timeval *ptvTX)
  123. {
  124. if(hMst)
  125. {
  126. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  127. return GfaMininetDeviceSetTimeouts(pMst->hDev, ptvRX, ptvTX);
  128. }
  129. errno = EINVAL;
  130. return false;
  131. }
  132. /////////////////////////////////////////////////////////////////////////////
  133. bool GfaMininetMasterSaveTimeouts(HGFAMINEMST hMst)
  134. {
  135. if(hMst)
  136. {
  137. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  138. if(pMst->nSaveToIndex < MAX_SAVE_TIMOUT_DEPTH)
  139. {
  140. int nIndex = pMst->nSaveToIndex++;
  141. return GfaMininetMasterGetTimeouts(hMst, &pMst->tvRXSave[nIndex], &pMst->tvTXSave[nIndex]);
  142. }
  143. else
  144. {
  145. errno = EPERM;
  146. return false;
  147. }
  148. }
  149. errno = EINVAL;
  150. return false;
  151. }
  152. /////////////////////////////////////////////////////////////////////////////
  153. bool GfaMininetMasterRestoreTimeouts(HGFAMINEMST hMst)
  154. {
  155. if(hMst)
  156. {
  157. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  158. if(pMst->nSaveToIndex > 0)
  159. {
  160. int nIndex = --pMst->nSaveToIndex;
  161. return GfaMininetMasterSetTimeouts(hMst, &pMst->tvRXSave[nIndex], &pMst->tvTXSave[nIndex]);
  162. }
  163. else
  164. {
  165. errno = EPERM;
  166. return false;
  167. }
  168. }
  169. errno = EINVAL;
  170. return false;
  171. }
  172. /////////////////////////////////////////////////////////////////////////////
  173. ssize_t GfaMininetMasterGetConfigParams(HGFAMINEMST hMst, void *pDevParams, size_t nSizeDevParams)
  174. {
  175. if(hMst)
  176. {
  177. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  178. return GfaMininetDeviceGetConfigParams(pMst->hDev, pDevParams, nSizeDevParams);
  179. }
  180. errno = EINVAL;
  181. return false;
  182. }
  183. /////////////////////////////////////////////////////////////////////////////
  184. int GfaMininetMasterSetConfigParams(HGFAMINEMST hMst, const void *pDevParams, size_t nSizeDevParams)
  185. {
  186. if(hMst)
  187. {
  188. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  189. return GfaMininetDeviceSetConfigParams(pMst->hDev, pDevParams, nSizeDevParams);
  190. }
  191. errno = EINVAL;
  192. return false;
  193. }
  194. /////////////////////////////////////////////////////////////////////////////
  195. bool GfaMininetMasterIsValidBaudrate(HGFAMINEMST hMst, uint32_t nBaudrate)
  196. {
  197. if(hMst)
  198. {
  199. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  200. return GfaMininetDeviceIsValidBaudrate(pMst->hDev, nBaudrate);
  201. }
  202. errno = EINVAL;
  203. return false;
  204. }
  205. /////////////////////////////////////////////////////////////////////////////
  206. int GfaMininetMasterSetBaudrate(HGFAMINEMST hMst, uint32_t nBaudrate)
  207. {
  208. if(hMst)
  209. {
  210. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  211. return GfaMininetDeviceSetBaudrate(pMst->hDev, nBaudrate);
  212. }
  213. errno = EINVAL;
  214. return false;
  215. }
  216. /////////////////////////////////////////////////////////////////////////////
  217. HMINETDEV GfaMininetMasterGetDeviceHandle(HGFAMINEMST hMst)
  218. {
  219. if(hMst)
  220. {
  221. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  222. return pMst->hDev;
  223. }
  224. errno = EINVAL;
  225. return NULL;
  226. }
  227. /////////////////////////////////////////////////////////////////////////////
  228. uint8_t GfaMininetMasterCalcChk(const void *pData, size_t nCbData, bool bProcessSTX)
  229. {
  230. size_t i = 0;
  231. uint16_t chk = 0;
  232. uint8_t cc, lc = 0;
  233. const uint8_t *pszData = (const uint8_t*)pData;
  234. for(i = 0; i < nCbData; ++i)
  235. {
  236. cc = *pszData++;
  237. if(cc || (lc != STX))
  238. {
  239. chk <<= 1;
  240. if(chk & 0x0100)
  241. chk = (chk + 1) & 0x00FF;
  242. chk += cc;
  243. if(chk > 0x00FF)
  244. chk = (chk + 1) & 0x00FF;
  245. }
  246. if(bProcessSTX && (i > 3))
  247. lc = cc;
  248. }
  249. if((uint8_t)chk == STX)
  250. chk = ~chk;
  251. return (uint8_t)chk;
  252. }
  253. /////////////////////////////////////////////////////////////////////////////
  254. size_t GfaMininetMasterBuildFrame(HGFAMINEMST hMst, uint8_t nNode, uint8_t nIndex, const void *pDataPayload, size_t nCbDataPayload, void *pFrameBuffer, size_t nCbFrameBuffer)
  255. {
  256. if(hMst && pFrameBuffer && (nCbFrameBuffer >= 5) && (nCbDataPayload <= MAX_DATA_PAYLOAD_LENGTH))
  257. {
  258. int i = 0;
  259. uint8_t b, c;
  260. size_t nLen = 4;
  261. const uint8_t *pszData = (const uint8_t*)pDataPayload;
  262. LPGFA_MININET_FRAME pf = (LPGFA_MININET_FRAME)pFrameBuffer;
  263. pf->stx = STX;
  264. pf->len = 5 + nCbDataPayload;
  265. pf->node = nNode;
  266. pf->index = _IsValidIndex(nIndex) ? nIndex : _GetNextIndex(hMst, nNode);
  267. if(pszData && nCbDataPayload)
  268. {
  269. while(nCbDataPayload--)
  270. {
  271. b = *pszData++;
  272. do
  273. {
  274. if(++nLen == nCbFrameBuffer)
  275. {
  276. errno = ENOMEM;
  277. return 0;
  278. }
  279. pf->data.by[i++] = b;
  280. c = b;
  281. b = 0;
  282. }
  283. while(c == STX);
  284. }
  285. }
  286. pf->data.by[i++] = GfaMininetMasterCalcChk(pFrameBuffer, nLen, true);
  287. ++nLen;
  288. return nLen;
  289. }
  290. errno = EINVAL;
  291. return 0;
  292. }
  293. /////////////////////////////////////////////////////////////////////////////
  294. int GfaMininetMasterResetSlaveIndex(HGFAMINEMST hMst, uint8_t nNode)
  295. {
  296. if(hMst)
  297. {
  298. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  299. ssize_t nLen, nRet;
  300. uint8_t nIndex;
  301. uint8_t txb[16];
  302. uint8_t rxb[16];
  303. nLen = GfaMininetMasterBuildFrame(hMst, nNode, RESET_INDEX, "\x1b\x52", 2, txb, sizeof(txb));
  304. if((nRet = GfaMininetMasterTransmitFrame(hMst, txb, nLen)) != nLen)
  305. {
  306. GfaMininetDevicePurgeRXBuffer(pMst->hDev);
  307. return -1;
  308. }
  309. if(!NODE_IS_BROADCAST(nNode) && !NODE_IS_GROUPCAST(nNode))
  310. {
  311. // we expect a response
  312. if((nRet = GfaMininetMasterReceiveFrame(hMst, rxb, sizeof(rxb), false)) <= 0)
  313. return -1;
  314. if((nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, nNode, rxb, nRet, false, &nIndex)) == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  315. {
  316. if(nIndex == MINET_SLAVE_STATUS_INDEX_RESET_DONE)
  317. return GfaMininetMasterResetLocalIndex(hMst, nNode);
  318. else
  319. {
  320. errno = nIndex;
  321. nRet = -1;
  322. }
  323. }
  324. else
  325. {
  326. errno = EPROTO;
  327. nRet = -1;
  328. }
  329. }
  330. else
  331. {
  332. // we don't expect a response. so let's just hope that all slaves have received the request and have performed an index reset!
  333. return GfaMininetMasterResetLocalIndex(hMst, nNode);
  334. }
  335. return nRet;
  336. }
  337. errno = EINVAL;
  338. return -1;
  339. }
  340. /////////////////////////////////////////////////////////////////////////////
  341. int GfaMininetMasterResetLocalIndex(HGFAMINEMST hMst, uint8_t nNode)
  342. {
  343. if(hMst)
  344. {
  345. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  346. if(NODE_IS_BROADCAST(nNode))
  347. memset(pMst->nIndexTable, START_INDEX, sizeof(pMst->nIndexTable));
  348. else if(NODE_IS_GROUPCAST(nNode))
  349. memset(&pMst->nIndexTable[nNode], START_INDEX, 10);
  350. else
  351. pMst->nIndexTable[nNode] = START_INDEX;
  352. return 0;
  353. }
  354. errno = EINVAL;
  355. return -1;
  356. }
  357. /////////////////////////////////////////////////////////////////////////////
  358. int GfaMininetMasterPurgeDeviceRXBuffer(HGFAMINEMST hMst)
  359. {
  360. if(hMst)
  361. {
  362. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  363. return GfaMininetDevicePurgeRXBuffer(pMst->hDev);
  364. }
  365. errno = EINVAL;
  366. return -1;
  367. }
  368. /////////////////////////////////////////////////////////////////////////////
  369. int GfaMininetMasterEvaluateSlaveResponse(HGFAMINEMST hMst, uint8_t nNode, const void *pFrame, size_t nCbFrame, bool bAckPossible, uint8_t *pbIndex)
  370. {
  371. if(hMst && pFrame && nCbFrame > 0)
  372. {
  373. bool bIsStatusIndex = false;
  374. LPCGFA_MININET_FRAME pf = (LPCGFA_MININET_FRAME)pFrame;
  375. /////////////////////////////////////////////////////////////////////
  376. if((nCbFrame < 6))
  377. {
  378. if(bAckPossible && (pf->stx == ACK))
  379. {
  380. return MINET_SLAVE_RESPONSE_ACK;
  381. }
  382. else
  383. {
  384. errno = MINET_SLAVE_RESPONSE_ERROR_INVALID_LENGTH;
  385. return -1;
  386. }
  387. }
  388. else
  389. {
  390. /////////////////////////////////////////////////////////////////
  391. // STX / ACK
  392. if(bAckPossible && (pf->stx == ACK))
  393. return MINET_SLAVE_RESPONSE_ACK;
  394. else if(pf->stx != STX)
  395. {
  396. errno = MINET_SLAVE_RESPONSE_ERROR_STX_ERROR;
  397. return -1;
  398. }
  399. /////////////////////////////////////////////////////////////////
  400. // Length
  401. if(pf->len > nCbFrame)
  402. {
  403. errno = MINET_SLAVE_RESPONSE_ERROR_INCOMPLETE_DATA;
  404. return -1;
  405. }
  406. /////////////////////////////////////////////////////////////////
  407. // Node address
  408. if(pf->node != (nNode & 0xF0))
  409. {
  410. errno = MINET_SLAVE_RESPONSE_ERROR_INVALID_NODE_ADDRESS;
  411. return -1;
  412. }
  413. /////////////////////////////////////////////////////////////////
  414. // Index range / match / status code
  415. if(pbIndex)
  416. *pbIndex = pf->index;
  417. if(_IsValidIndex(pf->index))
  418. {
  419. uint8_t nIndex = _GetCurIndex(hMst, nNode);
  420. if(pf->index != nIndex)
  421. {
  422. errno = MINET_SLAVE_RESPONSE_ERROR_INDEX_NO_MATCH;
  423. return -1;
  424. }
  425. }
  426. else if(pf->index < MIN_INDEX)
  427. {
  428. errno = MINET_SLAVE_RESPONSE_ERROR_INDEX_OUT_OF_RANGE;
  429. return -1;
  430. }
  431. else // pf->index > MAX_INDEX
  432. {
  433. switch(pf->index)
  434. {
  435. case MINET_SLAVE_STATUS_INDEX_RESET_DONE:
  436. case MINET_SLAVE_STATUS_INDEX_ERROR:
  437. case MINET_SLAVE_STATUS_INDEX_CMD_ERROR:
  438. case MINET_SLAVE_STATUS_INDEX_INVALID_PARAM:
  439. case MINET_SLAVE_STATUS_INDEX_UNKNOWN_CMD:
  440. case MINET_SLAVE_STATUS_INDEX_CMD_ALREADY_EX:
  441. bIsStatusIndex = true;
  442. break;
  443. default:
  444. errno = MINET_SLAVE_RESPONSE_ERROR_INDEX_OUT_OF_RANGE;
  445. return -1;
  446. }
  447. }
  448. /////////////////////////////////////////////////////////////////
  449. // Data / Slave indicator
  450. if(pf->data.by[0] != SLAVE_IND)
  451. {
  452. errno = MINET_SLAVE_RESPONSE_ERROR_INVALID_SLAVE_INDICATOR;
  453. return -1;
  454. }
  455. /////////////////////////////////////////////////////////////////
  456. // Checksum
  457. if(pf->data.by[pf->len - 5] != GfaMininetMasterCalcChk(pf, pf->len - 1, false))
  458. {
  459. errno = MINET_SLAVE_RESPONSE_ERROR_INVALID_CHECKSUM;
  460. return -1;
  461. }
  462. else
  463. {
  464. return bIsStatusIndex ? MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE : MINET_SLAVE_RESPONSE_SUCCESS;
  465. }
  466. }
  467. }
  468. errno = MINET_SLAVE_RESPONSE_ERROR_INVALID_ARGUMENT;
  469. return -1;
  470. }
  471. /////////////////////////////////////////////////////////////////////////////
  472. ssize_t GfaMininetMasterTransmitFrame(HGFAMINEMST hMst, const void *pData, size_t nCbData)
  473. {
  474. if(hMst && pData && nCbData)
  475. {
  476. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  477. GfaMininetMasterDumpFrame(hMst, pMst->pDumpCtx, (LPCGFA_MININET_FRAME)pData, true, NULL);
  478. return GfaMininetDeviceTransmit(pMst->hDev, pData, nCbData);
  479. }
  480. errno = EINVAL;
  481. return -1;
  482. }
  483. /////////////////////////////////////////////////////////////////////////////
  484. ssize_t GfaMininetMasterReceiveFrame(HGFAMINEMST hMst, void *pBuffer, size_t nCbBuffer, bool bAckPossible)
  485. {
  486. if(hMst && pBuffer && nCbBuffer)
  487. {
  488. uint8_t b, c, buf[256] = {0};
  489. bool bLoop = true;
  490. GfaMininetRxStates nState = GfaRxMNS_Stx;
  491. ssize_t nRet, nCbDataPayloadExp = 0, nCbDataPayloadRcv = 0;
  492. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  493. LPGFA_MININET_FRAME pFrameRx = (LPGFA_MININET_FRAME)buf;
  494. if(!pBuffer || !nCbBuffer)
  495. {
  496. errno = EINVAL;
  497. return -1;
  498. }
  499. do
  500. {
  501. switch(nState)
  502. {
  503. ////////////////////////////////////////////////////////////////////////
  504. // handle STX
  505. case GfaRxMNS_Stx:
  506. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  507. {
  508. bLoop = false;
  509. break;
  510. }
  511. if(b != STX)
  512. {
  513. if(bAckPossible && (b == ACK))
  514. {
  515. *(uint8_t*)pBuffer = b;
  516. nRet = 1;
  517. bLoop = false;
  518. GfaMininetMasterDumpFrame(hMst, pMst->pDumpCtx, (LPCGFA_MININET_FRAME)pBuffer, false, NULL);
  519. break;
  520. }
  521. continue;
  522. }
  523. pFrameRx->stx = b;
  524. ++nState;
  525. // fall through
  526. ////////////////////////////////////////////////////////////////////////
  527. // handle length
  528. case GfaRxMNS_Len:
  529. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  530. {
  531. bLoop = false;
  532. break;
  533. }
  534. if(b < 5)
  535. {
  536. if(b == STX)
  537. continue;
  538. else
  539. {
  540. nState = GfaRxMNS_Stx;
  541. continue;
  542. }
  543. }
  544. pFrameRx->len = b;
  545. nCbDataPayloadExp = b - 5;
  546. ++nState;
  547. // fall through
  548. ////////////////////////////////////////////////////////////////////////
  549. // handle node
  550. case GfaRxMNS_Node:
  551. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  552. {
  553. bLoop = false;
  554. break;
  555. }
  556. if(b == STX)
  557. {
  558. nState = GfaRxMNS_Len;
  559. continue;
  560. }
  561. pFrameRx->node = b;
  562. ++nState;
  563. // fall through
  564. ////////////////////////////////////////////////////////////////////////
  565. // handle index
  566. case GfaRxMNS_Index:
  567. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  568. {
  569. bLoop = false;
  570. break;
  571. }
  572. if(b == STX)
  573. {
  574. nState = GfaRxMNS_Len;
  575. continue;
  576. }
  577. else if(b < MIN_INDEX)
  578. {
  579. nState = GfaRxMNS_Stx;
  580. continue;
  581. }
  582. pFrameRx->index = b;
  583. ++nState;
  584. // fall through
  585. ////////////////////////////////////////////////////////////////////////
  586. // handle data, if any
  587. case GfaRxMNS_Data:
  588. if(nCbDataPayloadExp > nCbDataPayloadRcv)
  589. {
  590. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  591. {
  592. bLoop = false;
  593. break;
  594. }
  595. if(b == STX)
  596. ++nState;
  597. pFrameRx->data.by[nCbDataPayloadRcv++] = b;
  598. continue;
  599. }
  600. else
  601. {
  602. nState = GfaRxMNS_Check;
  603. continue;
  604. }
  605. ////////////////////////////////////////////////////////////////////////
  606. // handle 0
  607. case GfaRxMNS_Zero:
  608. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  609. {
  610. bLoop = false;
  611. break;
  612. }
  613. if(b == 0)
  614. {
  615. nState = GfaRxMNS_Data;
  616. continue;
  617. }
  618. else if(b == STX)
  619. {
  620. nCbDataPayloadRcv = nCbDataPayloadExp = 0;
  621. nState = GfaRxMNS_Len;
  622. continue;
  623. }
  624. else if(b >= 5)
  625. {
  626. pFrameRx->len = b;
  627. nCbDataPayloadRcv = 0;
  628. nCbDataPayloadExp = b - 5;
  629. nState = GfaRxMNS_Node;
  630. continue;
  631. }
  632. else
  633. {
  634. nCbDataPayloadRcv = nCbDataPayloadExp = 0;
  635. nState = GfaRxMNS_Stx;
  636. continue;
  637. }
  638. ////////////////////////////////////////////////////////////////////////
  639. // handle Checksum
  640. case GfaRxMNS_Check:
  641. if((nRet = GfaMininetDevicePop(pMst->hDev, &b)) != 1)
  642. {
  643. bLoop = false;
  644. break;
  645. }
  646. if(b == STX)
  647. {
  648. nCbDataPayloadRcv = nCbDataPayloadExp = 0;
  649. nState = GfaRxMNS_Len;
  650. continue;
  651. }
  652. c = GfaMininetMasterCalcChk(pFrameRx, pFrameRx->len - 1, false);
  653. if(b == c)
  654. {
  655. if((size_t)pFrameRx->len <= nCbBuffer)
  656. {
  657. pFrameRx->data.by[nCbDataPayloadRcv] = b;
  658. nRet = pFrameRx->len;
  659. memcpy(pBuffer, pFrameRx, nRet);
  660. GfaMininetMasterDumpFrame(hMst, pMst->pDumpCtx, (LPCGFA_MININET_FRAME)pFrameRx, false, NULL);
  661. }
  662. else
  663. {
  664. errno = ENOMEM;
  665. nRet = -1;
  666. }
  667. }
  668. else
  669. {
  670. pFrameRx->data.by[nCbDataPayloadRcv] = b;
  671. GfaMininetMasterDumpFrame(hMst, pMst->pDumpCtx, (LPCGFA_MININET_FRAME)pFrameRx, false, "CRC32!!!");
  672. errno = EPROTO;
  673. nRet = -1;
  674. }
  675. bLoop = false;
  676. break;
  677. ////////////////////////////////////////////////////////////////////////
  678. default:
  679. nRet = -1;
  680. bLoop = false;
  681. break;
  682. }
  683. }
  684. while(bLoop);
  685. return nRet;
  686. }
  687. errno = EINVAL;
  688. return -1;
  689. }
  690. /////////////////////////////////////////////////////////////////////////////
  691. ssize_t GfaMininetMasterGetDataFromFrame(const void *pFrame, size_t nCbFrame, void *pData, size_t nCbData)
  692. {
  693. if(pFrame && (nCbFrame >= 5) && pData && (nCbData > 0))
  694. {
  695. LPCGFA_MININET_FRAME pf = (LPCGFA_MININET_FRAME)pFrame;
  696. if(pf->len == 5)
  697. return 0; // no data
  698. else if(pf->len > 5)
  699. {
  700. if(nCbFrame >= pf->len)
  701. {
  702. size_t nDatalen = (size_t)pf->len - 5;
  703. if(nDatalen <= nCbData)
  704. {
  705. memcpy(pData, pf->data.by, nDatalen);
  706. return (ssize_t)nDatalen;
  707. }
  708. else
  709. {
  710. errno = ENOMEM;
  711. return -1;
  712. }
  713. }
  714. }
  715. else
  716. {
  717. errno = EPROTO;
  718. return -1;
  719. }
  720. }
  721. errno = EINVAL;
  722. return -1;
  723. }
  724. /////////////////////////////////////////////////////////////////////////////
  725. ssize_t GfaMininetMasterGetDataFromSlaveFrame(const void *pFrame, size_t nCbFrame, void *pData, size_t nCbData)
  726. {
  727. uint8_t data[256];
  728. ssize_t nRet = GfaMininetMasterGetDataFromFrame(pFrame, nCbFrame, data, sizeof(data));
  729. if(nRet > 0)
  730. {
  731. if(data[0] == SLAVE_IND)
  732. {
  733. if(--nRet <= (ssize_t)nCbData)
  734. {
  735. if(nRet > 0)
  736. memcpy(pData, &data[1], nRet);
  737. }
  738. else
  739. {
  740. errno = ENOMEM;
  741. nRet = -1;
  742. }
  743. }
  744. else
  745. {
  746. errno = EPROTO;
  747. nRet = -1;
  748. }
  749. }
  750. return nRet;
  751. }
  752. /////////////////////////////////////////////////////////////////////////////
  753. void GfaMininetMasterDumpFrame(HGFAMINEMST hMst, FILE *pf, LPCGFA_MININET_FRAME pFrame, bool bTX, const char *pszAnnotation)
  754. {
  755. if(hMst && pf)
  756. {
  757. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  758. if(pMst->nVerbosity >= 4)
  759. {
  760. struct timespec tsCur, tsIntv;
  761. clock_gettime(CLOCK_MONOTONIC, &tsCur);
  762. uint64_t nInterval = TimespecDiff(&tsCur, &pMst->tsStart);
  763. Ns2Timespec(nInterval, &tsIntv);
  764. if(pFrame)
  765. {
  766. if(pFrame->stx == ACK)
  767. {
  768. fprintf(pf, "\n///////////////////////////////////////\n");
  769. fprintf(pf, "// %ld.%03ld\n", tsIntv.tv_sec, tsIntv.tv_nsec / 1000000);
  770. fprintf(pf, "// %s:\n", bTX ? "TX" : "RX");
  771. fprintf(pf, "ACK: 06 (6)\n");
  772. }
  773. else if(pFrame->len >= 5)
  774. {
  775. int i, nCbData = pFrame->len - 5;
  776. fprintf(pf, "\n///////////////////////////////////////\n");
  777. fprintf(pf, "// %ld.%03ld\n", tsIntv.tv_sec, tsIntv.tv_nsec / 1000000);
  778. fprintf(pf, "// %s:\n", bTX ? "TX" : "RX");
  779. fprintf(pf, "STX: %02hhX (%hhu)\n", pFrame->stx, pFrame->stx);
  780. fprintf(pf, "Length: %02hhX (%hhu)\n", pFrame->len, pFrame->len);
  781. fprintf(pf, "Node: %02hhX (%hhu)\n", pFrame->node, pFrame->node);
  782. fprintf(pf, "Index: %02hhX (%hhu)\n", pFrame->index, pFrame->index);
  783. fprintf(pf, "Data: ");
  784. for(i = 0; i < nCbData; i++)
  785. {
  786. if(pFrame->data.by[i] >= 0x41 && pFrame->data.by[i] <= 0x5A)
  787. fprintf(pf, "<%c>", (char)pFrame->data.by[i]);
  788. else
  789. fprintf(pf, "[%02hhX]", (char)pFrame->data.by[i]);
  790. }
  791. fprintf(pf, "\nCRC: %02hhX (%hhu)\n", pFrame->data.by[i], pFrame->data.by[i]);
  792. if(pszAnnotation)
  793. fprintf(pf, "Annot.: %s\n", pszAnnotation);
  794. }
  795. }
  796. else
  797. {
  798. fprintf(pf, "\n///////////////////////////////////////\n");
  799. fprintf(pf, "// %ld:%03ld\n", tsIntv.tv_sec, tsIntv.tv_nsec / 1000000);
  800. fprintf(pf, "// %s:\n", bTX ? "TX" : "RX");
  801. fprintf(pf, "Invalid Mininet-Frame!\n");
  802. }
  803. fprintf(pf, "\n");
  804. fflush(pf);
  805. }
  806. }
  807. }
  808. /////////////////////////////////////////////////////////////////////////////
  809. int GfaMininetMasterSetVerbosity(HGFAMINEMST hMst, int nVerbosity)
  810. {
  811. if(hMst)
  812. {
  813. LPGFA_MININET_MASTER pMst = (LPGFA_MININET_MASTER)hMst;
  814. if(nVerbosity < 0)
  815. nVerbosity = 0;
  816. else if(nVerbosity > 4)
  817. nVerbosity = 4;
  818. pMst->nVerbosity = nVerbosity;
  819. return 0;
  820. }
  821. errno = EINVAL;
  822. return -1;
  823. }
  824. /////////////////////////////////////////////////////////////////////////////
  825. const char* GfaMininetMasterStrError(int nErrorCode)
  826. {
  827. switch(nErrorCode)
  828. {
  829. case MINET_SLAVE_RESPONSE_ERROR_STX_ERROR:
  830. return "First byte in Mininet Frame is neither STX nor ACK";
  831. case MINET_SLAVE_RESPONSE_ERROR_INVALID_ARGUMENT:
  832. return "An invalid argument was passed to GfaMininetMasterEvaluateSlaveResponse";
  833. case MINET_SLAVE_RESPONSE_ERROR_INVALID_LENGTH:
  834. return "Invalid Mininet Frame length";
  835. case MINET_SLAVE_RESPONSE_ERROR_INVALID_SLAVE_INDICATOR:
  836. return "Invalid Mininet slave indicator";
  837. case MINET_SLAVE_RESPONSE_ERROR_INCOMPLETE_DATA:
  838. return "Not enough data for Mininet Frame";
  839. case MINET_SLAVE_RESPONSE_ERROR_INVALID_NODE_ADDRESS:
  840. return "Invalid Mininet Node address";
  841. case MINET_SLAVE_RESPONSE_ERROR_INDEX_OUT_OF_RANGE:
  842. return "Mininet Index out of range";
  843. case MINET_SLAVE_RESPONSE_ERROR_INDEX_NO_MATCH:
  844. return "Mininet Index no match";
  845. case MINET_SLAVE_RESPONSE_ERROR_INVALID_CHECKSUM:
  846. return "Mininet Checksum error";
  847. case -MINET_SLAVE_STATUS_INDEX_RESET_DONE:
  848. return "Mininet index reset done";
  849. case -MINET_SLAVE_STATUS_INDEX_ERROR:
  850. return "Mininet index error";
  851. case -MINET_SLAVE_STATUS_INDEX_CMD_ERROR:
  852. return "Mininet command error";
  853. case -MINET_SLAVE_STATUS_INDEX_INVALID_PARAM:
  854. return "Mininet invalid parameter";
  855. case -MINET_SLAVE_STATUS_INDEX_UNKNOWN_CMD:
  856. return "Mininet unknown command";
  857. case -MINET_SLAVE_STATUS_INDEX_CMD_ALREADY_EX:
  858. return "Mininet command alearx executing";
  859. default:
  860. return strerror(nErrorCode);
  861. }
  862. }