gfabootlmast.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <malloc.h>
  4. #include <ctype.h>
  5. #include <errno.h>
  6. #include <unistd.h>
  7. #include <gfaserial.h>
  8. #include <gfamininetmst.h>
  9. #include <byteswap.h>
  10. #include "bl_commands.h"
  11. #include "gfabootlmast.h"
  12. #include "dbghlp.h"
  13. ////////////////////////////////////////////////////////////////////////////////////
  14. #define _dword_offset(m) (offsetof(GFA_APP_IMG_HEADER, m) / sizeof(uint32_t) - 2)
  15. #define _EXEC_CALLBACK(pfn, ...) if(pfn) (*pfn)(__FILE__, __LINE__, __VA_ARGS__)
  16. #define _BOOTLOADER_EXEC_WAIT_TIME 250
  17. #define _GFA_MAX_DUMP_DWORDS 16
  18. #define _MAX_SEND_DATA_BLOCK_SIZE 76
  19. #define _DEF_SEND_DATA_BLOCK_SIZE 64
  20. ////////////////////////////////////////////////////////////////////////////////////
  21. typedef struct _GFA_BLM
  22. {
  23. HGFAMINEMST hMst;
  24. PFN_BU_CMD_DOWNLOAD_STATUS pfnBuCmdDownloadStatus;
  25. PFN_BU_CMD_SEND_DATA_STATUS pfnBuCmdSendDataStatus;
  26. int nVerbosity;
  27. }GFA_BLM, *LPGFA_BLM;
  28. typedef const GFA_BLM *LPCGFA_BLM;
  29. ////////////////////////////////////////////////////////////////////////////////////
  30. HGFABLM GfaBlmOpen(LPCGFA_BLM_CFG_PARAMS pblmcfg)
  31. {
  32. if(pblmcfg)
  33. {
  34. HGFAMINEMST hMst = GfaMininetMasterOpen(&pblmcfg->mmcp);
  35. if(hMst)
  36. {
  37. LPGFA_BLM pBlm = malloc(sizeof(GFA_BLM));
  38. memset(pBlm, 0, sizeof(GFA_BLM));
  39. pBlm->hMst = hMst;
  40. pBlm->pfnBuCmdDownloadStatus = pblmcfg->pfnBuCmdDownloadStatus;
  41. pBlm->pfnBuCmdSendDataStatus = pblmcfg->pfnBuCmdSendDataStatus;
  42. return (HGFABLM)pBlm;
  43. }
  44. return NULL;
  45. }
  46. errno = EINVAL;
  47. return NULL;
  48. }
  49. ////////////////////////////////////////////////////////////////////////////////////
  50. void GfaBlmClose(HGFABLM hBlm)
  51. {
  52. if(hBlm)
  53. {
  54. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  55. GfaMininetMasterClose(pBlm->hMst);
  56. free(pBlm);
  57. }
  58. }
  59. /////////////////////////////////////////////////////////////////////////////
  60. int GfaBlmResetSlaveIndex(HGFABLM hBlm, uint8_t nNodeAddr)
  61. {
  62. if(hBlm)
  63. {
  64. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  65. return GfaMininetMasterResetSlaveIndex(pBlm->hMst, nNodeAddr);
  66. }
  67. errno = EINVAL;
  68. return -1;
  69. }
  70. ////////////////////////////////////////////////////////////////////////////////////
  71. ssize_t GfaBlmBUCmdPollData(HGFABLM hBlm, uint8_t nNodeAddr, void *pData, size_t nCbData, uint32_t nTimeoutMS)
  72. {
  73. if(hBlm && pData && nCbData && !NODE_IS_MULTICAST(nNodeAddr))
  74. {
  75. size_t s, nReceived = 0;
  76. struct timeval tvRX;
  77. ssize_t nLen, nRet = -1;
  78. uint8_t cmd[32];
  79. uint8_t txb[32];
  80. uint8_t rxb[512];
  81. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  82. uint8_t *pszData = (uint8_t*)pData;
  83. tvRX.tv_sec = nTimeoutMS / 1000;
  84. tvRX.tv_usec = (nTimeoutMS % 1000) * 1000;
  85. GfaMininetMasterSaveTimeouts(pBlm->hMst);
  86. GfaMininetMasterSetTimeouts(pBlm->hMst, &tvRX, NULL);
  87. while(nReceived < nCbData)
  88. {
  89. s = GfaBlmBuildCmdDataPacket("BU", 0, NULL, 0, cmd, sizeof(cmd), true);
  90. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
  91. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) <= 0)
  92. {
  93. nRet = -1;
  94. break;
  95. }
  96. if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) > 0)
  97. {
  98. uint8_t nIndex;
  99. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
  100. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  101. {
  102. if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, pszData, nCbData - nReceived)) > 0)
  103. {
  104. pszData += nRet;
  105. nReceived += nRet;
  106. }
  107. }
  108. else if(nRet == MINET_SLAVE_RESPONSE_ACK)
  109. {
  110. if(nTimeoutMS > 0)
  111. {
  112. if(nTimeoutMS >= 100)
  113. {
  114. usleep(100000);
  115. nTimeoutMS -= 100;
  116. // TRACE("\nACK ...\n");
  117. }
  118. else
  119. {
  120. usleep(nTimeoutMS * 1000);
  121. nTimeoutMS = 0;
  122. // TRACE("\nACK ...\n");
  123. }
  124. }
  125. else
  126. {
  127. errno = ETIMEDOUT;
  128. nReceived = 0;
  129. break;
  130. }
  131. }
  132. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  133. {
  134. errno = -(int)nIndex;
  135. nReceived = 0;
  136. break;
  137. }
  138. else
  139. {
  140. errno = EPROTO;
  141. nReceived = 0;
  142. break;
  143. }
  144. }
  145. else
  146. {
  147. nReceived = 0;
  148. break;
  149. }
  150. }
  151. GfaMininetMasterRestoreTimeouts(pBlm->hMst);
  152. return nReceived;
  153. }
  154. errno = EINVAL;
  155. return -1;
  156. }
  157. /////////////////////////////////////////////////////////////////////////////
  158. int GfaBlmBUCmdReset(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nTimeoutMS)
  159. {
  160. if(hBlm)
  161. {
  162. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  163. uint8_t nIndex;
  164. size_t s;
  165. ssize_t nRet, nLen;
  166. uint8_t cmd = COMMAND_RESET;
  167. uint8_t cmddata[16];
  168. char txb[32], rxb[256], ack[2];
  169. if((nRet = GfaBlmBootloaderSetBaudrate(hBlm, nNodeAddr, 19200)) != 0)
  170. return -1;
  171. s = GfaBlmBuildCmdDataPacket("BU", 0, &cmd, 1, cmddata, sizeof(cmddata), true);
  172. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmddata, s, txb, sizeof(txb));
  173. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  174. return nRet;
  175. if(NODE_IS_MULTICAST(nNodeAddr))
  176. return 0;
  177. if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
  178. return nLen;
  179. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
  180. if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
  181. (nRet == MINET_SLAVE_RESPONSE_ACK))
  182. {
  183. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  184. {
  185. if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
  186. return -1;
  187. }
  188. else
  189. {
  190. if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 200)) != 2)
  191. return -1;
  192. }
  193. if( (ack[0] == 0) &&
  194. (ack[1] == COMMAND_ACK))
  195. {
  196. do
  197. {
  198. if(nTimeoutMS > _BOOTLOADER_EXEC_WAIT_TIME)
  199. {
  200. usleep(_BOOTLOADER_EXEC_WAIT_TIME * 1000);
  201. nTimeoutMS -= _BOOTLOADER_EXEC_WAIT_TIME;
  202. }
  203. else
  204. {
  205. usleep(nTimeoutMS * 1000);
  206. nTimeoutMS = 0;
  207. }
  208. if((nRet = GfaMininetMasterResetSlaveIndex(pBlm->hMst, nNodeAddr)) == 0)
  209. break;
  210. GfaMininetMasterPurgeDeviceRXBuffer(pBlm->hMst);
  211. }
  212. while(nTimeoutMS > 0);
  213. return nRet;
  214. }
  215. }
  216. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  217. {
  218. errno = -(int)nIndex;
  219. return -1;
  220. }
  221. return -1;
  222. }
  223. errno = EINVAL;
  224. return -1;
  225. }
  226. /////////////////////////////////////////////////////////////////////////////
  227. int GfaBlmBUCmdPing(HGFABLM hBlm, uint8_t nNodeAddr)
  228. {
  229. if(hBlm && !NODE_IS_MULTICAST(nNodeAddr))
  230. {
  231. uint8_t nIndex;
  232. ssize_t nRet, nLen;
  233. uint8_t nCmd = COMMAND_PING;
  234. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  235. char txb[32], rxb[32], cmd[8], ack[2];
  236. size_t s = GfaBlmBuildCmdDataPacket("BU", 0, &nCmd, 1, cmd, sizeof(cmd), true);
  237. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
  238. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) < nLen)
  239. return nRet;
  240. if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
  241. return nLen;
  242. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
  243. if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
  244. (nRet == MINET_SLAVE_RESPONSE_ACK))
  245. {
  246. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  247. {
  248. if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
  249. return -1;
  250. }
  251. else
  252. {
  253. if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 200)) != 2)
  254. return -1;
  255. }
  256. if(ack[0] == 0)
  257. {
  258. return (ack[1] == COMMAND_ACK);
  259. }
  260. else
  261. {
  262. errno = EPROTO;
  263. return -1;
  264. }
  265. }
  266. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  267. {
  268. errno = -(int)nIndex;
  269. return -1;
  270. }
  271. return -1;
  272. }
  273. errno = EINVAL;
  274. return -1;
  275. }
  276. /////////////////////////////////////////////////////////////////////////////
  277. int GfaBlmBUCmdGetStatus(HGFABLM hBlm, uint8_t nNodeAddr, uint8_t *pbStatus)
  278. {
  279. if(hBlm && pbStatus && !NODE_IS_MULTICAST(nNodeAddr))
  280. {
  281. uint8_t nIndex;
  282. ssize_t nRet, nLen;
  283. uint8_t nCmd = COMMAND_GET_STATUS;
  284. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  285. char txb[32], rxb[32], cmd[8], ack[3], stat[3];
  286. size_t s = GfaBlmBuildCmdDataPacket("BU", 0, &nCmd, 1, cmd, sizeof(cmd), true);
  287. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
  288. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) < nLen)
  289. return nRet;
  290. if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
  291. return nLen;
  292. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
  293. if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
  294. (nRet == MINET_SLAVE_RESPONSE_ACK))
  295. {
  296. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  297. {
  298. if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
  299. return -1;
  300. }
  301. else
  302. {
  303. if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 200)) != 2)
  304. return -1;
  305. }
  306. if(ack[0] == 0)
  307. {
  308. if(ack[1] == COMMAND_ACK)
  309. {
  310. if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, stat, 3, 200)) != 3)
  311. return -1;
  312. if((stat[0] == 3) && (stat[1] == stat[2]))
  313. {
  314. if(pbStatus)
  315. *pbStatus = stat[2];
  316. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BU\xCC", 3, txb, sizeof(txb));
  317. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  318. return nRet;
  319. if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
  320. return nRet;
  321. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
  322. return 0;
  323. }
  324. else
  325. {
  326. errno = EPROTO;
  327. return -1;
  328. }
  329. }
  330. else
  331. {
  332. errno = EPROTO;
  333. return -1;
  334. }
  335. }
  336. else
  337. {
  338. errno = EPROTO;
  339. return -1;
  340. }
  341. }
  342. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  343. {
  344. errno = -(int)nIndex;
  345. return -1;
  346. }
  347. return -1;
  348. }
  349. errno = EINVAL;
  350. return -1;
  351. }
  352. /////////////////////////////////////////////////////////////////////////////
  353. int GfaBlmBUCmdDownload(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nFlashStartAddr, uint32_t nCbData, uint32_t nTimeoutMS)
  354. {
  355. if(hBlm && nCbData && !NODE_IS_MULTICAST(nNodeAddr))
  356. {
  357. size_t s;
  358. ssize_t nRet, nLen;
  359. uint8_t nIndex, nStatus;
  360. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  361. uint32_t nAddr = bswap_32(nFlashStartAddr), nCount = bswap_32(nCbData);
  362. uint8_t txb[32], rxb[32], cmd[16], data[9], ack[2];
  363. data[0] = COMMAND_DOWNLOAD;
  364. struct timeval tv;
  365. memcpy(&data[1], &nAddr, sizeof(nAddr));
  366. memcpy(&data[5], &nCount, sizeof(nCount));
  367. tv.tv_sec = nTimeoutMS / 1000;
  368. tv.tv_usec = (nTimeoutMS % 1000) * 1000;
  369. s = GfaBlmBuildCmdDataPacket("BU", 0, data, sizeof(data), cmd, sizeof(cmd), true);
  370. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
  371. GfaMininetMasterSaveTimeouts(pBlm->hMst);
  372. GfaMininetMasterSetTimeouts(pBlm->hMst, &tv, NULL);
  373. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 1, 0);
  374. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  375. {
  376. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
  377. GfaMininetMasterRestoreTimeouts(pBlm->hMst);
  378. return -1;
  379. }
  380. if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
  381. {
  382. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
  383. GfaMininetMasterRestoreTimeouts(pBlm->hMst);
  384. return -1;
  385. }
  386. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 2, 0);
  387. GfaMininetMasterRestoreTimeouts(pBlm->hMst);
  388. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
  389. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  390. {
  391. if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
  392. {
  393. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
  394. return -1;
  395. }
  396. if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
  397. {
  398. if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
  399. {
  400. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
  401. return -1;
  402. }
  403. if(nStatus == COMMAND_RET_SUCCESS)
  404. {
  405. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 3, 0);
  406. return 0;
  407. }
  408. }
  409. errno = EPROTO;
  410. return -1;
  411. }
  412. else if(nRet == MINET_SLAVE_RESPONSE_ACK)
  413. {
  414. if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, nTimeoutMS)) != 2)
  415. {
  416. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
  417. return -1;
  418. }
  419. if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
  420. {
  421. if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
  422. {
  423. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
  424. return -1;
  425. }
  426. if(nStatus == COMMAND_RET_SUCCESS)
  427. {
  428. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 3, 0);
  429. return 0;
  430. }
  431. }
  432. errno = EPROTO;
  433. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
  434. return -1;
  435. }
  436. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  437. {
  438. errno = -(int)nIndex;
  439. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
  440. return -1;
  441. }
  442. else
  443. {
  444. errno = EPROTO;
  445. _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
  446. return -1;
  447. }
  448. }
  449. errno = EINVAL;
  450. return -1;
  451. }
  452. /////////////////////////////////////////////////////////////////////////////
  453. int GfaBlmBUCmdSendDataBlock(HGFABLM hBlm, uint8_t nNodeAddr, const void *pDataBlock, size_t nCbDataBlock)
  454. {
  455. if(hBlm && pDataBlock && nCbDataBlock && (nCbDataBlock <= 250) && !NODE_IS_MULTICAST(nNodeAddr))
  456. {
  457. ssize_t nRet;
  458. struct timeval tv;
  459. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  460. tv.tv_sec = 0;
  461. tv.tv_usec = 500000;
  462. GfaMininetMasterSaveTimeouts(pBlm->hMst);
  463. GfaMininetMasterSetTimeouts(pBlm->hMst, &tv, NULL);
  464. do
  465. {
  466. size_t s;
  467. ssize_t nLen;
  468. uint8_t nIndex, nStatus;
  469. uint8_t txb[512], rxb[32], cmd[256], data[256], ack[2];
  470. data[0] = COMMAND_SEND_DATA;
  471. memcpy(&data[1], pDataBlock, nCbDataBlock);
  472. s = GfaBlmBuildCmdDataPacket("BU", 0, data, nCbDataBlock + 1, cmd, sizeof(cmd), true);
  473. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
  474. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  475. {
  476. nRet = -1;
  477. break;
  478. }
  479. if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
  480. {
  481. nRet = -1;
  482. break;
  483. }
  484. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
  485. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  486. {
  487. if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
  488. {
  489. nRet = -1;
  490. break;
  491. }
  492. if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
  493. {
  494. if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
  495. {
  496. nRet = -1;
  497. break;
  498. }
  499. if(nStatus != COMMAND_RET_SUCCESS)
  500. {
  501. errno = -nStatus;
  502. nRet = -1;
  503. break;
  504. }
  505. nRet = 0;
  506. break;
  507. }
  508. errno = EPROTO;
  509. nRet = -1;
  510. break;
  511. }
  512. else if(nRet == MINET_SLAVE_RESPONSE_ACK)
  513. {
  514. if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 5000)) != 2)
  515. {
  516. nRet = -1;
  517. break;
  518. }
  519. if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
  520. {
  521. if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
  522. {
  523. nRet = -1;
  524. break;
  525. }
  526. if(nStatus != COMMAND_RET_SUCCESS)
  527. {
  528. errno = -nStatus;
  529. nRet = -1;
  530. break;
  531. }
  532. nRet = 0;
  533. break;
  534. }
  535. errno = EPROTO;
  536. nRet = -1;
  537. break;
  538. }
  539. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  540. {
  541. errno = -(int)nIndex;
  542. nRet = -1;
  543. break;
  544. }
  545. }
  546. while(false);
  547. GfaMininetMasterRestoreTimeouts(pBlm->hMst);
  548. return nRet;
  549. }
  550. errno = EINVAL;
  551. return -1;
  552. }
  553. /////////////////////////////////////////////////////////////////////////////
  554. int GfaBlmBUCmdSendData(HGFABLM hBlm, uint8_t nNodeAddr, const void *pData, size_t nCbData, size_t nCbBlock)
  555. {
  556. if(hBlm && pData && nCbData && !NODE_IS_MULTICAST(nNodeAddr))
  557. {
  558. int nRet;
  559. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  560. const uint8_t *pbData = (const uint8_t*)pData;
  561. uint32_t nSent = 0;
  562. if(!nCbBlock || nCbBlock < 4 || nCbBlock > _MAX_SEND_DATA_BLOCK_SIZE)
  563. nCbBlock = _DEF_SEND_DATA_BLOCK_SIZE;
  564. else
  565. nCbBlock &= ~0x03;
  566. _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 1, 0);
  567. while(nCbData >= nCbBlock)
  568. {
  569. if((nRet = GfaBlmBUCmdSendDataBlock(hBlm, nNodeAddr, pbData, nCbBlock)) != 0)
  570. {
  571. _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 0, errno);
  572. return -1;
  573. }
  574. nCbData -= nCbBlock;
  575. pbData += nCbBlock;
  576. nSent += nCbBlock;
  577. _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 2, 0);
  578. }
  579. if(nCbData)
  580. {
  581. if((nRet = GfaBlmBUCmdSendDataBlock(hBlm, nNodeAddr, pbData, nCbData)) != 0)
  582. {
  583. _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 0, errno);
  584. return -1;
  585. }
  586. nSent += nCbData;
  587. nCbData = 0;
  588. _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 2, 0);
  589. }
  590. _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 3, 0);
  591. return 0;
  592. }
  593. errno = EINVAL;
  594. return -1;
  595. }
  596. /////////////////////////////////////////////////////////////////////////////
  597. int GfaBlmBUCmdSendDataFile(HGFABLM hBlm, uint8_t nNodeAddr, const char *pszFilename, uint32_t nFlashStartAddr, size_t nCbBlock, uint32_t nTimeoutMS)
  598. {
  599. if(hBlm && pszFilename && !NODE_IS_MULTICAST(nNodeAddr))
  600. {
  601. int nRet = -1;
  602. ssize_t nFileLen;
  603. FILE *pf = NULL;
  604. uint8_t *pBuf = NULL;
  605. do
  606. {
  607. if(!(pf = fopen(pszFilename, "rb")))
  608. break;
  609. if(fseek(pf, 0, SEEK_END))
  610. break;
  611. if((nFileLen = ftell(pf)) < 0)
  612. break;
  613. if(fseek(pf, 0, SEEK_SET))
  614. break;
  615. if( (nFileLen > 0) &&
  616. (pBuf = (uint8_t*)malloc(nFileLen)) &&
  617. (fread(pBuf, 1, nFileLen, pf) == (size_t)nFileLen))
  618. {
  619. if((nRet = GfaBlmBUCmdDownload(hBlm, nNodeAddr, nFlashStartAddr, nFileLen, nTimeoutMS)) == 0)
  620. nRet = GfaBlmBUCmdSendData(hBlm, nNodeAddr, pBuf, nFileLen, nCbBlock);
  621. }
  622. }
  623. while(false);
  624. if(pBuf)
  625. free(pBuf);
  626. if(pf)
  627. fclose(pf);
  628. return nRet;
  629. }
  630. errno = EINVAL;
  631. return -1;
  632. }
  633. /////////////////////////////////////////////////////////////////////////////
  634. GFA_BLM_EXEC_CONTEXT GfaBlmGetExecutionContext(HGFABLM hBlm, uint8_t nNodeAddr)
  635. {
  636. if(hBlm && !NODE_IS_MULTICAST(nNodeAddr))
  637. {
  638. uint8_t nIndex;
  639. ssize_t nRet, nLen;
  640. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  641. char txb[32], rxb[32];
  642. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BU", 2, txb, sizeof(txb));
  643. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  644. return GfaBlmCtx_Err;
  645. if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
  646. return GfaBlmCtx_Err;
  647. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
  648. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  649. return GfaBlmCtx_Err;
  650. else if(nRet == MINET_SLAVE_RESPONSE_ACK)
  651. return GfaBlmCtx_Boot;
  652. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  653. return GfaBlmCtx_App;
  654. return GfaBlmCtx_Err;
  655. }
  656. errno = EINVAL;
  657. return GfaBlmCtx_Err;
  658. }
  659. /////////////////////////////////////////////////////////////////////////////
  660. int GfaBlmBootloaderExecute(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t *pnImgCRC32, uint32_t nTimeoutMS)
  661. {
  662. if(hBlm && !NODE_IS_MULTICAST(nNodeAddr))
  663. {
  664. uint8_t nIndex;
  665. uint32_t nImgCRC32;
  666. ssize_t nRet, nLen;
  667. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  668. char txb[32], rxb[32];
  669. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BE", 2, txb, sizeof(txb));
  670. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  671. return -1;
  672. if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
  673. return nLen;
  674. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
  675. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  676. {
  677. if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, &nImgCRC32, sizeof(nImgCRC32))) == 4)
  678. {
  679. if(pnImgCRC32)
  680. *pnImgCRC32 = bswap_32(nImgCRC32);
  681. do
  682. {
  683. if(nTimeoutMS > _BOOTLOADER_EXEC_WAIT_TIME)
  684. {
  685. usleep(_BOOTLOADER_EXEC_WAIT_TIME * 1000);
  686. nTimeoutMS -= _BOOTLOADER_EXEC_WAIT_TIME;
  687. }
  688. else
  689. {
  690. usleep(nTimeoutMS * 1000);
  691. nTimeoutMS = 0;
  692. }
  693. if((nRet = GfaMininetMasterResetSlaveIndex(pBlm->hMst, nNodeAddr)) == 0)
  694. break;
  695. GfaMininetMasterPurgeDeviceRXBuffer(pBlm->hMst);
  696. }
  697. while(nTimeoutMS > 0);
  698. return nRet;
  699. }
  700. }
  701. else if(nRet == MINET_SLAVE_RESPONSE_ACK)
  702. {
  703. return 0;
  704. }
  705. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  706. {
  707. errno = -(int)nIndex;
  708. return -1;
  709. }
  710. return -1;
  711. }
  712. errno = EINVAL;
  713. return -1;
  714. }
  715. /////////////////////////////////////////////////////////////////////////////
  716. int GfaBlmBootloaderSetBaudrate(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nBaudrate)
  717. {
  718. if(hBlm)
  719. {
  720. uint8_t nIndex;
  721. size_t s;
  722. ssize_t nRet, nLen;
  723. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  724. if(GfaMininetMasterIsValidBaudrate(pBlm->hMst, nBaudrate))
  725. {
  726. char txb[32], rxb[32], cmd[8];
  727. uint32_t nBr = bswap_32(nBaudrate);
  728. s = GfaBlmBuildCmdDataPacket("BB", 0, &nBr, sizeof(nBr), cmd, sizeof(cmd), false);
  729. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
  730. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  731. return nRet;
  732. if(NODE_IS_MULTICAST(nNodeAddr))
  733. return 0;
  734. if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
  735. return nLen;
  736. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
  737. if(nRet == MINET_SLAVE_RESPONSE_ACK)
  738. {
  739. return GfaMininetMasterSetBaudrate(pBlm->hMst, nBaudrate);
  740. }
  741. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  742. {
  743. errno = -(int)nIndex;
  744. return -1;
  745. }
  746. return -1;
  747. }
  748. }
  749. errno = EINVAL;
  750. return -1;
  751. }
  752. /////////////////////////////////////////////////////////////////////////////
  753. int GfaBlmBootloaderDump(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nAddress, uint32_t nCntDwords, void *pBuffer, size_t nCbBuffer)
  754. {
  755. if(hBlm && pBuffer && nCntDwords && !NODE_IS_MULTICAST(nNodeAddr))
  756. {
  757. size_t s;
  758. uint8_t nIndex;
  759. ssize_t nRet, nLen;
  760. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  761. uint32_t i, dmp[_GFA_MAX_DUMP_DWORDS];
  762. char txb[32], rxb[128], cmd[10];
  763. if(nCntDwords > _GFA_MAX_DUMP_DWORDS)
  764. nCntDwords = _GFA_MAX_DUMP_DWORDS;
  765. if((nCntDwords * sizeof(uint32_t)) > nCbBuffer)
  766. {
  767. errno = ENOMEM;
  768. return -1;
  769. }
  770. struct _MEM
  771. {
  772. uint32_t nAddr;
  773. uint32_t nCount;
  774. }mem = {bswap_32(nAddress), bswap_32(nCntDwords)};
  775. s = GfaBlmBuildCmdDataPacket("BD", 0, &mem, sizeof(mem), cmd, sizeof(cmd), false);
  776. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
  777. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  778. return nRet;
  779. if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
  780. return nLen;
  781. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
  782. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  783. {
  784. if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, dmp, sizeof(uint32_t) * nCntDwords)) != (ssize_t)(sizeof(uint32_t) * nCntDwords))
  785. return -1;
  786. for(i = 0; i < nCntDwords; ++i)
  787. {
  788. dmp[i] = bswap_32(dmp[i]);
  789. }
  790. memcpy(pBuffer, dmp, sizeof(uint32_t) * nCntDwords);
  791. return 0;
  792. }
  793. else if(nRet == MINET_SLAVE_RESPONSE_ACK)
  794. {
  795. if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, dmp, sizeof(uint32_t) * nCntDwords, 200)) != (ssize_t)(sizeof(uint32_t) * nCntDwords))
  796. return -1;
  797. for(i = 0; i < nCntDwords; ++i)
  798. {
  799. dmp[i] = bswap_32(dmp[i]);
  800. }
  801. memcpy(pBuffer, dmp, sizeof(uint32_t) * nCntDwords);
  802. return 0;
  803. }
  804. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  805. {
  806. errno = -(int)nIndex;
  807. return -1;
  808. }
  809. return -1;
  810. }
  811. errno = EINVAL;
  812. return -1;
  813. }
  814. int GfaBlmGetImgInfo(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nDumpAddr, bool bCtxIsApp, LPGFA_IMG_INFO pii)
  815. {
  816. if(hBlm && pii && !NODE_IS_MULTICAST(nNodeAddr))
  817. {
  818. ssize_t nRet = 0;
  819. uint32_t i, j, nPfx0Addr = 0;
  820. int32_t nPfx0Index = -1, nPfx1Index = -1;
  821. uint32_t aDump[_GFA_MAX_DUMP_DWORDS];
  822. GFA_APP_IMG_HEADER aih;
  823. memset(&aih, 0, sizeof(aih));
  824. memset(pii, 0, sizeof(GFA_IMG_INFO));
  825. for(i = 0; i < 257; i += _GFA_MAX_DUMP_DWORDS)
  826. {
  827. if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, nDumpAddr, _GFA_MAX_DUMP_DWORDS, aDump, sizeof(aDump))) == 0)
  828. {
  829. for(j = 0; j < _GFA_MAX_DUMP_DWORDS; ++j, nDumpAddr += sizeof(uint32_t))
  830. {
  831. switch(aDump[j])
  832. {
  833. case GFA_APP_IMG_HEADER_PREFIX_0:
  834. nPfx0Addr = nDumpAddr;
  835. nPfx0Index = i + j;
  836. continue;
  837. case GFA_APP_IMG_HEADER_PREFIX_1:
  838. nPfx1Index = i + j;
  839. break;
  840. default:
  841. break;
  842. }
  843. if((nPfx0Index >= 0) && (nPfx1Index == (nPfx0Index + 1)))
  844. {
  845. uint32_t nDmpStart = nPfx0Addr + 2 * sizeof(uint32_t), *pDwDst = ((uint32_t*)&aih) + 2;
  846. uint32_t nCntDwAvail = 15 - j;
  847. if(bCtxIsApp)
  848. {
  849. uint32_t nDwOffsImgMaterialNum = _dword_offset(app.pszImgMaterialNum);
  850. uint32_t nDwOffsImgNameBuild = _dword_offset(app.pszImgNameBuild);
  851. uint32_t nDwOffsImgCRC32 = _dword_offset(nImgCRC32);
  852. size_t nSizeDst = (nDwOffsImgNameBuild + 1) * sizeof(uint32_t);
  853. uint32_t nCntDwToDmp, nCntDwToCpy;
  854. if(nCntDwAvail > nDwOffsImgNameBuild)
  855. {
  856. // have nImgLength, nImgCRC32, pszImgMaterialNum, pszImgNameBuild
  857. // need nothing
  858. nCntDwToCpy = nDwOffsImgNameBuild + 1;
  859. nCntDwToDmp = 0;
  860. memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
  861. }
  862. else if(nCntDwAvail == nDwOffsImgNameBuild)
  863. {
  864. // have nImgLength, nImgCRC32, pszImgMaterialNum
  865. // need pszImgNameBuild
  866. nCntDwToCpy = nDwOffsImgNameBuild;
  867. nCntDwToDmp = 1;
  868. nDmpStart += nCntDwToCpy * sizeof(uint32_t);
  869. memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
  870. pDwDst += nCntDwToCpy;
  871. nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
  872. }
  873. else if(nCntDwAvail > nDwOffsImgCRC32)
  874. {
  875. // have nImgLength, nImgCRC32
  876. // need pszImgMaterialNum, pszImgNameBuild
  877. nCntDwToCpy = 2;
  878. nCntDwToDmp = 2;
  879. nDmpStart += nDwOffsImgMaterialNum * sizeof(uint32_t);
  880. memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
  881. pDwDst += nDwOffsImgMaterialNum;
  882. nSizeDst -= nDwOffsImgMaterialNum * sizeof(uint32_t);
  883. }
  884. else if(nCntDwAvail == nDwOffsImgCRC32)
  885. {
  886. // have nImgLength
  887. // need nImgCRC32, pszImgMaterialNum, pszImgNameBuild
  888. nCntDwToCpy = nDwOffsImgCRC32;
  889. nCntDwToDmp = 7; // 1 + 4 + 2
  890. nDmpStart += sizeof(uint32_t);
  891. memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
  892. pDwDst += nCntDwToCpy;
  893. nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
  894. }
  895. else
  896. {
  897. // have nothing
  898. // need nImgLength, nImgCRC32, pszImgMaterialNum, pszImgNameBuild
  899. nCntDwToCpy = 0;
  900. nCntDwToDmp = nDwOffsImgNameBuild + 1; // 2 + 4 + 2
  901. }
  902. if(nCntDwToDmp)
  903. {
  904. if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, nDmpStart, nCntDwToDmp, pDwDst, nSizeDst)) != 0)
  905. return -1;
  906. }
  907. pii->nImgLength = aih.nImgLength;
  908. pii->nImgCRC32 = aih.nImgCRC32;
  909. if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, (uint32_t)aih.app.pszImgMaterialNum, GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH / sizeof(uint32_t), pii->szImgMaterialNum, GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH)) != 0)
  910. return -1;
  911. if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, (uint32_t)aih.app.pszImgNameBuild, GFA_APP_MAX_IMG_NAME_BUILD_LENGTH / sizeof(uint32_t), pii->szImgNameBuild, GFA_APP_MAX_IMG_NAME_BUILD_LENGTH)) != 0)
  912. return -1;
  913. pii->szImgMaterialNum[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH - 1] = '\0';
  914. pii->szImgNameBuild[GFA_APP_MAX_IMG_NAME_BUILD_LENGTH - 1] = '\0';
  915. return 0;
  916. }
  917. else
  918. {
  919. uint32_t nDwOffsImgMaterialNum = _dword_offset(bl.szImgMaterialNum);
  920. uint32_t nDwOffsImgNameBuild = _dword_offset(bl.szImgNameBuild);
  921. uint32_t nDwOffsImgCRC32 = _dword_offset(nImgCRC32);
  922. size_t nSizeDst = nDwOffsImgNameBuild * sizeof(uint32_t) + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH;
  923. uint32_t nCntDwToDmp, nCntDwToCpy;
  924. if(nCntDwAvail >= (nDwOffsImgNameBuild + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH / sizeof(uint32_t)))
  925. {
  926. // have nImgLength, nImgCRC32, szImgMaterialNum, szImgNameBuild
  927. // need nothing
  928. nCntDwToCpy = nDwOffsImgNameBuild + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH / sizeof(uint32_t);
  929. nCntDwToDmp = 0;
  930. memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
  931. }
  932. else if(nCntDwAvail > nDwOffsImgMaterialNum)
  933. {
  934. // have nImgLength, nImgCRC32, szImgMaterialNum
  935. // need szImgNameBuild
  936. nCntDwToCpy = nCntDwAvail;
  937. nCntDwToDmp = nSizeDst / sizeof(uint32_t) - nCntDwToCpy; // (1...3) + 6
  938. nDmpStart += nCntDwToCpy * sizeof(uint32_t);
  939. memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
  940. pDwDst += nCntDwToCpy;
  941. nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
  942. }
  943. else if(nCntDwAvail > nDwOffsImgCRC32)
  944. {
  945. // have nImgLength, nImgCRC32
  946. // need szImgMaterialNum, szImgNameBuild
  947. nCntDwToCpy = 2;
  948. nCntDwToDmp = (GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH) / sizeof(uint32_t); // 4 + 6
  949. nDmpStart += nDwOffsImgMaterialNum * sizeof(uint32_t);
  950. memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
  951. pDwDst += nDwOffsImgMaterialNum;
  952. nSizeDst -= nDwOffsImgMaterialNum * sizeof(uint32_t);
  953. }
  954. else if(nCntDwAvail == nDwOffsImgCRC32)
  955. {
  956. // have nImgLength
  957. // need nImgCRC32, szImgMaterialNum, szImgNameBuild
  958. nCntDwToCpy = nDwOffsImgCRC32;
  959. nCntDwToDmp = nSizeDst / sizeof(uint32_t) - nCntDwToCpy; // 1 + 4 + 4 + 6
  960. nDmpStart += sizeof(uint32_t);
  961. memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
  962. pDwDst += nCntDwToCpy;
  963. nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
  964. }
  965. else
  966. {
  967. // have nothing
  968. // need nImgLength, nImgCRC32, pszImgMaterialNum, pszImgNameBuild
  969. nCntDwToCpy = 0;
  970. nCntDwToDmp = nSizeDst / sizeof(uint32_t); // 2 + 4 + 4 + 6
  971. }
  972. if(nCntDwToDmp)
  973. {
  974. if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, nDmpStart, nCntDwToDmp, pDwDst, nSizeDst)) != 0)
  975. return -1;
  976. }
  977. pii->nImgLength = aih.nImgLength;
  978. pii->nImgCRC32 = aih.nImgCRC32;
  979. memcpy(pii->szImgMaterialNum, aih.bl.szImgMaterialNum, GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH);
  980. memcpy(pii->szImgNameBuild, aih.bl.szImgNameBuild, GFA_APP_MAX_IMG_NAME_BUILD_LENGTH);
  981. pii->szImgMaterialNum[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH - 1] = '\0';
  982. pii->szImgNameBuild[GFA_APP_MAX_IMG_NAME_BUILD_LENGTH - 1] = '\0';
  983. return 0;
  984. }
  985. }
  986. }
  987. }
  988. else
  989. {
  990. break;
  991. }
  992. }
  993. return -1;
  994. }
  995. errno = EINVAL;
  996. return -1;
  997. }
  998. /////////////////////////////////////////////////////////////////////////////
  999. int GfaBlmGetInfoBD(HGFABLM hBlm, uint8_t nNodeAddr, LPGFA_BL_APP_IMG_INFO paii)
  1000. {
  1001. if(hBlm && paii && !NODE_IS_MULTICAST(nNodeAddr))
  1002. {
  1003. int nRet1, nRet2;
  1004. if((nRet1 = GfaBlmGetImgInfo(hBlm, nNodeAddr, GFA_APP_BOOTLOADER_START_ADDRESS, false, &paii->bl)) < 0)
  1005. {
  1006. memset(&paii->bl, 0, sizeof(paii->bl));
  1007. paii->bl.nImgLength = paii->bl.nImgCRC32 = 0xFFFFFFFF;
  1008. }
  1009. if((nRet2 = GfaBlmGetImgInfo(hBlm, nNodeAddr, GFA_APP_APPLICATION_START_ADDRESS, true, &paii->app)) < 0)
  1010. {
  1011. memset(&paii->app, 0, sizeof(paii->app));
  1012. paii->app.nImgLength = paii->app.nImgCRC32 = 0xFFFFFFFF;
  1013. }
  1014. return nRet1 + nRet2;
  1015. }
  1016. errno = EINVAL;
  1017. return -1;
  1018. }
  1019. /////////////////////////////////////////////////////////////////////////////
  1020. int GfaBlmGetInfoBI(HGFABLM hBlm, uint8_t nNodeAddr, LPGFA_BL_APP_IMG_INFO paii)
  1021. {
  1022. if(hBlm && paii && !NODE_IS_MULTICAST(nNodeAddr))
  1023. {
  1024. uint8_t nIndex;
  1025. ssize_t nRet, nLen;
  1026. char txb[32], rxb[256];
  1027. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  1028. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BI", 2, txb, sizeof(txb));
  1029. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  1030. return nRet;
  1031. if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
  1032. return nLen;
  1033. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
  1034. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  1035. {
  1036. if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, paii, sizeof(GFA_BL_APP_IMG_INFO))) == sizeof(GFA_BL_APP_IMG_INFO))
  1037. {
  1038. paii->bl.nImgLength = bswap_32(paii->bl.nImgLength);
  1039. paii->bl.nImgCRC32 = bswap_32(paii->bl.nImgCRC32);
  1040. paii->app.nImgLength = bswap_32(paii->app.nImgLength);
  1041. paii->app.nImgCRC32 = bswap_32(paii->app.nImgCRC32);
  1042. return 0;
  1043. }
  1044. errno = EPROTO;
  1045. return -1;
  1046. }
  1047. else if(nRet == MINET_SLAVE_RESPONSE_ACK)
  1048. {
  1049. errno = EPROTO;
  1050. return -1;
  1051. }
  1052. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  1053. {
  1054. errno = -(int)nIndex;
  1055. return -1;
  1056. }
  1057. return -1;
  1058. }
  1059. errno = EINVAL;
  1060. return -1;
  1061. }
  1062. /////////////////////////////////////////////////////////////////////////////
  1063. int GfaBlmReadMaterialAndSerialID(HGFABLM hBlm, uint8_t nNodeAddr, char *pszMaterial, size_t nCbMaterial, char *pszSerial, size_t nCbSerial)
  1064. {
  1065. if(hBlm && pszMaterial && (nCbMaterial >= GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH) && pszSerial && (nCbSerial >= GFA_APP_MAX_IMG_SERIAL_NUM_LENGTH) && !NODE_IS_MULTICAST(nNodeAddr))
  1066. {
  1067. uint8_t nIndex;
  1068. ssize_t nRet, nLen;
  1069. char txb[32], rxb[64], data[32];
  1070. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  1071. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BR", 2, txb, sizeof(txb));
  1072. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  1073. return nRet;
  1074. if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
  1075. return nLen;
  1076. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
  1077. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  1078. {
  1079. if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, data, sizeof(data))) != (GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH + GFA_APP_MAX_IMG_SERIAL_NUM_LENGTH))
  1080. return -1;
  1081. memcpy(pszMaterial, data, GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH);
  1082. pszMaterial[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH - 1] = '\0';
  1083. memcpy(pszSerial, &data[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH], GFA_APP_MAX_IMG_SERIAL_NUM_LENGTH);
  1084. pszSerial[GFA_APP_MAX_IMG_SERIAL_NUM_LENGTH - 1] = '\0';
  1085. return 0;
  1086. }
  1087. else if(nRet == MINET_SLAVE_RESPONSE_ACK)
  1088. {
  1089. if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, data, sizeof(data), 200)) != (ssize_t)sizeof(data))
  1090. return -1;
  1091. memcpy(pszMaterial, data, GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH);
  1092. pszMaterial[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH - 1] = '\0';
  1093. memcpy(pszSerial, &data[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH], GFA_APP_MAX_IMG_SERIAL_NUM_LENGTH);
  1094. pszSerial[GFA_APP_MAX_IMG_SERIAL_NUM_LENGTH - 1] = '\0';
  1095. return 0;
  1096. }
  1097. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  1098. {
  1099. errno = -(int)nIndex;
  1100. return -1;
  1101. }
  1102. return -1;
  1103. }
  1104. errno = EINVAL;
  1105. return -1;
  1106. }
  1107. /////////////////////////////////////////////////////////////////////////////
  1108. int GfaBlmWriteMaterialAndSerialID(HGFABLM hBlm, uint8_t nNodeAddr, const char *pszMaterial, const char *pszSerial)
  1109. {
  1110. if(hBlm && pszMaterial && pszSerial && !NODE_IS_MULTICAST(nNodeAddr))
  1111. {
  1112. uint8_t nIndex;
  1113. size_t s;
  1114. ssize_t nRet, nLen;
  1115. size_t nLenMaterial, nLenSerial;
  1116. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  1117. struct _TS
  1118. {
  1119. char szMaterial[16];
  1120. char szSerial[16];
  1121. }ts;
  1122. char txb[64], rxb[32], cmd[64];
  1123. nLenMaterial = strlen(pszMaterial);
  1124. nLenSerial = strlen(pszSerial);
  1125. if((nLenMaterial > 15) || (nLenSerial > 15))
  1126. return -1;
  1127. memcpy(ts.szMaterial, pszMaterial, nLenMaterial);
  1128. if(nLenMaterial < 15)
  1129. memset(&ts.szMaterial[nLenMaterial], ' ', 15 - nLenMaterial);
  1130. ts.szMaterial[15] = '\0';
  1131. memcpy(ts.szSerial, pszSerial, nLenSerial);
  1132. if(nLenSerial < 15)
  1133. memset(&ts.szSerial[nLenSerial], ' ', 15 - nLenSerial);
  1134. ts.szSerial[15] = '\0';
  1135. s = GfaBlmBuildCmdDataPacket("BW", 0, &ts, sizeof(ts), cmd, sizeof(cmd), false);
  1136. nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
  1137. if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
  1138. return nRet;
  1139. if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
  1140. return nRet;
  1141. nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
  1142. if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
  1143. {
  1144. return 0;
  1145. }
  1146. else if(nRet == MINET_SLAVE_RESPONSE_ACK)
  1147. {
  1148. return 0;
  1149. }
  1150. else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
  1151. {
  1152. errno = -(int)nIndex;
  1153. return -1;
  1154. }
  1155. return -1;
  1156. }
  1157. errno = EINVAL;
  1158. return -1;
  1159. }
  1160. /////////////////////////////////////////////////////////////////////////////
  1161. HGFAMINEMST GfaBlmGetMininetMasterHandle(HGFABLM hBlm)
  1162. {
  1163. if(hBlm)
  1164. {
  1165. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  1166. return pBlm->hMst;
  1167. }
  1168. errno = EINVAL;
  1169. return NULL;
  1170. }
  1171. /////////////////////////////////////////////////////////////////////////////
  1172. int GfaBlmSetVerbosity(HGFABLM hBlm, int nVerbosity)
  1173. {
  1174. if(hBlm)
  1175. {
  1176. LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
  1177. if(nVerbosity < 0)
  1178. nVerbosity = 0;
  1179. else if(nVerbosity > 4)
  1180. nVerbosity = 4;
  1181. pBlm->nVerbosity = nVerbosity;
  1182. return GfaMininetMasterSetVerbosity(pBlm->hMst, pBlm->nVerbosity);
  1183. }
  1184. errno = EINVAL;
  1185. return -1;
  1186. }
  1187. /////////////////////////////////////////////////////////////////////////////
  1188. uint8_t GfaBlmDataCheckSum(const void *pData, size_t nCbData)
  1189. {
  1190. uint8_t chk = 0;
  1191. const uint8_t *pbData = (const uint8_t*)pData;
  1192. while(nCbData--) {
  1193. chk += *pbData++;
  1194. }
  1195. return chk;
  1196. }
  1197. /////////////////////////////////////////////////////////////////////////////
  1198. size_t GfaBlmBuildCmdDataPacket(const char *pszCmd, uint8_t tiCmd, const void *pCmdData, size_t nCbCmdData, void *pPacket, size_t nCbPacket, bool bAddLenAndCheck)
  1199. {
  1200. size_t nLen = strlen(pszCmd);
  1201. uint8_t *pbPacket = (uint8_t*)pPacket;
  1202. tiCmd = tiCmd; // not yet used
  1203. if(nCbPacket < (nLen + nCbCmdData + ((pCmdData && nCbCmdData && bAddLenAndCheck) ? 2 : 0)))
  1204. return 0;
  1205. memcpy(pbPacket, pszCmd, nLen);
  1206. pbPacket += nLen;
  1207. if(pCmdData && nCbCmdData)
  1208. {
  1209. if(bAddLenAndCheck)
  1210. {
  1211. *pbPacket++ = nCbCmdData + 2;
  1212. *pbPacket++ = GfaBlmDataCheckSum(pCmdData, nCbCmdData);
  1213. nLen += 2;
  1214. }
  1215. memcpy(pbPacket, pCmdData, nCbCmdData);
  1216. nLen += nCbCmdData;
  1217. }
  1218. return nLen;
  1219. }
  1220. const char* GfaBlmStrError(int nErrorCode)
  1221. {
  1222. switch(nErrorCode)
  1223. {
  1224. case -COMMAND_RET_UNKNOWN_CMD:
  1225. return "Unknown Bootloader command";
  1226. case -COMMAND_RET_INVALID_CMD:
  1227. return "Invalid Bootloader command";
  1228. case -COMMAND_RET_INVALID_ADR:
  1229. return "Invalid Flash address";
  1230. case -COMMAND_RET_FLASH_FAIL:
  1231. return "Bootloader failed to erase flash";
  1232. case -COMMAND_RET_CRC_FAIL:
  1233. return "Invalid Image CRC32";
  1234. default:
  1235. return GfaMininetMasterStrError(nErrorCode);
  1236. }
  1237. }