SWUpdate library to be used with RPC.

Fork of SWUpdate by David Smart

Committer:
WiredHome
Date:
Sat Jul 05 22:27:09 2014 +0000
Revision:
17:1d318666246c
Parent:
16:de99e872fc9d
Child:
18:5f7667d63a27
The cleanup function was not properly forming the current version filename, so could delete it on some circumstances.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 12:f1fdf8cabbc4 1 /// @file
WiredHome 12:f1fdf8cabbc4 2 /// Automatic Software Update via the network.
WiredHome 9:73067ef14c30 3 ///
WiredHome 9:73067ef14c30 4 /// This library provides a reasonably simple interface to updating sofware
WiredHome 10:78d727e8d0de 5 /// semi-automatically via the network. It does that by querying a web server
WiredHome 10:78d727e8d0de 6 /// upon which you have placed an updated version of the embedded software
WiredHome 10:78d727e8d0de 7 /// application. Upon finding something there, it will determine if it is
WiredHome 10:78d727e8d0de 8 /// a different version than the one you current have installed and it
WiredHome 10:78d727e8d0de 9 /// will try to download the software. If that succeeds, then it can
WiredHome 10:78d727e8d0de 10 /// optionally reboot to activate the new software.
WiredHome 10:78d727e8d0de 11 ///
WiredHome 10:78d727e8d0de 12 /// While the name shown in the examples here is "myprog", this is unimportant.
WiredHome 10:78d727e8d0de 13 /// Your application will have a name of your choosing, which you will
WiredHome 10:78d727e8d0de 14 /// use in the API.
WiredHome 10:78d727e8d0de 15 ///
WiredHome 14:0e012d53c6df 16 /// @note Your binary file name should not exceed 6 characters. This leaves
WiredHome 14:0e012d53c6df 17 /// room for a 2-digit sequence number. Since this is using the local
WiredHome 14:0e012d53c6df 18 /// file system, it does not support long filenames when accessed from
WiredHome 14:0e012d53c6df 19 /// the mbed. So, SomeLongFile23.bin becomes somefi~1.bin and is then
WiredHome 14:0e012d53c6df 20 /// erased, leaving no file.
WiredHome 14:0e012d53c6df 21 ///
WiredHome 15:49cc43dcbbf6 22 /// @note This was tested with firmware version 16457. Others may/not work.
WiredHome 15:49cc43dcbbf6 23 /// To check your version, open the mbed.htm file in a text editor,
WiredHome 15:49cc43dcbbf6 24 /// and look for "&firmware=16457&"
WiredHome 15:49cc43dcbbf6 25 ///
WiredHome 10:78d727e8d0de 26 /// Local File System Files:
WiredHome 10:78d727e8d0de 27 ///
WiredHome 10:78d727e8d0de 28 /// The files of interest on the local file system are as follows:
WiredHome 10:78d727e8d0de 29 ///
WiredHome 14:0e012d53c6df 30 /// @li myprog23.bin - The actual application binary file that is currently
WiredHome 10:78d727e8d0de 31 /// executing. In this case, this is the 23rd version that
WiredHome 10:78d727e8d0de 32 /// has been installed. You can go to 99 after which you might
WiredHome 10:78d727e8d0de 33 /// want to start over.
WiredHome 10:78d727e8d0de 34 /// @li myprog.ver - A text file, maintained by this software update
WiredHome 10:78d727e8d0de 35 /// application, that was downloaded from the server with
WiredHome 10:78d727e8d0de 36 /// application version 23.
WiredHome 10:78d727e8d0de 37 ///
WiredHome 10:78d727e8d0de 38 /// If "myprog.ver" does not exist, it will assume that the server has a
WiredHome 10:78d727e8d0de 39 /// newer application, so it will be downloaded and activated (even if all
WiredHome 14:0e012d53c6df 40 /// it does is to replace the existing myprog23.bin file).
WiredHome 10:78d727e8d0de 41 ///
WiredHome 10:78d727e8d0de 42 /// Web Server Files:
WiredHome 10:78d727e8d0de 43 ///
WiredHome 10:78d727e8d0de 44 /// The files on the web server are as follows.
WiredHome 10:78d727e8d0de 45 ///
WiredHome 10:78d727e8d0de 46 /// @li myprog.bin - The latest version of the application binary file.
WiredHome 10:78d727e8d0de 47 /// Note that this file does not have any version number
WiredHome 10:78d727e8d0de 48 /// embedded into its filename as is the case on the local
WiredHome 10:78d727e8d0de 49 /// file system.
WiredHome 10:78d727e8d0de 50 /// @li myprog.txt - A corresponding text file. The root name must match
WiredHome 10:78d727e8d0de 51 /// that of the binary file.
WiredHome 10:78d727e8d0de 52 ///
WiredHome 10:78d727e8d0de 53 /// The myprog.txt file shall have 3 comma-separated numbers in it.
WiredHome 10:78d727e8d0de 54 /// version,checksum,filesize (e.g. "23,41384,107996").
WiredHome 10:78d727e8d0de 55 ///
WiredHome 10:78d727e8d0de 56 /// @li version is a simple number. If the number is different than
WiredHome 10:78d727e8d0de 57 /// what is stored on the local file system, then the program
WiredHome 10:78d727e8d0de 58 /// will be updated (even if the server number is lower).
WiredHome 10:78d727e8d0de 59 /// This bidirectional "update" can let you downgrade.
WiredHome 10:78d727e8d0de 60 /// @li checksum is the decimal representation of a simple 16-bit checksum.
WiredHome 10:78d727e8d0de 61 /// @li filesize is the decimal representation of the size of the file.
WiredHome 10:78d727e8d0de 62 ///
WiredHome 10:78d727e8d0de 63 /// Variations:
WiredHome 10:78d727e8d0de 64 ///
WiredHome 10:78d727e8d0de 65 /// Within that single web server folder, you could have several apps -
WiredHome 14:0e012d53c6df 66 /// @li Sensor.bin, Sensor.txt
WiredHome 14:0e012d53c6df 67 /// @li SensrB.bin, SensrB.txt
WiredHome 14:0e012d53c6df 68 /// @li SensrD.bin, SensrD.txt
WiredHome 10:78d727e8d0de 69 ///
WiredHome 10:78d727e8d0de 70 /// In this example, perhaps your first version was called SensorNode, but
WiredHome 10:78d727e8d0de 71 /// with a small hardware design change, you have a new "model B" version.
WiredHome 10:78d727e8d0de 72 /// This example also assumes that you have a need to maintain two separate
WiredHome 10:78d727e8d0de 73 /// applications, one for each hardware version.
WiredHome 10:78d727e8d0de 74 ///
WiredHome 13:cf76c2bd3dfc 75 /// Creating the Version and Integrity Check data:
WiredHome 13:cf76c2bd3dfc 76 ///
WiredHome 10:78d727e8d0de 77 /// You can create the server "myprog.txt" file with this perl script (not
WiredHome 10:78d727e8d0de 78 /// every detail is shown, but it should be easy to figure out).
WiredHome 10:78d727e8d0de 79 /// @code
WiredHome 10:78d727e8d0de 80 /// # Read current .txt file
WiredHome 10:78d727e8d0de 81 /// open (FT, "<$txt") || die("Can't read $txt.");
WiredHome 10:78d727e8d0de 82 /// $ver = <FT>; chomp $ver; close FT;
WiredHome 10:78d727e8d0de 83 /// $ver =~ s/(\d+),.*/$1/;
WiredHome 10:78d727e8d0de 84 /// print "Current Version is {$ver}\n";
WiredHome 10:78d727e8d0de 85 ///
WiredHome 10:78d727e8d0de 86 /// # Read the [assumed new] .bin file
WiredHome 10:78d727e8d0de 87 /// open (FB, "<$bin") || die("Can't read $bin.");
WiredHome 10:78d727e8d0de 88 /// binmode FB;
WiredHome 10:78d727e8d0de 89 /// while (sysread(FB, $c, 1))
WiredHome 10:78d727e8d0de 90 /// {
WiredHome 10:78d727e8d0de 91 /// $cksum = ($cksum + ord($c)) & 0xFFFF;
WiredHome 10:78d727e8d0de 92 /// $byteCount++;
WiredHome 10:78d727e8d0de 93 /// }
WiredHome 10:78d727e8d0de 94 /// close FB;
WiredHome 10:78d727e8d0de 95 /// # Advance version number and write the new .txt file
WiredHome 10:78d727e8d0de 96 /// $ver++; print "$ver Checksum is $cksum over $byteCount bytes.\n";
WiredHome 10:78d727e8d0de 97 /// open (FT, ">$txt") || die("Can't write update to $txt.");
WiredHome 10:78d727e8d0de 98 /// printf(FT "%d,%d,%d\n", $ver, $cksum,$byteCount);
WiredHome 10:78d727e8d0de 99 /// close FT;
WiredHome 10:78d727e8d0de 100 /// @endcode
WiredHome 4:1a3656ae80dc 101 ///
WiredHome 0:e221363f7942 102
WiredHome 0:e221363f7942 103 #ifndef SWUPDATE_H
WiredHome 0:e221363f7942 104 #define SWUPDATE_H
WiredHome 0:e221363f7942 105
WiredHome 17:1d318666246c 106 #include "mbed.h"
WiredHome 17:1d318666246c 107 #include "HTTPClient.h"
WiredHome 17:1d318666246c 108
WiredHome 9:73067ef14c30 109 // This defines the maximum string length for a fully qualified
WiredHome 9:73067ef14c30 110 // filename. Usually, this will be pretty short
WiredHome 16:de99e872fc9d 111 // (e.g. "/local/myprog.bin"), which should be 19 max with 8.3 filename.
WiredHome 16:de99e872fc9d 112 #define SW_MAX_FQFN 20
WiredHome 9:73067ef14c30 113
WiredHome 9:73067ef14c30 114 // This defines the maximum string length for the url, including
WiredHome 9:73067ef14c30 115 // the base filename of interest.
WiredHome 9:73067ef14c30 116 #define SW_MAX_URL 150
WiredHome 9:73067ef14c30 117
WiredHome 1:208de08b1a19 118 /// After downloading, the user can choose what happens next.
WiredHome 0:e221363f7942 119 typedef enum {
WiredHome 6:6025fddc1af9 120 DEFER_REBOOT, ///< Do not reboot to activate the new firmware.
WiredHome 6:6025fddc1af9 121 AUTO_REBOOT ///< Automatically reboot to activate the new firmware.
WiredHome 0:e221363f7942 122 } Reboot_T;
WiredHome 0:e221363f7942 123
WiredHome 9:73067ef14c30 124 /// Bit-Field return codes from the SoftwareUpdate API.
WiredHome 9:73067ef14c30 125 ///
WiredHome 9:73067ef14c30 126 /// Various things can go wrong in the software update process. The return
WiredHome 17:1d318666246c 127 /// value is a bit-field that flags the possibilities, although usually there
WiredHome 17:1d318666246c 128 /// will only be a single bit set.
WiredHome 17:1d318666246c 129 ///
WiredHome 9:73067ef14c30 130 typedef enum {
WiredHome 9:73067ef14c30 131 SWUP_OK = 0x00, ///< Software Update succeeded as planned.
WiredHome 9:73067ef14c30 132 SWUP_SAME_VER = 0x01, ///< Online version is the same as the installed version.
WiredHome 17:1d318666246c 133 SWUP_HTTP_BIN = 0x02, ///< HTTP get returned an error while trying to fetch the bin file.
WiredHome 17:1d318666246c 134 SWUP_OLD_STUCK = 0x04, ///< Old file could not be removed.
WiredHome 9:73067ef14c30 135 SWUP_VER_STUCK = 0x08, ///< Old version number could not be updated.
WiredHome 9:73067ef14c30 136 SWUP_VWRITE_FAILED = 0x10, ///< Can't open for write the version tracking file.
WiredHome 9:73067ef14c30 137 SWUP_INTEGRITY_FAILED = 0x20, ///< Integrity check of downloaded file failed.
WiredHome 17:1d318666246c 138 SWUP_HTTP_VER = 0x40, ///< HTTP get returned an error while trying to fetch the version file.
WiredHome 9:73067ef14c30 139 } SWUpdate_T;
WiredHome 9:73067ef14c30 140
WiredHome 10:78d727e8d0de 141
WiredHome 10:78d727e8d0de 142 /// To perform the software update, we simply give this API the web
WiredHome 10:78d727e8d0de 143 /// server URL that is hosting the embedded software. We also give it
WiredHome 10:78d727e8d0de 144 /// the "root" name of the file of interest, which permits you to
WiredHome 10:78d727e8d0de 145 /// have different applications served from the same location.
WiredHome 16:de99e872fc9d 146 ///
WiredHome 16:de99e872fc9d 147 /// Note that the root name can be a long filename, as is typically
WiredHome 16:de99e872fc9d 148 /// produced from the cloud-based build process. This name will
WiredHome 16:de99e872fc9d 149 /// be truncated to the first 6 characters when installed on the
WiredHome 16:de99e872fc9d 150 /// mbed local file system, in order to retain space for a 2-digit
WiredHome 16:de99e872fc9d 151 /// version number.
WiredHome 16:de99e872fc9d 152 ///
WiredHome 10:78d727e8d0de 153 /// One optional parameter lets you decide what happens if a new
WiredHome 10:78d727e8d0de 154 /// version is installed - automatically reboot to launch it, or
WiredHome 10:78d727e8d0de 155 /// return to the calling program which may perform a more orderly
WiredHome 10:78d727e8d0de 156 /// reboot.
WiredHome 9:73067ef14c30 157 ///
WiredHome 9:73067ef14c30 158 /// @code
WiredHome 9:73067ef14c30 159 /// ...
WiredHome 9:73067ef14c30 160 /// if (NowIsTheTimeToCheckForSoftwareUpdates()) {
WiredHome 16:de99e872fc9d 161 /// if (SWUP_OK == SoftwareUpdate("http://192.168.1.200/path/to/file", "myprog_LPC1768", DEFER_REBOOT)) {
WiredHome 9:73067ef14c30 162 /// printf("Software updated, rebooting now...\r\n");
WiredHome 9:73067ef14c30 163 /// wait_ms(5000);
WiredHome 9:73067ef14c30 164 /// mbed_reset();
WiredHome 9:73067ef14c30 165 /// }
WiredHome 9:73067ef14c30 166 /// }
WiredHome 9:73067ef14c30 167 /// ...
WiredHome 9:73067ef14c30 168 /// @endcode
WiredHome 9:73067ef14c30 169 ///
WiredHome 1:208de08b1a19 170 /// @param url is a pointer to a text string of the url from which to download.
WiredHome 1:208de08b1a19 171 /// @param name is the base filename of the binary file.
WiredHome 9:73067ef14c30 172 /// @param action determines whether to automatically reboot to activate the new bin.
WiredHome 13:cf76c2bd3dfc 173 /// @return SWUpdate_T code indicating if the update succeeded, otherwise it returns a bitmask
WiredHome 13:cf76c2bd3dfc 174 /// of failure flags. Also, note that if it succeeded, and it was set for AUTO_REBOOT
WiredHome 13:cf76c2bd3dfc 175 /// that it will not return from this function.
WiredHome 1:208de08b1a19 176 ///
WiredHome 9:73067ef14c30 177 SWUpdate_T SoftwareUpdate(const char *url, const char * name, Reboot_T action = AUTO_REBOOT);
WiredHome 0:e221363f7942 178
WiredHome 17:1d318666246c 179 /// Get the HTTP transaction return code.
WiredHome 17:1d318666246c 180 ///
WiredHome 17:1d318666246c 181 /// If something goes wrong with the communications with the server, SoftwareUpdate will
WiredHome 17:1d318666246c 182 /// respond with an SWUP_HTTP_VER or SWUP_HTTP_BIN return value. To learn more about
WiredHome 17:1d318666246c 183 /// what went wrong, this API will provide the actual return code from the HTTP transaction.
WiredHome 17:1d318666246c 184 ///
WiredHome 17:1d318666246c 185 /// @returns @ref HTTPResult code from the server transaction.
WiredHome 17:1d318666246c 186 ///
WiredHome 17:1d318666246c 187 HTTPResult SoftwareUpdateGetHTTPErrorCode(void);
WiredHome 17:1d318666246c 188
WiredHome 17:1d318666246c 189
WiredHome 0:e221363f7942 190 #endif // SWUPDATE_H