The FirmwareUpdater is a mbed firmware update library with HTTP server on cloud.

Dependents:   FirmwareUpdater_TestProgram geigercounter04 firm LPC1768_up_frim

Committer:
shintamainjp
Date:
Fri Nov 05 12:16:17 2010 +0000
Revision:
3:851bd91fa0ae
Parent:
2:a9a32355af69
Specification changed. The maximum firmware name length changed to 8 from 4.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shintamainjp 0:f9bdb06ab672 1 /**
shintamainjp 0:f9bdb06ab672 2 * =============================================================================
shintamainjp 1:0305a8120f06 3 * Firmware updater (Version 0.0.2)
shintamainjp 0:f9bdb06ab672 4 * =============================================================================
shintamainjp 0:f9bdb06ab672 5 * Copyright (c) 2010 Shinichiro Nakamura (CuBeatSystems)
shintamainjp 0:f9bdb06ab672 6 *
shintamainjp 0:f9bdb06ab672 7 * Permission is hereby granted, free of charge, to any person obtaining a copy
shintamainjp 0:f9bdb06ab672 8 * of this software and associated documentation files (the "Software"), to deal
shintamainjp 0:f9bdb06ab672 9 * in the Software without restriction, including without limitation the rights
shintamainjp 0:f9bdb06ab672 10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
shintamainjp 0:f9bdb06ab672 11 * copies of the Software, and to permit persons to whom the Software is
shintamainjp 0:f9bdb06ab672 12 * furnished to do so, subject to the following conditions:
shintamainjp 1:0305a8120f06 13 *
shintamainjp 0:f9bdb06ab672 14 * The above copyright notice and this permission notice shall be included in
shintamainjp 0:f9bdb06ab672 15 * all copies or substantial portions of the Software.
shintamainjp 0:f9bdb06ab672 16 *
shintamainjp 0:f9bdb06ab672 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
shintamainjp 0:f9bdb06ab672 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
shintamainjp 0:f9bdb06ab672 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
shintamainjp 0:f9bdb06ab672 20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
shintamainjp 0:f9bdb06ab672 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
shintamainjp 0:f9bdb06ab672 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
shintamainjp 0:f9bdb06ab672 23 * THE SOFTWARE.
shintamainjp 0:f9bdb06ab672 24 * =============================================================================
shintamainjp 0:f9bdb06ab672 25 */
shintamainjp 0:f9bdb06ab672 26
shintamainjp 0:f9bdb06ab672 27 #include "FirmwareUpdater.h"
shintamainjp 0:f9bdb06ab672 28
shintamainjp 0:f9bdb06ab672 29 #include <stdio.h>
shintamainjp 0:f9bdb06ab672 30 #include <stdarg.h>
shintamainjp 0:f9bdb06ab672 31
shintamainjp 0:f9bdb06ab672 32 extern "C" void mbed_reset();
shintamainjp 0:f9bdb06ab672 33
shintamainjp 0:f9bdb06ab672 34 const std::string FirmwareUpdater::EXT_BIN = ".bin";
shintamainjp 0:f9bdb06ab672 35 const std::string FirmwareUpdater::EXT_BINTMP = ".b__";
shintamainjp 0:f9bdb06ab672 36 const std::string FirmwareUpdater::EXT_TXT = ".txt";
shintamainjp 0:f9bdb06ab672 37 const std::string FirmwareUpdater::EXT_TXTTMP = ".t__";
shintamainjp 0:f9bdb06ab672 38
shintamainjp 0:f9bdb06ab672 39 /**
shintamainjp 0:f9bdb06ab672 40 * Create.
shintamainjp 0:f9bdb06ab672 41 *
shintamainjp 0:f9bdb06ab672 42 * @param url URL for firmware. Do not include a target file name.
shintamainjp 0:f9bdb06ab672 43 * @param name An application name. Do not include a extention.
shintamainjp 0:f9bdb06ab672 44 * @param log True if logging.
shintamainjp 0:f9bdb06ab672 45 */
shintamainjp 0:f9bdb06ab672 46 FirmwareUpdater::FirmwareUpdater(std::string url, std::string name, bool log)
shintamainjp 0:f9bdb06ab672 47 : url(url), name(name), log(log), local("local") {
shintamainjp 0:f9bdb06ab672 48 client.setTimeout(10000);
shintamainjp 0:f9bdb06ab672 49
shintamainjp 0:f9bdb06ab672 50 /*
shintamainjp 0:f9bdb06ab672 51 * A file name on the mbed local file system should keep '8 + 3' types of name.
shintamainjp 0:f9bdb06ab672 52 */
shintamainjp 3:851bd91fa0ae 53 if (MAXNAMELEN < name.length()) {
shintamainjp 3:851bd91fa0ae 54 LOG("ERR : Invalid firmware name '%s' found. The maximum length is %d.\n", name.c_str(), MAXNAMELEN);
shintamainjp 3:851bd91fa0ae 55 error("ERR : Invalid firmware name '%s' found. The maximum length is %d.\n", name.c_str(), MAXNAMELEN);
shintamainjp 0:f9bdb06ab672 56 }
shintamainjp 0:f9bdb06ab672 57 }
shintamainjp 0:f9bdb06ab672 58
shintamainjp 0:f9bdb06ab672 59 /**
shintamainjp 0:f9bdb06ab672 60 * Dispose.
shintamainjp 0:f9bdb06ab672 61 */
shintamainjp 0:f9bdb06ab672 62 FirmwareUpdater::~FirmwareUpdater() {
shintamainjp 0:f9bdb06ab672 63 }
shintamainjp 0:f9bdb06ab672 64
shintamainjp 0:f9bdb06ab672 65 /**
shintamainjp 0:f9bdb06ab672 66 * Get a URL.
shintamainjp 0:f9bdb06ab672 67 *
shintamainjp 0:f9bdb06ab672 68 * @return URL.
shintamainjp 0:f9bdb06ab672 69 */
shintamainjp 0:f9bdb06ab672 70 const std::string FirmwareUpdater:: getURL() const {
shintamainjp 0:f9bdb06ab672 71 return url;
shintamainjp 0:f9bdb06ab672 72 }
shintamainjp 0:f9bdb06ab672 73
shintamainjp 0:f9bdb06ab672 74 /**
shintamainjp 0:f9bdb06ab672 75 * Get a name.
shintamainjp 0:f9bdb06ab672 76 *
shintamainjp 0:f9bdb06ab672 77 * @return name.
shintamainjp 0:f9bdb06ab672 78 */
shintamainjp 0:f9bdb06ab672 79 const std::string FirmwareUpdater:: getName() const {
shintamainjp 0:f9bdb06ab672 80 return name;
shintamainjp 0:f9bdb06ab672 81 }
shintamainjp 0:f9bdb06ab672 82
shintamainjp 0:f9bdb06ab672 83 /**
shintamainjp 0:f9bdb06ab672 84 * Checking a new firmware.
shintamainjp 0:f9bdb06ab672 85 * Compare versions of the software between local storage on mbed and on webserver.
shintamainjp 0:f9bdb06ab672 86 *
shintamainjp 0:f9bdb06ab672 87 * @return Return 0 if a new firmware exists.
shintamainjp 0:f9bdb06ab672 88 */
shintamainjp 0:f9bdb06ab672 89 int FirmwareUpdater::exist() {
shintamainjp 0:f9bdb06ab672 90 int ver_local, ver_server;
shintamainjp 0:f9bdb06ab672 91
shintamainjp 0:f9bdb06ab672 92 /*
shintamainjp 0:f9bdb06ab672 93 * Fetch the version from a local.
shintamainjp 0:f9bdb06ab672 94 */
shintamainjp 1:0305a8120f06 95 std::string file_local = "/local/" + name + EXT_TXT;
shintamainjp 1:0305a8120f06 96 ver_local = readVersionFromFile(file_local.c_str());
shintamainjp 1:0305a8120f06 97 if (ver_local < 0) {
shintamainjp 1:0305a8120f06 98 return -1;
shintamainjp 0:f9bdb06ab672 99 }
shintamainjp 1:0305a8120f06 100
shintamainjp 0:f9bdb06ab672 101 /*
shintamainjp 0:f9bdb06ab672 102 * Fetch the version from a server.
shintamainjp 0:f9bdb06ab672 103 */
shintamainjp 1:0305a8120f06 104 std::string file_server = url + "/" + name + EXT_TXT;
shintamainjp 1:0305a8120f06 105 ver_server = readVersionFromURL(file_server.c_str());
shintamainjp 1:0305a8120f06 106 if (ver_server < 0) {
shintamainjp 1:0305a8120f06 107 return -2;
shintamainjp 0:f9bdb06ab672 108 }
shintamainjp 0:f9bdb06ab672 109
shintamainjp 0:f9bdb06ab672 110 return (ver_local < ver_server) ? 0 : 1;
shintamainjp 0:f9bdb06ab672 111 }
shintamainjp 0:f9bdb06ab672 112
shintamainjp 0:f9bdb06ab672 113 /**
shintamainjp 0:f9bdb06ab672 114 * Execute update.
shintamainjp 0:f9bdb06ab672 115 *
shintamainjp 0:f9bdb06ab672 116 * @return Return 0 if it succeed.
shintamainjp 0:f9bdb06ab672 117 */
shintamainjp 0:f9bdb06ab672 118 int FirmwareUpdater::execute() {
shintamainjp 0:f9bdb06ab672 119 /*
shintamainjp 0:f9bdb06ab672 120 * Fetch the files.
shintamainjp 0:f9bdb06ab672 121 */
shintamainjp 0:f9bdb06ab672 122 std::string serv_txt = url + "/" + name + EXT_TXT;
shintamainjp 0:f9bdb06ab672 123 std::string file_txttmp = "/local/" + name + EXT_TXTTMP;
shintamainjp 0:f9bdb06ab672 124 if (fetch(serv_txt, file_txttmp) != 0) {
shintamainjp 1:0305a8120f06 125 LOG("ERR : Aborted...\n");
shintamainjp 0:f9bdb06ab672 126 return -1;
shintamainjp 0:f9bdb06ab672 127 }
shintamainjp 1:0305a8120f06 128 std::string serv_bin = url + "/" + name + EXT_BIN;
shintamainjp 1:0305a8120f06 129 std::string file_bintmp = "/local/" + name + EXT_BINTMP;
shintamainjp 0:f9bdb06ab672 130 if (fetch(serv_bin, file_bintmp) != 0) {
shintamainjp 1:0305a8120f06 131 LOG("ERR : Aborted...\n");
shintamainjp 0:f9bdb06ab672 132 return -2;
shintamainjp 0:f9bdb06ab672 133 }
shintamainjp 1:0305a8120f06 134
shintamainjp 1:0305a8120f06 135 /*
shintamainjp 1:0305a8120f06 136 * Check the firmware versions.
shintamainjp 1:0305a8120f06 137 */
shintamainjp 1:0305a8120f06 138 std::string file_txt = "/local/" + name + EXT_TXT;
shintamainjp 1:0305a8120f06 139 int ver_old = readVersionFromFile(file_txt.c_str());
shintamainjp 1:0305a8120f06 140 int ver_new = readVersionFromFile(file_txttmp.c_str());
shintamainjp 1:0305a8120f06 141 if (ver_old < 0) {
shintamainjp 1:0305a8120f06 142 LOG("ERR : Could not read the previous firmware version.\n");
shintamainjp 1:0305a8120f06 143 LOG("ERR : Aborted...\n");
shintamainjp 1:0305a8120f06 144 return -3;
shintamainjp 1:0305a8120f06 145 }
shintamainjp 1:0305a8120f06 146 if (ver_new < 0) {
shintamainjp 1:0305a8120f06 147 LOG("ERR : Could not read the new firmware version.\n");
shintamainjp 1:0305a8120f06 148 LOG("ERR : Aborted...\n");
shintamainjp 1:0305a8120f06 149 return -4;
shintamainjp 1:0305a8120f06 150 }
shintamainjp 1:0305a8120f06 151 if (ver_new < ver_old) {
shintamainjp 1:0305a8120f06 152 LOG("ERR : Ignore the new firmware. (old=%d, new=%d)\n", ver_old, ver_new);
shintamainjp 1:0305a8120f06 153 LOG("ERR : Aborted...\n");
shintamainjp 1:0305a8120f06 154 return -5;
shintamainjp 1:0305a8120f06 155 }
shintamainjp 1:0305a8120f06 156 LOG("INFO: Firmware updating... (%d -> %d)\n", ver_old, ver_new);
shintamainjp 1:0305a8120f06 157
shintamainjp 1:0305a8120f06 158 /*
shintamainjp 1:0305a8120f06 159 * Cleanup the previous versions.
shintamainjp 1:0305a8120f06 160 *
shintamainjp 1:0305a8120f06 161 * Note:
shintamainjp 1:0305a8120f06 162 * A file time stamp on mbed is always '12:00 01/01/2008'.
shintamainjp 1:0305a8120f06 163 * mbed can't sense updated firmware when the file name is same as previous version.
shintamainjp 1:0305a8120f06 164 *
shintamainjp 1:0305a8120f06 165 * So I decided to cleanup all bin files.
shintamainjp 1:0305a8120f06 166 * And the new firmware name is 'name-VERSION.bin'.
shintamainjp 1:0305a8120f06 167 * To remove previous versions at first means 'start critical section on the system'.
shintamainjp 1:0305a8120f06 168 */
shintamainjp 1:0305a8120f06 169 cleanupAllBinFiles();
shintamainjp 1:0305a8120f06 170
shintamainjp 0:f9bdb06ab672 171 /*
shintamainjp 0:f9bdb06ab672 172 * Copy it.
shintamainjp 0:f9bdb06ab672 173 */
shintamainjp 3:851bd91fa0ae 174 char nn[32];
shintamainjp 3:851bd91fa0ae 175 createNewBinName(ver_new, nn, sizeof(nn));
shintamainjp 3:851bd91fa0ae 176 std::string file_bin = "/local/" + std::string(nn) + EXT_BIN;
shintamainjp 0:f9bdb06ab672 177 if (copy(file_txttmp, file_txt) != 0) {
shintamainjp 1:0305a8120f06 178 return -6;
shintamainjp 0:f9bdb06ab672 179 }
shintamainjp 0:f9bdb06ab672 180 if (copy(file_bintmp, file_bin) != 0) {
shintamainjp 1:0305a8120f06 181 return -7;
shintamainjp 0:f9bdb06ab672 182 }
shintamainjp 0:f9bdb06ab672 183 /*
shintamainjp 0:f9bdb06ab672 184 * Delete the temporary files.
shintamainjp 0:f9bdb06ab672 185 */
shintamainjp 0:f9bdb06ab672 186 remove(file_txttmp.c_str());
shintamainjp 0:f9bdb06ab672 187 remove(file_bintmp.c_str());
shintamainjp 0:f9bdb06ab672 188 return 0;
shintamainjp 0:f9bdb06ab672 189 }
shintamainjp 0:f9bdb06ab672 190
shintamainjp 0:f9bdb06ab672 191 /**
shintamainjp 0:f9bdb06ab672 192 * Reset system.
shintamainjp 0:f9bdb06ab672 193 */
shintamainjp 0:f9bdb06ab672 194 void FirmwareUpdater::reset() {
shintamainjp 0:f9bdb06ab672 195 mbed_reset();
shintamainjp 0:f9bdb06ab672 196 }
shintamainjp 0:f9bdb06ab672 197
shintamainjp 0:f9bdb06ab672 198 /**
shintamainjp 0:f9bdb06ab672 199 * Fetch a file.
shintamainjp 0:f9bdb06ab672 200 *
shintamainjp 0:f9bdb06ab672 201 * @param src_url URL of a source file.
shintamainjp 0:f9bdb06ab672 202 * @param local_file Local file name.
shintamainjp 0:f9bdb06ab672 203 *
shintamainjp 0:f9bdb06ab672 204 * @return Return 0 if it succeed.
shintamainjp 0:f9bdb06ab672 205 */
shintamainjp 0:f9bdb06ab672 206 int FirmwareUpdater::fetch(std::string src_url, std::string local_file) {
shintamainjp 0:f9bdb06ab672 207 /*
shintamainjp 0:f9bdb06ab672 208 * Fetch the source file from URL to a temporary file on local.
shintamainjp 0:f9bdb06ab672 209 */
shintamainjp 0:f9bdb06ab672 210 HTTPFile file(local_file.c_str());
shintamainjp 0:f9bdb06ab672 211 int r = client.get(src_url.c_str(), &file);
shintamainjp 0:f9bdb06ab672 212 if (r != HTTP_OK) {
shintamainjp 1:0305a8120f06 213 LOG("ERR : Fetch '%s' to '%s'.\n", src_url.c_str(), local_file.c_str());
shintamainjp 0:f9bdb06ab672 214 return -1;
shintamainjp 0:f9bdb06ab672 215 }
shintamainjp 3:851bd91fa0ae 216 LOG("INFO: Fetched '%s' to '%s'.\n", src_url.c_str(), local_file.c_str());
shintamainjp 0:f9bdb06ab672 217 return 0;
shintamainjp 0:f9bdb06ab672 218 }
shintamainjp 0:f9bdb06ab672 219
shintamainjp 0:f9bdb06ab672 220 /**
shintamainjp 0:f9bdb06ab672 221 * Copy a file.
shintamainjp 0:f9bdb06ab672 222 *
shintamainjp 0:f9bdb06ab672 223 * @param local_file1 Source file.
shintamainjp 0:f9bdb06ab672 224 * @param local_file2 Destination file.
shintamainjp 0:f9bdb06ab672 225 *
shintamainjp 0:f9bdb06ab672 226 * @return Return 0 if it succeed.
shintamainjp 0:f9bdb06ab672 227 */
shintamainjp 0:f9bdb06ab672 228 int FirmwareUpdater::copy(std::string local_file1, std::string local_file2) {
shintamainjp 1:0305a8120f06 229 LOG("INFO: File copying... (%s->%s)\n", local_file1.c_str(), local_file2.c_str());
shintamainjp 0:f9bdb06ab672 230 FILE *rp = fopen(local_file1.c_str(), "rb");
shintamainjp 0:f9bdb06ab672 231 if (rp == NULL) {
shintamainjp 1:0305a8120f06 232 LOG("ERR : File '%s' open failed.\n", local_file1.c_str());
shintamainjp 0:f9bdb06ab672 233 return -1;
shintamainjp 0:f9bdb06ab672 234 }
shintamainjp 0:f9bdb06ab672 235 remove(local_file2.c_str());
shintamainjp 0:f9bdb06ab672 236 FILE *wp = fopen(local_file2.c_str(), "wb");
shintamainjp 0:f9bdb06ab672 237 if (wp == NULL) {
shintamainjp 1:0305a8120f06 238 LOG("ERR : File '%s' open failed.\n", local_file2.c_str());
shintamainjp 0:f9bdb06ab672 239 fclose(rp);
shintamainjp 0:f9bdb06ab672 240 return -2;
shintamainjp 0:f9bdb06ab672 241 }
shintamainjp 0:f9bdb06ab672 242 int c;
shintamainjp 0:f9bdb06ab672 243 while ((c = fgetc(rp)) != EOF) {
shintamainjp 0:f9bdb06ab672 244 fputc(c, wp);
shintamainjp 0:f9bdb06ab672 245 }
shintamainjp 0:f9bdb06ab672 246 fclose(rp);
shintamainjp 0:f9bdb06ab672 247 fclose(wp);
shintamainjp 1:0305a8120f06 248 LOG("INFO: File copied. (%s->%s)\n", local_file1.c_str(), local_file2.c_str());
shintamainjp 0:f9bdb06ab672 249 return 0;
shintamainjp 0:f9bdb06ab672 250 }
shintamainjp 0:f9bdb06ab672 251
shintamainjp 0:f9bdb06ab672 252 /**
shintamainjp 0:f9bdb06ab672 253 * Output a message to a log file.
shintamainjp 0:f9bdb06ab672 254 *
shintamainjp 0:f9bdb06ab672 255 * @param format ...
shintamainjp 0:f9bdb06ab672 256 */
shintamainjp 0:f9bdb06ab672 257 void FirmwareUpdater::LOG(const char* format, ...) {
shintamainjp 0:f9bdb06ab672 258 if (log) {
shintamainjp 0:f9bdb06ab672 259 FILE *fplog = fopen("/local/update.log", "a");
shintamainjp 0:f9bdb06ab672 260 if (fplog != NULL) {
shintamainjp 0:f9bdb06ab672 261 char buf[BUFSIZ];
shintamainjp 0:f9bdb06ab672 262 va_list p;
shintamainjp 0:f9bdb06ab672 263 va_start(p, format);
shintamainjp 0:f9bdb06ab672 264 vsnprintf(buf, sizeof(buf) - 1, format, p);
shintamainjp 0:f9bdb06ab672 265 fprintf(fplog, "%s", buf);
shintamainjp 2:a9a32355af69 266 // printf("%s", buf); /* If you want to check a message from a console. */
shintamainjp 0:f9bdb06ab672 267 va_end(p);
shintamainjp 0:f9bdb06ab672 268 fclose(fplog);
shintamainjp 0:f9bdb06ab672 269 }
shintamainjp 0:f9bdb06ab672 270 }
shintamainjp 0:f9bdb06ab672 271 }
shintamainjp 1:0305a8120f06 272
shintamainjp 1:0305a8120f06 273 /**
shintamainjp 1:0305a8120f06 274 * Cleanup all bin files.
shintamainjp 1:0305a8120f06 275 */
shintamainjp 1:0305a8120f06 276 int FirmwareUpdater::cleanupAllBinFiles(void) {
shintamainjp 1:0305a8120f06 277 struct dirent *p;
shintamainjp 1:0305a8120f06 278 DIR *dir = opendir("/local");
shintamainjp 1:0305a8120f06 279 if (dir == NULL) {
shintamainjp 1:0305a8120f06 280 return -1;
shintamainjp 1:0305a8120f06 281 }
shintamainjp 1:0305a8120f06 282 while ((p = readdir(dir)) != NULL) {
shintamainjp 1:0305a8120f06 283 char *str = p->d_name;
shintamainjp 1:0305a8120f06 284 if ((strstr(str, ".bin") != NULL) || (strstr(str, ".BIN") != NULL)) {
shintamainjp 1:0305a8120f06 285 char buf[BUFSIZ];
shintamainjp 1:0305a8120f06 286 snprintf(buf, sizeof(buf) - 1, "/local/%s", str);
shintamainjp 1:0305a8120f06 287 if (remove(buf) == 0) {
shintamainjp 1:0305a8120f06 288 LOG("INFO: Deleted '%s'.\n", buf);
shintamainjp 1:0305a8120f06 289 } else {
shintamainjp 1:0305a8120f06 290 LOG("ERR : Delete '%s' failed.\n", buf);
shintamainjp 1:0305a8120f06 291 }
shintamainjp 1:0305a8120f06 292 }
shintamainjp 1:0305a8120f06 293 }
shintamainjp 1:0305a8120f06 294 closedir(dir);
shintamainjp 1:0305a8120f06 295 return 0;
shintamainjp 1:0305a8120f06 296 }
shintamainjp 1:0305a8120f06 297
shintamainjp 1:0305a8120f06 298 /**
shintamainjp 3:851bd91fa0ae 299 * Create a new binary file name.
shintamainjp 3:851bd91fa0ae 300 *
shintamainjp 3:851bd91fa0ae 301 * @param ver Version.
shintamainjp 3:851bd91fa0ae 302 * @param buf A pointer to a buffer.
shintamainjp 3:851bd91fa0ae 303 * @param siz A size of the buffer.
shintamainjp 3:851bd91fa0ae 304 *
shintamainjp 3:851bd91fa0ae 305 * @return Return 0 if it succeed.
shintamainjp 3:851bd91fa0ae 306 */
shintamainjp 3:851bd91fa0ae 307 int FirmwareUpdater::createNewBinName(const int ver, char *buf, size_t siz) {
shintamainjp 3:851bd91fa0ae 308 if (siz <= name.length()) {
shintamainjp 3:851bd91fa0ae 309 return -1;
shintamainjp 3:851bd91fa0ae 310 }
shintamainjp 3:851bd91fa0ae 311 snprintf(buf, siz - 1, "%s", name.c_str());
shintamainjp 3:851bd91fa0ae 312 char nb[32];
shintamainjp 3:851bd91fa0ae 313 snprintf(nb, sizeof(nb) - 1, "-%d", ver);
shintamainjp 3:851bd91fa0ae 314 if (strlen(buf) + strlen(nb) <= MAXNAMELEN) {
shintamainjp 3:851bd91fa0ae 315 strcat(buf, nb);
shintamainjp 3:851bd91fa0ae 316 return 0;
shintamainjp 3:851bd91fa0ae 317 } else {
shintamainjp 3:851bd91fa0ae 318 strcpy(buf + (MAXNAMELEN - strlen(nb)), nb);
shintamainjp 3:851bd91fa0ae 319 return 0;
shintamainjp 3:851bd91fa0ae 320 }
shintamainjp 3:851bd91fa0ae 321 }
shintamainjp 3:851bd91fa0ae 322
shintamainjp 3:851bd91fa0ae 323 /**
shintamainjp 1:0305a8120f06 324 * Read a version from a file.
shintamainjp 1:0305a8120f06 325 *
shintamainjp 1:0305a8120f06 326 * @param filename file name.
shintamainjp 1:0305a8120f06 327 * @return A version.
shintamainjp 1:0305a8120f06 328 */
shintamainjp 1:0305a8120f06 329 int FirmwareUpdater::readVersionFromFile(const char *filename) {
shintamainjp 1:0305a8120f06 330 int ver;
shintamainjp 1:0305a8120f06 331 FILE *fp = fopen(filename, "rb");
shintamainjp 1:0305a8120f06 332 if (fp == NULL) {
shintamainjp 1:0305a8120f06 333 LOG("ERR : Version file '%s' open failed.\n", filename);
shintamainjp 1:0305a8120f06 334 return -1;
shintamainjp 1:0305a8120f06 335 }
shintamainjp 1:0305a8120f06 336 if (fscanf(fp, "%d", &ver) != 1) {
shintamainjp 1:0305a8120f06 337 LOG("ERR : Version file '%s' is invalid.\n", filename);
shintamainjp 1:0305a8120f06 338 return -2;
shintamainjp 1:0305a8120f06 339 }
shintamainjp 1:0305a8120f06 340 fclose(fp);
shintamainjp 1:0305a8120f06 341 LOG("INFO: Version file '%s': Version %d.\n", filename, ver);
shintamainjp 1:0305a8120f06 342 return ver;
shintamainjp 1:0305a8120f06 343 }
shintamainjp 1:0305a8120f06 344
shintamainjp 1:0305a8120f06 345 /**
shintamainjp 1:0305a8120f06 346 * Read a version from a URL.
shintamainjp 1:0305a8120f06 347 *
shintamainjp 1:0305a8120f06 348 * @param url URL.
shintamainjp 1:0305a8120f06 349 * @return A version.
shintamainjp 1:0305a8120f06 350 */
shintamainjp 1:0305a8120f06 351 int FirmwareUpdater::readVersionFromURL(const char *url) {
shintamainjp 1:0305a8120f06 352 int ver;
shintamainjp 1:0305a8120f06 353 HTTPText text;
shintamainjp 1:0305a8120f06 354 HTTPResult r = client.get(url, &text);
shintamainjp 1:0305a8120f06 355 if (r != HTTP_OK) {
shintamainjp 1:0305a8120f06 356 LOG("ERR : Version file '%s' open failed.\n", url);
shintamainjp 1:0305a8120f06 357 return -1;
shintamainjp 1:0305a8120f06 358 }
shintamainjp 1:0305a8120f06 359 if (sscanf(text.gets(), "%d", &ver) != 1) {
shintamainjp 1:0305a8120f06 360 LOG("ERR : Version file '%s' is invalid.\n", url);
shintamainjp 1:0305a8120f06 361 return -2;
shintamainjp 1:0305a8120f06 362 }
shintamainjp 1:0305a8120f06 363 LOG("INFO: Version file '%s': Version %d.\n", url, ver);
shintamainjp 1:0305a8120f06 364 return ver;
shintamainjp 1:0305a8120f06 365 }