SWUpdate library to be used with RPC.

Fork of SWUpdate by David Smart

Committer:
WiredHome
Date:
Sun Jun 15 20:01:58 2014 +0000
Revision:
8:8e840a036116
Parent:
7:a7efbae7e02e
Child:
9:73067ef14c30
Documentation and rearranging a few files for easier maintenance.

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 7:a7efbae7e02e 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 3:c69fff55fc60 80 parseCount = sscanf(buf, "%d,%d,%d", &latest_ver, &cksum, &fsize);
WiredHome 3:c69fff55fc60 81 if (parseCount == 3) {
WiredHome 3:c69fff55fc60 82 INFO(" web version: %d", latest_ver);
WiredHome 3:c69fff55fc60 83 INFO(" checksum: %d", cksum);
WiredHome 3:c69fff55fc60 84 INFO(" file size: %d", fsize);
WiredHome 3:c69fff55fc60 85 if (inst_ver != latest_ver) {
WiredHome 3:c69fff55fc60 86 INFO(" Downloading firmware ver %d ...", latest_ver);
WiredHome 3:c69fff55fc60 87 sprintf(fwfn, "/local/%s%d.BIN", name, latest_ver);
WiredHome 3:c69fff55fc60 88 snprintf(fqurl, 150, "%s/%s.bin", url, name);
WiredHome 3:c69fff55fc60 89
WiredHome 3:c69fff55fc60 90 HTTPFile latest(fwfn);
WiredHome 3:c69fff55fc60 91 r = http.get(fqurl, &latest);
WiredHome 3:c69fff55fc60 92 if (r == HTTP_OK) {
WiredHome 3:c69fff55fc60 93 // Check the integrity of the freshly downloaded file,
WiredHome 3:c69fff55fc60 94 // before swapping out the old version.
WiredHome 3:c69fff55fc60 95 // ... to appear here ...
WiredHome 3:c69fff55fc60 96 if (PassesIntegrityCheck(fwfn, cksum, fsize)) {
WiredHome 3:c69fff55fc60 97 sprintf(fwfn, "/local/%s%d.BIN", name, inst_ver);
WiredHome 3:c69fff55fc60 98 INFO(" Firmware downloaded, removing old version (%s).", fwfn);
WiredHome 3:c69fff55fc60 99 if (remove(fwfn)) {
WiredHome 3:c69fff55fc60 100 ERR(" *** Failed to remove old version. ***");
WiredHome 3:c69fff55fc60 101 }
WiredHome 3:c69fff55fc60 102 INFO("Updating stored version number.");
WiredHome 3:c69fff55fc60 103 fv = fopen(verfn, "w");
WiredHome 3:c69fff55fc60 104 if (fv) {
WiredHome 3:c69fff55fc60 105 int fr = fputs(buf, fv);
WiredHome 3:c69fff55fc60 106 if (fr < 0) {
WiredHome 3:c69fff55fc60 107 ERR("Failed (%d) to update stored version number.", fr);
WiredHome 3:c69fff55fc60 108 fclose( fv );
WiredHome 3:c69fff55fc60 109 } else {
WiredHome 3:c69fff55fc60 110 fclose( fv );
WiredHome 3:c69fff55fc60 111 if (reboot == AUTO_REBOOT) {
WiredHome 3:c69fff55fc60 112 WARN("Resetting...\n");
WiredHome 3:c69fff55fc60 113 wait_ms(200);
WiredHome 3:c69fff55fc60 114 mbed_reset();
WiredHome 3:c69fff55fc60 115 }
WiredHome 3:c69fff55fc60 116 result = true;
WiredHome 3:c69fff55fc60 117 }
WiredHome 1:208de08b1a19 118 } else {
WiredHome 3:c69fff55fc60 119 WARN("Failed to update local version info in %s.", verfn);
WiredHome 1:208de08b1a19 120 }
WiredHome 0:e221363f7942 121 } else {
WiredHome 3:c69fff55fc60 122 WARN("New file {%s} did not pass integrity check.", fwfn);
WiredHome 0:e221363f7942 123 }
WiredHome 1:208de08b1a19 124 } else {
WiredHome 3:c69fff55fc60 125 WARN("Failed to download lastest firmware.");
WiredHome 0:e221363f7942 126 }
WiredHome 0:e221363f7942 127 } else {
WiredHome 7:a7efbae7e02e 128 INFO("Online version is same as installed version.", parseCount);
WiredHome 0:e221363f7942 129 }
WiredHome 0:e221363f7942 130 }
WiredHome 0:e221363f7942 131 } else {
WiredHome 1:208de08b1a19 132 WARN("Failed to download online firmware version number.");
WiredHome 0:e221363f7942 133 }
WiredHome 0:e221363f7942 134 return result;
WiredHome 0:e221363f7942 135 }