SWUpdate library to be used with RPC.

Fork of SWUpdate by David Smart

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?

UserRevisionLine numberNew 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 }