| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492 |
- #include <stdio.h>
- #include <string.h>
- #include <malloc.h>
- #include <ctype.h>
- #include <errno.h>
- #include <unistd.h>
- #include <gfaserial.h>
- #include <gfamininetmst.h>
- #include <byteswap.h>
- #include "bl_commands.h"
- #include "gfabootlmast.h"
- #include "dbghlp.h"
- ////////////////////////////////////////////////////////////////////////////////////
- #define _dword_offset(m) (offsetof(GFA_APP_IMG_HEADER, m) / sizeof(uint32_t) - 2)
- #ifdef _DEBUG
- #define _EXEC_CALLBACK(pfn, ...) if(pfn) (*pfn)(__FILE__, __LINE__, __VA_ARGS__)
- #else // _DEBUG
- #define _EXEC_CALLBACK(pfn, ...) if(pfn) (*pfn)(__VA_ARGS__)
- #endif // _DEBUG
- #define _BOOTLOADER_EXEC_WAIT_TIME 250
- #define _GFA_MAX_DUMP_DWORDS 16
- #define _MAX_SEND_DATA_BLOCK_SIZE 76
- #define _DEF_SEND_DATA_BLOCK_SIZE 64
- ////////////////////////////////////////////////////////////////////////////////////
- typedef struct _GFA_BLM
- {
- HGFAMINEMST hMst;
- PFN_BU_CMD_DOWNLOAD_STATUS pfnBuCmdDownloadStatus;
- PFN_BU_CMD_SEND_DATA_STATUS pfnBuCmdSendDataStatus;
- int nVerbosity;
- }GFA_BLM, *LPGFA_BLM;
- typedef const GFA_BLM *LPCGFA_BLM;
- ////////////////////////////////////////////////////////////////////////////////////
- #define GFA_APP_BOOTLOADER_START_ADDRESS ((uint32_t)0x00000000)
- #define GFA_APP_APPLICATION_START_ADDRESS ((uint32_t)0x00002000)
- #define GFA_APP_IMG_HEADER_PREFIX_0 ((uint32_t)0xFF01FF02)
- #define GFA_APP_IMG_HEADER_PREFIX_1 ((uint32_t)0xFF03FF04)
- ////////////////////////////////////////////////////////////////////////////////////
- typedef struct _GFA_APP_IMG_HEADER
- {
- const uint32_t nPrefix0;
- const uint32_t nPrefix1;
- const uint32_t nImgLength;
- const uint32_t nImgCRC32;
- const uint32_t nReserved[4];
- union
- {
- struct
- {
- const char * const pszImgMaterialNum;
- const char * const pszImgNameBuild;
- }app;
- struct
- {
- const char szImgMaterialNum[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH];
- const char szImgNameBuild[GFA_APP_MAX_IMG_NAME_BUILD_LENGTH];
- }bl;
- };
- }GFA_APP_IMG_HEADER, *LPGFA_APP_IMG_HEADER;
- typedef const GFA_APP_IMG_HEADER *LPCGFA_APP_IMG_HEADER;
- ////////////////////////////////////////////////////////////////////////////////////
- HGFABLM GfaBlmOpen(LPCGFA_BLM_CFG_PARAMS pblmcfg)
- {
- if(pblmcfg)
- {
- HGFAMINEMST hMst = GfaMininetMasterOpen(&pblmcfg->mmcp);
- if(hMst)
- {
- LPGFA_BLM pBlm = malloc(sizeof(GFA_BLM));
- memset(pBlm, 0, sizeof(GFA_BLM));
- pBlm->hMst = hMst;
- pBlm->pfnBuCmdDownloadStatus = pblmcfg->pfnBuCmdDownloadStatus;
- pBlm->pfnBuCmdSendDataStatus = pblmcfg->pfnBuCmdSendDataStatus;
- return (HGFABLM)pBlm;
- }
- return NULL;
- }
- errno = EINVAL;
- return NULL;
- }
- ////////////////////////////////////////////////////////////////////////////////////
- void GfaBlmClose(HGFABLM hBlm)
- {
- if(hBlm)
- {
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- GfaMininetMasterClose(pBlm->hMst);
- free(pBlm);
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmResetSlaveIndex(HGFABLM hBlm, uint8_t nNodeAddr)
- {
- if(hBlm)
- {
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- return GfaMininetMasterResetSlaveIndex(pBlm->hMst, nNodeAddr);
- }
- errno = EINVAL;
- return -1;
- }
- ////////////////////////////////////////////////////////////////////////////////////
- ssize_t GfaBlmBUCmdPollData(HGFABLM hBlm, uint8_t nNodeAddr, void *pData, size_t nCbData, uint32_t nTimeoutMS)
- {
- if(hBlm && pData && nCbData && !NODE_IS_MULTICAST(nNodeAddr))
- {
- size_t s, nReceived = 0;
- struct timeval tvRX;
- ssize_t nLen, nRet = -1;
- uint8_t cmd[32];
- uint8_t txb[32];
- uint8_t rxb[512];
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- uint8_t *pszData = (uint8_t*)pData;
- tvRX.tv_sec = nTimeoutMS / 1000;
- tvRX.tv_usec = (nTimeoutMS % 1000) * 1000;
- GfaMininetMasterSaveTimeouts(pBlm->hMst);
- GfaMininetMasterSetTimeouts(pBlm->hMst, &tvRX, NULL);
- while(nReceived < nCbData)
- {
- s = GfaBlmBuildCmdDataPacket("BU", 0, NULL, 0, cmd, sizeof(cmd), true);
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) <= 0)
- {
- nRet = -1;
- break;
- }
- if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) > 0)
- {
- uint8_t nIndex;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, pszData, nCbData - nReceived)) > 0)
- {
- pszData += nRet;
- nReceived += nRet;
- }
- }
- else if(nRet == MINET_SLAVE_RESPONSE_ACK)
- {
- if(nTimeoutMS > 0)
- {
- if(nTimeoutMS >= 100)
- {
- usleep(100000);
- nTimeoutMS -= 100;
- // TRACE("\nACK ...\n");
- }
- else
- {
- usleep(nTimeoutMS * 1000);
- nTimeoutMS = 0;
- // TRACE("\nACK ...\n");
- }
- }
- else
- {
- errno = ETIMEDOUT;
- nReceived = 0;
- break;
- }
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- nReceived = 0;
- break;
- }
- else
- {
- errno = EPROTO;
- nReceived = 0;
- break;
- }
- }
- else
- {
- nReceived = 0;
- break;
- }
- }
- GfaMininetMasterRestoreTimeouts(pBlm->hMst);
- return nReceived;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmBUCmdReset(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nTimeoutMS)
- {
- if(hBlm)
- {
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- uint8_t nIndex;
- size_t s;
- ssize_t nRet, nLen;
- uint8_t cmd = COMMAND_RESET;
- uint8_t cmddata[16];
- char txb[32], rxb[256], ack[2];
-
- if((nRet = GfaBlmBootloaderSetBaudrate(hBlm, nNodeAddr, 19200)) != 0)
- return -1;
- s = GfaBlmBuildCmdDataPacket("BU", 0, &cmd, 1, cmddata, sizeof(cmddata), true);
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmddata, s, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- return nRet;
-
- if(NODE_IS_MULTICAST(nNodeAddr))
- return 0;
- if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
- return nLen;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
- if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
- (nRet == MINET_SLAVE_RESPONSE_ACK))
- {
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
- return -1;
- }
- else
- {
- if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 200)) != 2)
- return -1;
- }
- if( (ack[0] == 0) &&
- (ack[1] == COMMAND_ACK))
- {
- do
- {
- if(nTimeoutMS > _BOOTLOADER_EXEC_WAIT_TIME)
- {
- usleep(_BOOTLOADER_EXEC_WAIT_TIME * 1000);
- nTimeoutMS -= _BOOTLOADER_EXEC_WAIT_TIME;
- }
- else
- {
- usleep(nTimeoutMS * 1000);
- nTimeoutMS = 0;
- }
- if((nRet = GfaMininetMasterResetSlaveIndex(pBlm->hMst, nNodeAddr)) == 0)
- break;
- GfaMininetMasterPurgeDeviceRXBuffer(pBlm->hMst);
- }
- while(nTimeoutMS > 0);
- return nRet;
- }
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- return -1;
- }
- return -1;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmBUCmdPing(HGFABLM hBlm, uint8_t nNodeAddr)
- {
- if(hBlm && !NODE_IS_MULTICAST(nNodeAddr))
- {
- uint8_t nIndex;
- ssize_t nRet, nLen;
- uint8_t nCmd = COMMAND_PING;
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- char txb[32], rxb[32], cmd[8], ack[2];
- size_t s = GfaBlmBuildCmdDataPacket("BU", 0, &nCmd, 1, cmd, sizeof(cmd), true);
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) < nLen)
- return nRet;
- if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
- return nLen;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
- if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
- (nRet == MINET_SLAVE_RESPONSE_ACK))
- {
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
- return -1;
- }
- else
- {
- if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 200)) != 2)
- return -1;
- }
- if(ack[0] == 0)
- {
- return (ack[1] == COMMAND_ACK);
- }
- else
- {
- errno = EPROTO;
- return -1;
- }
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- return -1;
- }
- return -1;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmBUCmdGetStatus(HGFABLM hBlm, uint8_t nNodeAddr, uint8_t *pbStatus)
- {
- if(hBlm && pbStatus && !NODE_IS_MULTICAST(nNodeAddr))
- {
- uint8_t nIndex;
- ssize_t nRet, nLen;
- uint8_t nCmd = COMMAND_GET_STATUS;
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- char txb[32], rxb[32], cmd[8], ack[3], stat[3];
- size_t s = GfaBlmBuildCmdDataPacket("BU", 0, &nCmd, 1, cmd, sizeof(cmd), true);
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) < nLen)
- return nRet;
- if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
- return nLen;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
- if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
- (nRet == MINET_SLAVE_RESPONSE_ACK))
- {
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
- return -1;
- }
- else
- {
- if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 200)) != 2)
- return -1;
- }
- if(ack[0] == 0)
- {
- if(ack[1] == COMMAND_ACK)
- {
- if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, stat, 3, 200)) != 3)
- return -1;
- if((stat[0] == 3) && (stat[1] == stat[2]))
- {
- if(pbStatus)
- *pbStatus = stat[2];
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BU\xCC", 3, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- return nRet;
- if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
- return nRet;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
- return 0;
- }
- else
- {
- errno = EPROTO;
- return -1;
- }
- }
- else
- {
- errno = EPROTO;
- return -1;
- }
- }
- else
- {
- errno = EPROTO;
- return -1;
- }
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- return -1;
- }
- return -1;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmBUCmdDownload(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nFlashStartAddr, uint32_t nCbData, uint32_t nTimeoutMS)
- {
- if(hBlm && nCbData && !NODE_IS_MULTICAST(nNodeAddr))
- {
- size_t s;
- ssize_t nRet, nLen;
- uint8_t nIndex, nStatus;
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- uint32_t nAddr = bswap_32(nFlashStartAddr), nCount = bswap_32(nCbData);
- uint8_t txb[32], rxb[32], cmd[16], data[9], ack[2];
- data[0] = COMMAND_DOWNLOAD;
- struct timeval tv;
- memcpy(&data[1], &nAddr, sizeof(nAddr));
- memcpy(&data[5], &nCount, sizeof(nCount));
- tv.tv_sec = nTimeoutMS / 1000;
- tv.tv_usec = (nTimeoutMS % 1000) * 1000;
- s = GfaBlmBuildCmdDataPacket("BU", 0, data, sizeof(data), cmd, sizeof(cmd), true);
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
- GfaMininetMasterSaveTimeouts(pBlm->hMst);
- GfaMininetMasterSetTimeouts(pBlm->hMst, &tv, NULL);
-
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 1, 0);
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- {
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
- GfaMininetMasterRestoreTimeouts(pBlm->hMst);
- return -1;
- }
-
- if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
- {
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
- GfaMininetMasterRestoreTimeouts(pBlm->hMst);
- return -1;
- }
-
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 2, 0);
- GfaMininetMasterRestoreTimeouts(pBlm->hMst);
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
- {
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
- return -1;
- }
- if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
- {
- if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
- {
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
- return -1;
- }
- if(nStatus == COMMAND_RET_SUCCESS)
- {
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 3, 0);
- return 0;
- }
- }
- errno = EPROTO;
- return -1;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_ACK)
- {
- if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, nTimeoutMS)) != 2)
- {
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
- return -1;
- }
- if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
- {
- if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
- {
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
- return -1;
- }
- if(nStatus == COMMAND_RET_SUCCESS)
- {
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 3, 0);
- return 0;
- }
- }
- errno = EPROTO;
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
- return -1;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
- return -1;
- }
- else
- {
- errno = EPROTO;
- _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
- return -1;
- }
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmBUCmdSendDataBlock(HGFABLM hBlm, uint8_t nNodeAddr, const void *pDataBlock, size_t nCbDataBlock)
- {
- if(hBlm && pDataBlock && nCbDataBlock && (nCbDataBlock <= 250) && !NODE_IS_MULTICAST(nNodeAddr))
- {
- ssize_t nRet;
- struct timeval tv;
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- tv.tv_sec = 0;
- tv.tv_usec = 500000;
- GfaMininetMasterSaveTimeouts(pBlm->hMst);
- GfaMininetMasterSetTimeouts(pBlm->hMst, &tv, NULL);
-
- do
- {
- size_t s;
- ssize_t nLen;
- uint8_t nIndex, nStatus;
- uint8_t txb[512], rxb[32], cmd[256], data[256], ack[2];
- data[0] = COMMAND_SEND_DATA;
- memcpy(&data[1], pDataBlock, nCbDataBlock);
- s = GfaBlmBuildCmdDataPacket("BU", 0, data, nCbDataBlock + 1, cmd, sizeof(cmd), true);
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- {
- nRet = -1;
- break;
- }
- if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
- {
- nRet = -1;
- break;
- }
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
- {
- nRet = -1;
- break;
- }
- if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
- {
- if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
- {
- nRet = -1;
- break;
- }
- if(nStatus != COMMAND_RET_SUCCESS)
- {
- errno = -nStatus;
- nRet = -1;
- break;
- }
- nRet = 0;
- break;
- }
- errno = EPROTO;
- nRet = -1;
- break;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_ACK)
- {
- if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 5000)) != 2)
- {
- nRet = -1;
- break;
- }
- if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
- {
- if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
- {
- nRet = -1;
- break;
- }
- if(nStatus != COMMAND_RET_SUCCESS)
- {
- errno = -nStatus;
- nRet = -1;
- break;
- }
- nRet = 0;
- break;
- }
- errno = EPROTO;
- nRet = -1;
- break;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- nRet = -1;
- break;
- }
- }
- while(false);
-
- GfaMininetMasterRestoreTimeouts(pBlm->hMst);
- return nRet;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmBUCmdSendData(HGFABLM hBlm, uint8_t nNodeAddr, const void *pData, size_t nCbData, size_t nCbBlock)
- {
- if(hBlm && pData && nCbData && !NODE_IS_MULTICAST(nNodeAddr))
- {
- int nRet;
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- const uint8_t *pbData = (const uint8_t*)pData;
- uint32_t nSent = 0;
- if(!nCbBlock || nCbBlock < 4 || nCbBlock > _MAX_SEND_DATA_BLOCK_SIZE)
- nCbBlock = _DEF_SEND_DATA_BLOCK_SIZE;
- else
- nCbBlock &= ~0x03;
- _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 1, 0);
-
- while(nCbData >= nCbBlock)
- {
- if((nRet = GfaBlmBUCmdSendDataBlock(hBlm, nNodeAddr, pbData, nCbBlock)) != 0)
- {
- _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 0, errno);
- return -1;
- }
- nCbData -= nCbBlock;
- pbData += nCbBlock;
- nSent += nCbBlock;
- _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 2, 0);
- }
-
- if(nCbData)
- {
- if((nRet = GfaBlmBUCmdSendDataBlock(hBlm, nNodeAddr, pbData, nCbData)) != 0)
- {
- _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 0, errno);
- return -1;
- }
- nSent += nCbData;
- nCbData = 0;
- _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 2, 0);
- }
- _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 3, 0);
- return 0;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmBUCmdSendDataFile(HGFABLM hBlm, uint8_t nNodeAddr, const char *pszFilename, uint32_t nFlashStartAddr, size_t nCbBlock, uint32_t nTimeoutMS)
- {
- if(hBlm && pszFilename && !NODE_IS_MULTICAST(nNodeAddr))
- {
- int nRet = -1;
- ssize_t nFileLen;
- FILE *pf = NULL;
- uint8_t *pBuf = NULL;
-
- do
- {
- if(!(pf = fopen(pszFilename, "rb")))
- break;
- if(fseek(pf, 0, SEEK_END))
- break;
- if((nFileLen = ftell(pf)) < 0)
- break;
- if(fseek(pf, 0, SEEK_SET))
- break;
- if( (nFileLen > 0) &&
- (pBuf = (uint8_t*)malloc(nFileLen)) &&
- (fread(pBuf, 1, nFileLen, pf) == (size_t)nFileLen))
- {
- if((nRet = GfaBlmBUCmdDownload(hBlm, nNodeAddr, nFlashStartAddr, nFileLen, nTimeoutMS)) == 0)
- nRet = GfaBlmBUCmdSendData(hBlm, nNodeAddr, pBuf, nFileLen, nCbBlock);
- }
- }
- while(false);
-
- if(pBuf)
- free(pBuf);
- if(pf)
- fclose(pf);
- return nRet;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- GFA_BLM_EXEC_CONTEXT GfaBlmGetExecutionContext(HGFABLM hBlm, uint8_t nNodeAddr)
- {
- if(hBlm && !NODE_IS_MULTICAST(nNodeAddr))
- {
- uint8_t nIndex;
- ssize_t nRet, nLen;
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- char txb[32], rxb[32];
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BU", 2, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- return GfaBlmCtx_Err;
- if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
- return GfaBlmCtx_Err;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- return GfaBlmCtx_Err;
- else if(nRet == MINET_SLAVE_RESPONSE_ACK)
- return GfaBlmCtx_Boot;
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- return GfaBlmCtx_App;
- return GfaBlmCtx_Err;
- }
- errno = EINVAL;
- return GfaBlmCtx_Err;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmBootloaderExecute(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t *pnImgCRC32, uint32_t nTimeoutMS)
- {
- if(hBlm && !NODE_IS_MULTICAST(nNodeAddr))
- {
- uint8_t nIndex;
- uint32_t nImgCRC32;
- ssize_t nRet, nLen;
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- char txb[32], rxb[32];
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BE", 2, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- return -1;
- if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
- return nLen;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, &nImgCRC32, sizeof(nImgCRC32))) == 4)
- {
- if(pnImgCRC32)
- *pnImgCRC32 = bswap_32(nImgCRC32);
- do
- {
- if(nTimeoutMS > _BOOTLOADER_EXEC_WAIT_TIME)
- {
- usleep(_BOOTLOADER_EXEC_WAIT_TIME * 1000);
- nTimeoutMS -= _BOOTLOADER_EXEC_WAIT_TIME;
- }
- else
- {
- usleep(nTimeoutMS * 1000);
- nTimeoutMS = 0;
- }
- if((nRet = GfaMininetMasterResetSlaveIndex(pBlm->hMst, nNodeAddr)) == 0)
- break;
- GfaMininetMasterPurgeDeviceRXBuffer(pBlm->hMst);
- }
- while(nTimeoutMS > 0);
- return nRet;
- }
- }
- else if(nRet == MINET_SLAVE_RESPONSE_ACK)
- {
- return 0;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- return -1;
- }
- return -1;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmBootloaderSetBaudrate(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nBaudrate)
- {
- if(hBlm)
- {
- uint8_t nIndex;
- size_t s;
- ssize_t nRet, nLen;
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
-
- if(GfaMininetMasterIsValidBaudrate(pBlm->hMst, nBaudrate))
- {
- char txb[32], rxb[32], cmd[8];
- uint32_t nBr = bswap_32(nBaudrate);
- s = GfaBlmBuildCmdDataPacket("BB", 0, &nBr, sizeof(nBr), cmd, sizeof(cmd), false);
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- return nRet;
-
- if(NODE_IS_MULTICAST(nNodeAddr))
- return 0;
- if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
- return nLen;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
- if(nRet == MINET_SLAVE_RESPONSE_ACK)
- {
- return GfaMininetMasterSetBaudrate(pBlm->hMst, nBaudrate);
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- return -1;
- }
- return -1;
- }
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmBootloaderDump(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nAddress, uint32_t nCntDwords, void *pBuffer, size_t nCbBuffer)
- {
- if(hBlm && pBuffer && nCntDwords && !NODE_IS_MULTICAST(nNodeAddr))
- {
- size_t s;
- uint8_t nIndex;
- ssize_t nRet, nLen;
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- uint32_t i, dmp[_GFA_MAX_DUMP_DWORDS];
- char txb[32], rxb[128], cmd[10];
- if(nCntDwords > _GFA_MAX_DUMP_DWORDS)
- nCntDwords = _GFA_MAX_DUMP_DWORDS;
- if((nCntDwords * sizeof(uint32_t)) > nCbBuffer)
- {
- errno = ENOMEM;
- return -1;
- }
- struct _MEM
- {
- uint32_t nAddr;
- uint32_t nCount;
- }mem = {bswap_32(nAddress), bswap_32(nCntDwords)};
- s = GfaBlmBuildCmdDataPacket("BD", 0, &mem, sizeof(mem), cmd, sizeof(cmd), false);
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- return nRet;
- if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
- return nLen;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, dmp, sizeof(uint32_t) * nCntDwords)) != (ssize_t)(sizeof(uint32_t) * nCntDwords))
- return -1;
- for(i = 0; i < nCntDwords; ++i)
- {
- dmp[i] = bswap_32(dmp[i]);
- }
- memcpy(pBuffer, dmp, sizeof(uint32_t) * nCntDwords);
- return 0;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_ACK)
- {
- if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, dmp, sizeof(uint32_t) * nCntDwords, 200)) != (ssize_t)(sizeof(uint32_t) * nCntDwords))
- return -1;
- for(i = 0; i < nCntDwords; ++i)
- {
- dmp[i] = bswap_32(dmp[i]);
- }
- memcpy(pBuffer, dmp, sizeof(uint32_t) * nCntDwords);
- return 0;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- return -1;
- }
- return -1;
- }
- errno = EINVAL;
- return -1;
- }
- int GfaBlmGetImgInfo(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nDumpAddr, bool bCtxIsApp, LPGFA_IMG_INFO pii)
- {
- if(hBlm && pii && !NODE_IS_MULTICAST(nNodeAddr))
- {
- ssize_t nRet = 0;
- uint32_t i, j, nPfx0Addr = 0;
- int32_t nPfx0Index = -1, nPfx1Index = -1;
- uint32_t aDump[_GFA_MAX_DUMP_DWORDS];
- GFA_APP_IMG_HEADER aih;
- memset(&aih, 0, sizeof(aih));
- memset(pii, 0, sizeof(GFA_IMG_INFO));
- for(i = 0; i < 257; i += _GFA_MAX_DUMP_DWORDS)
- {
- if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, nDumpAddr, _GFA_MAX_DUMP_DWORDS, aDump, sizeof(aDump))) == 0)
- {
- for(j = 0; j < _GFA_MAX_DUMP_DWORDS; ++j, nDumpAddr += sizeof(uint32_t))
- {
- switch(aDump[j])
- {
- case GFA_APP_IMG_HEADER_PREFIX_0:
- nPfx0Addr = nDumpAddr;
- nPfx0Index = i + j;
- continue;
- case GFA_APP_IMG_HEADER_PREFIX_1:
- nPfx1Index = i + j;
- break;
- default:
- break;
- }
- if((nPfx0Index >= 0) && (nPfx1Index == (nPfx0Index + 1)))
- {
- uint32_t nDmpStart = nPfx0Addr + 2 * sizeof(uint32_t), *pDwDst = ((uint32_t*)&aih) + 2;
- uint32_t nCntDwAvail = 15 - j;
- if(bCtxIsApp)
- {
- uint32_t nDwOffsImgMaterialNum = _dword_offset(app.pszImgMaterialNum);
- uint32_t nDwOffsImgNameBuild = _dword_offset(app.pszImgNameBuild);
- uint32_t nDwOffsImgCRC32 = _dword_offset(nImgCRC32);
- size_t nSizeDst = (nDwOffsImgNameBuild + 1) * sizeof(uint32_t);
- uint32_t nCntDwToDmp, nCntDwToCpy;
- if(nCntDwAvail > nDwOffsImgNameBuild)
- {
- // have nImgLength, nImgCRC32, pszImgMaterialNum, pszImgNameBuild
- // need nothing
- nCntDwToCpy = nDwOffsImgNameBuild + 1;
- nCntDwToDmp = 0;
- memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
- }
- else if(nCntDwAvail == nDwOffsImgNameBuild)
- {
- // have nImgLength, nImgCRC32, pszImgMaterialNum
- // need pszImgNameBuild
- nCntDwToCpy = nDwOffsImgNameBuild;
- nCntDwToDmp = 1;
- nDmpStart += nCntDwToCpy * sizeof(uint32_t);
- memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
- pDwDst += nCntDwToCpy;
- nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
- }
- else if(nCntDwAvail > nDwOffsImgCRC32)
- {
- // have nImgLength, nImgCRC32
- // need pszImgMaterialNum, pszImgNameBuild
- nCntDwToCpy = 2;
- nCntDwToDmp = 2;
- nDmpStart += nDwOffsImgMaterialNum * sizeof(uint32_t);
- memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
- pDwDst += nDwOffsImgMaterialNum;
- nSizeDst -= nDwOffsImgMaterialNum * sizeof(uint32_t);
- }
- else if(nCntDwAvail == nDwOffsImgCRC32)
- {
- // have nImgLength
- // need nImgCRC32, pszImgMaterialNum, pszImgNameBuild
- nCntDwToCpy = nDwOffsImgCRC32;
- nCntDwToDmp = 7; // 1 + 4 + 2
- nDmpStart += sizeof(uint32_t);
- memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
- pDwDst += nCntDwToCpy;
- nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
- }
- else
- {
- // have nothing
- // need nImgLength, nImgCRC32, pszImgMaterialNum, pszImgNameBuild
- nCntDwToCpy = 0;
- nCntDwToDmp = nDwOffsImgNameBuild + 1; // 2 + 4 + 2
- }
- if(nCntDwToDmp)
- {
- if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, nDmpStart, nCntDwToDmp, pDwDst, nSizeDst)) != 0)
- return -1;
- }
- pii->nImgLength = aih.nImgLength;
- pii->nImgCRC32 = aih.nImgCRC32;
- 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)
- return -1;
- 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)
- return -1;
- pii->szImgMaterialNum[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH - 1] = '\0';
- pii->szImgNameBuild[GFA_APP_MAX_IMG_NAME_BUILD_LENGTH - 1] = '\0';
- return 0;
- }
- else
- {
- uint32_t nDwOffsImgMaterialNum = _dword_offset(bl.szImgMaterialNum);
- uint32_t nDwOffsImgNameBuild = _dword_offset(bl.szImgNameBuild);
- uint32_t nDwOffsImgCRC32 = _dword_offset(nImgCRC32);
- size_t nSizeDst = nDwOffsImgNameBuild * sizeof(uint32_t) + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH;
- uint32_t nCntDwToDmp, nCntDwToCpy;
- if(nCntDwAvail >= (nDwOffsImgNameBuild + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH / sizeof(uint32_t)))
- {
- // have nImgLength, nImgCRC32, szImgMaterialNum, szImgNameBuild
- // need nothing
- nCntDwToCpy = nDwOffsImgNameBuild + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH / sizeof(uint32_t);
- nCntDwToDmp = 0;
- memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
- }
- else if(nCntDwAvail > nDwOffsImgMaterialNum)
- {
- // have nImgLength, nImgCRC32, szImgMaterialNum
- // need szImgNameBuild
- nCntDwToCpy = nCntDwAvail;
- nCntDwToDmp = nSizeDst / sizeof(uint32_t) - nCntDwToCpy; // (1...3) + 6
- nDmpStart += nCntDwToCpy * sizeof(uint32_t);
- memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
- pDwDst += nCntDwToCpy;
- nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
- }
- else if(nCntDwAvail > nDwOffsImgCRC32)
- {
- // have nImgLength, nImgCRC32
- // need szImgMaterialNum, szImgNameBuild
- nCntDwToCpy = 2;
- nCntDwToDmp = (GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH) / sizeof(uint32_t); // 4 + 6
- nDmpStart += nDwOffsImgMaterialNum * sizeof(uint32_t);
- memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
- pDwDst += nDwOffsImgMaterialNum;
- nSizeDst -= nDwOffsImgMaterialNum * sizeof(uint32_t);
- }
- else if(nCntDwAvail == nDwOffsImgCRC32)
- {
- // have nImgLength
- // need nImgCRC32, szImgMaterialNum, szImgNameBuild
- nCntDwToCpy = nDwOffsImgCRC32;
- nCntDwToDmp = nSizeDst / sizeof(uint32_t) - nCntDwToCpy; // 1 + 4 + 4 + 6
- nDmpStart += sizeof(uint32_t);
- memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
- pDwDst += nCntDwToCpy;
- nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
- }
- else
- {
- // have nothing
- // need nImgLength, nImgCRC32, pszImgMaterialNum, pszImgNameBuild
- nCntDwToCpy = 0;
- nCntDwToDmp = nSizeDst / sizeof(uint32_t); // 2 + 4 + 4 + 6
- }
- if(nCntDwToDmp)
- {
- if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, nDmpStart, nCntDwToDmp, pDwDst, nSizeDst)) != 0)
- return -1;
- }
- pii->nImgLength = aih.nImgLength;
- pii->nImgCRC32 = aih.nImgCRC32;
- memcpy(pii->szImgMaterialNum, aih.bl.szImgMaterialNum, GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH);
- memcpy(pii->szImgNameBuild, aih.bl.szImgNameBuild, GFA_APP_MAX_IMG_NAME_BUILD_LENGTH);
- pii->szImgMaterialNum[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH - 1] = '\0';
- pii->szImgNameBuild[GFA_APP_MAX_IMG_NAME_BUILD_LENGTH - 1] = '\0';
- return 0;
- }
- }
- }
- }
- else
- {
- break;
- }
- }
- return -1;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmGetInfoBD(HGFABLM hBlm, uint8_t nNodeAddr, LPGFA_BL_APP_IMG_INFO paii)
- {
- if(hBlm && paii && !NODE_IS_MULTICAST(nNodeAddr))
- {
- int nRet1, nRet2;
- if((nRet1 = GfaBlmGetImgInfo(hBlm, nNodeAddr, GFA_APP_BOOTLOADER_START_ADDRESS, false, &paii->bl)) < 0)
- {
- memset(&paii->bl, 0, sizeof(paii->bl));
- paii->bl.nImgLength = paii->bl.nImgCRC32 = 0xFFFFFFFF;
- }
- if((nRet2 = GfaBlmGetImgInfo(hBlm, nNodeAddr, GFA_APP_APPLICATION_START_ADDRESS, true, &paii->app)) < 0)
- {
- memset(&paii->app, 0, sizeof(paii->app));
- paii->app.nImgLength = paii->app.nImgCRC32 = 0xFFFFFFFF;
- }
- return nRet1 + nRet2;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmGetInfoBI(HGFABLM hBlm, uint8_t nNodeAddr, LPGFA_BL_APP_IMG_INFO paii)
- {
- if(hBlm && paii && !NODE_IS_MULTICAST(nNodeAddr))
- {
- uint8_t nIndex;
- ssize_t nRet, nLen;
- char txb[32], rxb[256];
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BI", 2, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- return nRet;
- if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
- return nLen;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, paii, sizeof(GFA_BL_APP_IMG_INFO))) == sizeof(GFA_BL_APP_IMG_INFO))
- {
- paii->bl.nImgLength = bswap_32(paii->bl.nImgLength);
- paii->bl.nImgCRC32 = bswap_32(paii->bl.nImgCRC32);
- paii->app.nImgLength = bswap_32(paii->app.nImgLength);
- paii->app.nImgCRC32 = bswap_32(paii->app.nImgCRC32);
- return 0;
- }
- errno = EPROTO;
- return -1;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_ACK)
- {
- errno = EPROTO;
- return -1;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- return -1;
- }
- return -1;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmReadMaterialAndSerialID(HGFABLM hBlm, uint8_t nNodeAddr, char *pszMaterial, size_t nCbMaterial, char *pszSerial, size_t nCbSerial)
- {
- if(hBlm && pszMaterial && (nCbMaterial >= 16) && pszSerial && (nCbSerial >= 16) && !NODE_IS_MULTICAST(nNodeAddr))
- {
- uint8_t nIndex;
- ssize_t nRet, nLen;
- char txb[32], rxb[64], data[32];
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BR", 2, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- return nRet;
- if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
- return nLen;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, data, sizeof(data))) != 32)
- return -1;
- memcpy(pszMaterial, data, 16);
- pszMaterial[15] = '\0';
- memcpy(pszSerial, &data[16], 16);
- pszSerial[15] = '\0';
- return 0;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_ACK)
- {
- if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, data, sizeof(data), 200)) != (ssize_t)sizeof(data))
- return -1;
- memcpy(pszMaterial, data, 16);
- pszMaterial[15] = '\0';
- memcpy(pszSerial, &data[16], 16);
- pszSerial[15] = '\0';
- return 0;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- return -1;
- }
- return -1;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmWriteMaterialAndSerialID(HGFABLM hBlm, uint8_t nNodeAddr, const char *pszMaterial, const char *pszSerial)
- {
- if(hBlm && pszMaterial && pszSerial && !NODE_IS_MULTICAST(nNodeAddr))
- {
- uint8_t nIndex;
- size_t s;
- ssize_t nRet, nLen;
- size_t nLenMaterial, nLenSerial;
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- struct _TS
- {
- char szMaterial[16];
- char szSerial[16];
- }ts;
- char txb[64], rxb[32], cmd[64];
- nLenMaterial = strlen(pszMaterial);
- nLenSerial = strlen(pszSerial);
- if((nLenMaterial > 15) || (nLenSerial > 15))
- return -1;
- memcpy(ts.szMaterial, pszMaterial, nLenMaterial);
- if(nLenMaterial < 15)
- memset(&ts.szMaterial[nLenMaterial], ' ', 15 - nLenMaterial);
- ts.szMaterial[15] = '\0';
- memcpy(ts.szSerial, pszSerial, nLenSerial);
- if(nLenSerial < 15)
- memset(&ts.szSerial[nLenSerial], ' ', 15 - nLenSerial);
- ts.szSerial[15] = '\0';
- s = GfaBlmBuildCmdDataPacket("BW", 0, &ts, sizeof(ts), cmd, sizeof(cmd), false);
- nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
- if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
- return nRet;
- if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
- return nRet;
- nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
- if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- return 0;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_ACK)
- {
- return 0;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- errno = -(int)nIndex;
- return -1;
- }
- return -1;
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- HGFAMINEMST GfaBlmGetMininetMasterHandle(HGFABLM hBlm)
- {
- if(hBlm)
- {
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- return pBlm->hMst;
- }
- errno = EINVAL;
- return NULL;
- }
- /////////////////////////////////////////////////////////////////////////////
- int GfaBlmSetVerbosity(HGFABLM hBlm, int nVerbosity)
- {
- if(hBlm)
- {
- LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
- if(nVerbosity < 0)
- nVerbosity = 0;
- else if(nVerbosity > 4)
- nVerbosity = 4;
- pBlm->nVerbosity = nVerbosity;
- return GfaMininetMasterSetVerbosity(pBlm->hMst, pBlm->nVerbosity);
- }
- errno = EINVAL;
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- uint8_t GfaBlmDataCheckSum(const void *pData, size_t nCbData)
- {
- uint8_t chk = 0;
- const uint8_t *pbData = (const uint8_t*)pData;
- while(nCbData--) {
- chk += *pbData++;
- }
- return chk;
- }
- /////////////////////////////////////////////////////////////////////////////
- size_t GfaBlmBuildCmdDataPacket(const char *pszCmd, uint8_t tiCmd, const void *pCmdData, size_t nCbCmdData, void *pPacket, size_t nCbPacket, bool bAddLenAndCheck)
- {
- size_t nLen = strlen(pszCmd);
- uint8_t *pbPacket = (uint8_t*)pPacket;
- tiCmd = tiCmd; // not yet used
- if(nCbPacket < (nLen + nCbCmdData + ((pCmdData && nCbCmdData && bAddLenAndCheck) ? 2 : 0)))
- return 0;
- memcpy(pbPacket, pszCmd, nLen);
- pbPacket += nLen;
- if(pCmdData && nCbCmdData)
- {
- if(bAddLenAndCheck)
- {
- *pbPacket++ = nCbCmdData + 2;
- *pbPacket++ = GfaBlmDataCheckSum(pCmdData, nCbCmdData);
- nLen += 2;
- }
- memcpy(pbPacket, pCmdData, nCbCmdData);
- nLen += nCbCmdData;
- }
- return nLen;
- }
- const char* GfaBlmStrError(int nErrorCode)
- {
- switch(nErrorCode)
- {
- case -COMMAND_RET_UNKNOWN_CMD:
- return "Unknown Bootloader command";
- case -COMMAND_RET_INVALID_CMD:
- return "Invalid Bootloader command";
- case -COMMAND_RET_INVALID_ADR:
- return "Invalid Flash address";
- case -COMMAND_RET_FLASH_FAIL:
- return "Bootloader failed to erase flash";
- case -COMMAND_RET_CRC_FAIL:
- return "Invalid Image CRC32";
- default:
- return GfaMininetMasterStrError(nErrorCode);
- }
- }
|