Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SWUpdate by
SWUpdate.cpp@3:c69fff55fc60, 2014-06-14 (annotated)
- Committer:
- WiredHome
- Date:
- Sat Jun 14 18:18:28 2014 +0000
- Revision:
- 3:c69fff55fc60
- Parent:
- 1:208de08b1a19
- Child:
- 7:a7efbae7e02e
Updated documentation to support integrity checking.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| WiredHome | 0:e221363f7942 | 1 | |
| WiredHome | 0:e221363f7942 | 2 | // Software Update via Ethernet from forum - |
| WiredHome | 0:e221363f7942 | 3 | // http://mbed.org/forum/mbed/topic/1183/ |
| WiredHome | 1:208de08b1a19 | 4 | // |
| WiredHome | 0:e221363f7942 | 5 | #include "mbed.h" |
| WiredHome | 0:e221363f7942 | 6 | #include "SWUpdate.h" |
| WiredHome | 0:e221363f7942 | 7 | #include "HTTPClient.h" |
| WiredHome | 0:e221363f7942 | 8 | #include "HTTPText.h" |
| WiredHome | 0:e221363f7942 | 9 | #include "HTTPFile.h" |
| WiredHome | 0:e221363f7942 | 10 | #include <stdio.h> |
| WiredHome | 0:e221363f7942 | 11 | |
| WiredHome | 0:e221363f7942 | 12 | extern "C" void mbed_reset(); |
| WiredHome | 0:e221363f7942 | 13 | |
| WiredHome | 0:e221363f7942 | 14 | #define DEBUG "SWup" |
| WiredHome | 0:e221363f7942 | 15 | #include <cstdio> |
| WiredHome | 0:e221363f7942 | 16 | #if (defined(DEBUG) && !defined(TARGET_LPC11U24)) |
| WiredHome | 0:e221363f7942 | 17 | #define DBG(x, ...) std::printf("[DBG %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
| WiredHome | 0:e221363f7942 | 18 | #define WARN(x, ...) std::printf("[WRN %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
| WiredHome | 0:e221363f7942 | 19 | #define ERR(x, ...) std::printf("[ERR %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
| WiredHome | 0:e221363f7942 | 20 | #define INFO(x, ...) std::printf("[INF %s %3d] "x"\r\n", DEBUG, __LINE__, ##__VA_ARGS__); |
| WiredHome | 0:e221363f7942 | 21 | #else |
| WiredHome | 0:e221363f7942 | 22 | #define DBG(x, ...) |
| WiredHome | 0:e221363f7942 | 23 | #define WARN(x, ...) |
| WiredHome | 0:e221363f7942 | 24 | #define ERR(x, ...) |
| WiredHome | 0:e221363f7942 | 25 | #define INFO(x, ...) |
| WiredHome | 0:e221363f7942 | 26 | #endif |
| WiredHome | 0:e221363f7942 | 27 | |
| WiredHome | 3:c69fff55fc60 | 28 | static bool PassesIntegrityCheck(const char * fname, int cksum, int fsize) { |
| WiredHome | 3:c69fff55fc60 | 29 | int res = false; // assume things go wrong... |
| WiredHome | 3:c69fff55fc60 | 30 | int newCksum = 0; |
| WiredHome | 3:c69fff55fc60 | 31 | int newFSize = 0; |
| WiredHome | 3:c69fff55fc60 | 32 | FILE *fh = fopen(fname, "rb"); |
| WiredHome | 3:c69fff55fc60 | 33 | INFO("IntegrityCheck(%s,%d,%d)", fname, cksum, fsize); |
| WiredHome | 3:c69fff55fc60 | 34 | if (fh) { |
| WiredHome | 3:c69fff55fc60 | 35 | char buf; |
| WiredHome | 3:c69fff55fc60 | 36 | while (fread(&buf, 1, 1, fh)) { |
| WiredHome | 3:c69fff55fc60 | 37 | newCksum = (newCksum + buf) & 0xFFFF; |
| WiredHome | 3:c69fff55fc60 | 38 | newFSize++; |
| WiredHome | 3:c69fff55fc60 | 39 | } |
| WiredHome | 3:c69fff55fc60 | 40 | fclose(fh); |
| WiredHome | 3:c69fff55fc60 | 41 | INFO(" Check(...,%d,%d)", newCksum, newFSize); |
| WiredHome | 3:c69fff55fc60 | 42 | if (newCksum == cksum && newFSize == fsize) |
| WiredHome | 3:c69fff55fc60 | 43 | res = true; |
| WiredHome | 3:c69fff55fc60 | 44 | } else { |
| WiredHome | 3:c69fff55fc60 | 45 | WARN("failed to open %s.", fname); |
| WiredHome | 3:c69fff55fc60 | 46 | } |
| WiredHome | 3:c69fff55fc60 | 47 | return res; |
| WiredHome | 1:208de08b1a19 | 48 | } |
| WiredHome | 1:208de08b1a19 | 49 | |
| WiredHome | 0:e221363f7942 | 50 | bool SoftwareUpdate(const char *url, const char * name, Reboot_T reboot) { |
| WiredHome | 0:e221363f7942 | 51 | HTTPClient http; |
| WiredHome | 0:e221363f7942 | 52 | //http.setTimeout( 15000 ); |
| WiredHome | 0:e221363f7942 | 53 | char fqurl[150]; // fully qualified url |
| WiredHome | 0:e221363f7942 | 54 | char verfn[32]; // local version file |
| WiredHome | 0:e221363f7942 | 55 | char fwfn[32]; |
| WiredHome | 0:e221363f7942 | 56 | bool result = false; // many things can go wrong, assume failure |
| WiredHome | 0:e221363f7942 | 57 | char buf[50]; |
| WiredHome | 0:e221363f7942 | 58 | |
| WiredHome | 0:e221363f7942 | 59 | INFO("SoftwareUpdate(%s,%s)", url, name); |
| WiredHome | 0:e221363f7942 | 60 | snprintf(verfn, 32, "/local/%s.ver", name); |
| WiredHome | 0:e221363f7942 | 61 | |
| WiredHome | 0:e221363f7942 | 62 | /* Read installed version string */ |
| WiredHome | 0:e221363f7942 | 63 | int inst_ver = -1; |
| WiredHome | 0:e221363f7942 | 64 | FILE *fv = fopen(verfn, "r"); |
| WiredHome | 0:e221363f7942 | 65 | if (fv) { |
| WiredHome | 0:e221363f7942 | 66 | fscanf(fv, "%d", &inst_ver); |
| WiredHome | 0:e221363f7942 | 67 | fclose(fv); |
| WiredHome | 0:e221363f7942 | 68 | } |
| WiredHome | 0:e221363f7942 | 69 | INFO(" Installed version: %d", inst_ver); |
| WiredHome | 0:e221363f7942 | 70 | |
| WiredHome | 0:e221363f7942 | 71 | /* Download latest version string */ |
| WiredHome | 0:e221363f7942 | 72 | HTTPText server_ver("test message"); |
| WiredHome | 0:e221363f7942 | 73 | snprintf(fqurl, 150, "%s/%s.txt", url, name); |
| WiredHome | 0:e221363f7942 | 74 | HTTPResult r = http.get(fqurl, buf, sizeof(buf)); |
| WiredHome | 0:e221363f7942 | 75 | if (r == HTTP_OK) { |
| WiredHome | 0:e221363f7942 | 76 | int latest_ver = -1; |
| WiredHome | 3:c69fff55fc60 | 77 | int cksum = 0; |
| WiredHome | 3:c69fff55fc60 | 78 | int fsize = 0; |
| WiredHome | 3:c69fff55fc60 | 79 | int parseCount; |
| WiredHome | 0:e221363f7942 | 80 | INFO(" read {%s}", buf); |
| WiredHome | 3:c69fff55fc60 | 81 | parseCount = sscanf(buf, "%d,%d,%d", &latest_ver, &cksum, &fsize); |
| WiredHome | 3:c69fff55fc60 | 82 | if (parseCount == 3) { |
| WiredHome | 3:c69fff55fc60 | 83 | INFO(" web version: %d", latest_ver); |
| WiredHome | 3:c69fff55fc60 | 84 | INFO(" checksum: %d", cksum); |
| WiredHome | 3:c69fff55fc60 | 85 | INFO(" file size: %d", fsize); |
| WiredHome | 3:c69fff55fc60 | 86 | if (inst_ver != latest_ver) { |
| WiredHome | 3:c69fff55fc60 | 87 | INFO(" Downloading firmware ver %d ...", latest_ver); |
| WiredHome | 3:c69fff55fc60 | 88 | sprintf(fwfn, "/local/%s%d.BIN", name, latest_ver); |
| WiredHome | 3:c69fff55fc60 | 89 | snprintf(fqurl, 150, "%s/%s.bin", url, name); |
| WiredHome | 3:c69fff55fc60 | 90 | |
| WiredHome | 3:c69fff55fc60 | 91 | HTTPFile latest(fwfn); |
| WiredHome | 3:c69fff55fc60 | 92 | r = http.get(fqurl, &latest); |
| WiredHome | 3:c69fff55fc60 | 93 | if (r == HTTP_OK) { |
| WiredHome | 3:c69fff55fc60 | 94 | // Check the integrity of the freshly downloaded file, |
| WiredHome | 3:c69fff55fc60 | 95 | // before swapping out the old version. |
| WiredHome | 3:c69fff55fc60 | 96 | // ... to appear here ... |
| WiredHome | 3:c69fff55fc60 | 97 | if (PassesIntegrityCheck(fwfn, cksum, fsize)) { |
| WiredHome | 3:c69fff55fc60 | 98 | sprintf(fwfn, "/local/%s%d.BIN", name, inst_ver); |
| WiredHome | 3:c69fff55fc60 | 99 | INFO(" Firmware downloaded, removing old version (%s).", fwfn); |
| WiredHome | 3:c69fff55fc60 | 100 | if (remove(fwfn)) { |
| WiredHome | 3:c69fff55fc60 | 101 | ERR(" *** Failed to remove old version. ***"); |
| WiredHome | 3:c69fff55fc60 | 102 | } |
| WiredHome | 3:c69fff55fc60 | 103 | INFO("Updating stored version number."); |
| WiredHome | 3:c69fff55fc60 | 104 | fv = fopen(verfn, "w"); |
| WiredHome | 3:c69fff55fc60 | 105 | if (fv) { |
| WiredHome | 3:c69fff55fc60 | 106 | int fr = fputs(buf, fv); |
| WiredHome | 3:c69fff55fc60 | 107 | if (fr < 0) { |
| WiredHome | 3:c69fff55fc60 | 108 | ERR("Failed (%d) to update stored version number.", fr); |
| WiredHome | 3:c69fff55fc60 | 109 | fclose( fv ); |
| WiredHome | 3:c69fff55fc60 | 110 | } else { |
| WiredHome | 3:c69fff55fc60 | 111 | fclose( fv ); |
| WiredHome | 3:c69fff55fc60 | 112 | if (reboot == AUTO_REBOOT) { |
| WiredHome | 3:c69fff55fc60 | 113 | WARN("Resetting...\n"); |
| WiredHome | 3:c69fff55fc60 | 114 | wait_ms(200); |
| WiredHome | 3:c69fff55fc60 | 115 | mbed_reset(); |
| WiredHome | 3:c69fff55fc60 | 116 | } |
| WiredHome | 3:c69fff55fc60 | 117 | result = true; |
| WiredHome | 3:c69fff55fc60 | 118 | } |
| WiredHome | 1:208de08b1a19 | 119 | } else { |
| WiredHome | 3:c69fff55fc60 | 120 | WARN("Failed to update local version info in %s.", verfn); |
| WiredHome | 1:208de08b1a19 | 121 | } |
| WiredHome | 0:e221363f7942 | 122 | } else { |
| WiredHome | 3:c69fff55fc60 | 123 | WARN("New file {%s} did not pass integrity check.", fwfn); |
| WiredHome | 0:e221363f7942 | 124 | } |
| WiredHome | 1:208de08b1a19 | 125 | } else { |
| WiredHome | 3:c69fff55fc60 | 126 | WARN("Failed to download lastest firmware."); |
| WiredHome | 0:e221363f7942 | 127 | } |
| WiredHome | 0:e221363f7942 | 128 | } else { |
| WiredHome | 3:c69fff55fc60 | 129 | WARN("Only %d parameters found in online version file.", parseCount); |
| WiredHome | 0:e221363f7942 | 130 | } |
| WiredHome | 0:e221363f7942 | 131 | } |
| WiredHome | 0:e221363f7942 | 132 | } else { |
| WiredHome | 1:208de08b1a19 | 133 | WARN("Failed to download online firmware version number."); |
| WiredHome | 0:e221363f7942 | 134 | } |
| WiredHome | 0:e221363f7942 | 135 | return result; |
| WiredHome | 0:e221363f7942 | 136 | } |
