gfamininetmst.c 26 KB

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