gfabootlmast.c 41 KB

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