SWUpdate library to be used with RPC.
Fork of SWUpdate by
SWUpdate.cpp
- Committer:
- WiredHome
- Date:
- 2014-06-15
- Revision:
- 8:8e840a036116
- Parent:
- 7:a7efbae7e02e
- Child:
- 9:73067ef14c30
File content as of revision 8:8e840a036116:
// Software Update via Ethernet from forum - // http://mbed.org/forum/mbed/topic/1183/ // #include "mbed.h" #include "SWUpdate.h" #include "HTTPClient.h" #include "HTTPText.h" #include "HTTPFile.h" #include <stdio.h> extern "C" void mbed_reset(); //#define DEBUG "SWup" #include <cstdio> #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) #define DBG(x, ...) std::printf("[DBG %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); #else #define DBG(x, ...) #define WARN(x, ...) #define ERR(x, ...) #define INFO(x, ...) #endif static bool PassesIntegrityCheck(const char * fname, int cksum, int fsize) { int res = false; // assume things go wrong... int newCksum = 0; int newFSize = 0; FILE *fh = fopen(fname, "rb"); INFO("IntegrityCheck(%s,%d,%d)", fname, cksum, fsize); if (fh) { char buf; while (fread(&buf, 1, 1, fh)) { newCksum = (newCksum + buf) & 0xFFFF; newFSize++; } fclose(fh); INFO(" Check(...,%d,%d)", newCksum, newFSize); if (newCksum == cksum && newFSize == fsize) res = true; } else { WARN("failed to open %s.", fname); } return res; } bool SoftwareUpdate(const char *url, const char * name, Reboot_T reboot) { HTTPClient http; //http.setTimeout( 15000 ); char fqurl[150]; // fully qualified url char verfn[32]; // local version file char fwfn[32]; bool result = false; // many things can go wrong, assume failure char buf[50]; INFO("SoftwareUpdate(%s,%s)", url, name); snprintf(verfn, 32, "/local/%s.ver", name); /* Read installed version string */ int inst_ver = -1; FILE *fv = fopen(verfn, "r"); if (fv) { fscanf(fv, "%d", &inst_ver); fclose(fv); } INFO(" Installed version: %d", inst_ver); /* Download latest version string */ HTTPText server_ver("test message"); snprintf(fqurl, 150, "%s/%s.txt", url, name); HTTPResult r = http.get(fqurl, buf, sizeof(buf)); if (r == HTTP_OK) { int latest_ver = -1; int cksum = 0; int fsize = 0; int parseCount; parseCount = sscanf(buf, "%d,%d,%d", &latest_ver, &cksum, &fsize); if (parseCount == 3) { INFO(" web version: %d", latest_ver); INFO(" checksum: %d", cksum); INFO(" file size: %d", fsize); if (inst_ver != latest_ver) { INFO(" Downloading firmware ver %d ...", latest_ver); sprintf(fwfn, "/local/%s%d.BIN", name, latest_ver); snprintf(fqurl, 150, "%s/%s.bin", url, name); HTTPFile latest(fwfn); r = http.get(fqurl, &latest); if (r == HTTP_OK) { // Check the integrity of the freshly downloaded file, // before swapping out the old version. // ... to appear here ... if (PassesIntegrityCheck(fwfn, cksum, fsize)) { sprintf(fwfn, "/local/%s%d.BIN", name, inst_ver); INFO(" Firmware downloaded, removing old version (%s).", fwfn); if (remove(fwfn)) { ERR(" *** Failed to remove old version. ***"); } INFO("Updating stored version number."); fv = fopen(verfn, "w"); if (fv) { int fr = fputs(buf, fv); if (fr < 0) { ERR("Failed (%d) to update stored version number.", fr); fclose( fv ); } else { fclose( fv ); if (reboot == AUTO_REBOOT) { WARN("Resetting...\n"); wait_ms(200); mbed_reset(); } result = true; } } else { WARN("Failed to update local version info in %s.", verfn); } } else { WARN("New file {%s} did not pass integrity check.", fwfn); } } else { WARN("Failed to download lastest firmware."); } } else { INFO("Online version is same as installed version.", parseCount); } } } else { WARN("Failed to download online firmware version number."); } return result; }