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.
vfs_user.c
00001 /** 00002 * @file vfs_user.c 00003 * @brief Implementation of vfs_user.h 00004 * 00005 * DAPLink Interface Firmware 00006 * Copyright (c) 2009-2020, ARM Limited, All Rights Reserved 00007 * Copyright 2019, Cypress Semiconductor Corporation 00008 * or a subsidiary of Cypress Semiconductor Corporation. 00009 * SPDX-License-Identifier: Apache-2.0 00010 * 00011 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00012 * not use this file except in compliance with the License. 00013 * You may obtain a copy of the License at 00014 * 00015 * http://www.apache.org/licenses/LICENSE-2.0 00016 * 00017 * Unless required by applicable law or agreed to in writing, software 00018 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00019 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 * See the License for the specific language governing permissions and 00021 * limitations under the License. 00022 */ 00023 00024 #include <stdbool.h> 00025 #include <ctype.h> 00026 #include <string.h> 00027 00028 #include "vfs_user.h" 00029 #include "vfs_manager.h" 00030 #include "error.h" 00031 #include "util.h" 00032 #include "settings.h" 00033 #include "daplink.h" 00034 #include "version_git.h" 00035 #include "info.h" 00036 #include "gpio.h" // for gpio_get_sw_reset 00037 #include "flash_intf.h" // for flash_intf_target 00038 #include "cortex_m.h" 00039 #include "target_board.h" 00040 #include "flash_manager.h" 00041 00042 //! @brief Size in bytes of the virtual disk. 00043 //! 00044 //! Must be bigger than 4x the flash size of the biggest supported 00045 //! device. This is to accomodate for hex file programming. 00046 #define VFS_DISK_SIZE (MB(64)) 00047 00048 //! @brief Constants for magic action or config files. 00049 //! 00050 //! The "magic files" are files with a special name that if created on the USB MSC volume, will 00051 //! cause an event. There are two classes of magic files: action files and config files. The former 00052 //! causes a given action to take place, while the latter changes a persistent configuration setting 00053 //! to a predetermined value. 00054 //! 00055 //! See #s_magic_file_info for the mapping of filenames to these enums. 00056 typedef enum _magic_file { 00057 kDAPLinkModeActionFile, //!< Switch between interface and bootloader. 00058 kTestAssertActionFile, //!< Force an assertion for testing. 00059 kRefreshActionFile, //!< Force a remount. 00060 kEraseActionFile, //!< Erase the target flash. 00061 kAutoResetConfigFile, //!< Enable reset after flash. 00062 kHardResetConfigFile, //!< Disable reset after flash. 00063 kAutomationOnConfigFile, //!< Enable automation. 00064 kAutomationOffConfigFile, //!< Disable automation. 00065 kOverflowOnConfigFile, //!< Enable UART overflow reporting. 00066 kOverflowOffConfigFile, //!< Disable UART overflow reporting. 00067 kMSDOnConfigFile, //!< Enable USB MSC. Uh.... 00068 kMSDOffConfigFile, //!< Disable USB MSC. 00069 kPageEraseActionFile, //!< Enable page programming and sector erase for drag and drop. 00070 kChipEraseActionFile, //!< Enable page programming and chip erase for drag and drop. 00071 } magic_file_t; 00072 00073 //! @brief Mapping from filename string to magic file enum. 00074 typedef struct _magic_file_info { 00075 const char *name; //!< Name of the magic file, must be in 8.3 format. 00076 magic_file_t which; //!< Enum for the file. 00077 } magic_file_info_t; 00078 00079 static const char mbed_redirect_file[] = 00080 "<!doctype html>\r\n" 00081 "<!-- mbed Platform Website and Authentication Shortcut -->\r\n" 00082 "<html>\r\n" 00083 "<head>\r\n" 00084 "<meta charset=\"utf-8\">\r\n" 00085 "<title>mbed Website Shortcut</title>\r\n" 00086 "</head>\r\n" 00087 "<body>\r\n" 00088 "<script>\r\n" 00089 "window.location.replace(\"@R\");\r\n" 00090 "</script>\r\n" 00091 "</body>\r\n" 00092 "</html>\r\n"; 00093 00094 static const char error_prefix[] = "error: "; 00095 static const char error_type_prefix[] = "type: "; 00096 00097 static const vfs_filename_t assert_file = "ASSERT TXT"; 00098 00099 //! @brief Table of magic files and their names. 00100 static const magic_file_info_t s_magic_file_info[] = { 00101 { daplink_mode_file_name, kDAPLinkModeActionFile }, 00102 { "ASSERT ACT", kTestAssertActionFile }, 00103 { "REFRESH ACT", kRefreshActionFile }, 00104 { "ERASE ACT", kEraseActionFile }, 00105 { "AUTO_RSTCFG", kAutoResetConfigFile }, 00106 { "HARD_RSTCFG", kHardResetConfigFile }, 00107 { "AUTO_ON CFG", kAutomationOnConfigFile }, 00108 { "AUTO_OFFCFG", kAutomationOffConfigFile }, 00109 { "OVFL_ON CFG", kOverflowOnConfigFile }, 00110 { "OVFL_OFFCFG", kOverflowOffConfigFile }, 00111 { "MSD_ON CFG", kMSDOnConfigFile }, 00112 { "MSD_OFF CFG", kMSDOffConfigFile }, 00113 { "PAGE_ON ACT", kPageEraseActionFile }, 00114 { "PAGE_OFFACT", kChipEraseActionFile }, 00115 }; 00116 00117 static uint8_t file_buffer[VFS_SECTOR_SIZE]; 00118 static char assert_buf[64 + 1]; 00119 static uint16_t assert_line; 00120 static assert_source_t assert_source; 00121 static uint32_t remount_count; 00122 00123 static uint32_t get_file_size(vfs_read_cb_t read_func); 00124 00125 static uint32_t read_file_mbed_htm(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors); 00126 static uint32_t read_file_details_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors); 00127 static uint32_t read_file_fail_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors); 00128 static uint32_t read_file_assert_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors); 00129 static uint32_t read_file_need_bl_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors); 00130 00131 static uint32_t update_html_file(uint8_t *data, uint32_t datasize); 00132 static uint32_t update_details_txt_file(uint8_t *data, uint32_t datasize); 00133 static void erase_target(void); 00134 00135 static uint32_t expand_info(uint8_t *buf, uint32_t bufsize); 00136 00137 void vfs_user_build_filesystem() 00138 { 00139 uint32_t file_size; 00140 vfs_file_t file_handle; 00141 // Setup the filesystem based on target parameters 00142 vfs_init(get_daplink_drive_name(), VFS_DISK_SIZE); 00143 // MBED.HTM 00144 file_size = get_file_size(read_file_mbed_htm); 00145 vfs_create_file(get_daplink_url_name(), read_file_mbed_htm, 0, file_size); 00146 // DETAILS.TXT 00147 file_size = get_file_size(read_file_details_txt); 00148 vfs_create_file("DETAILS TXT", read_file_details_txt, 0, file_size); 00149 00150 // FAIL.TXT 00151 if (vfs_mngr_get_transfer_status() != ERROR_SUCCESS) { 00152 file_size = get_file_size(read_file_fail_txt); 00153 vfs_create_file("FAIL TXT", read_file_fail_txt, 0, file_size); 00154 } 00155 00156 // ASSERT.TXT 00157 if (config_ram_get_assert(assert_buf, sizeof(assert_buf), &assert_line, &assert_source)) { 00158 file_size = get_file_size(read_file_assert_txt); 00159 file_handle = vfs_create_file(assert_file, read_file_assert_txt, 0, file_size); 00160 vfs_file_set_attr(file_handle, (vfs_file_attr_bit_t)0); // Remove read only attribute 00161 } 00162 00163 // NEED_BL.TXT 00164 volatile uint32_t bl_start = DAPLINK_ROM_BL_START; // Silence warnings about null pointer 00165 volatile uint32_t if_start = DAPLINK_ROM_IF_START; // Silence warnings about null pointer 00166 00167 if (daplink_is_interface() && 00168 (DAPLINK_ROM_BL_SIZE > 0) && 00169 (0 == memcmp((void *)bl_start, (void *)if_start, DAPLINK_MIN_WRITE_SIZE))) { 00170 // If the bootloader contains a copy of the interfaces vector table 00171 // then an error occurred when updating so warn that the bootloader is 00172 // missing. 00173 file_size = get_file_size(read_file_need_bl_txt); 00174 vfs_create_file("NEED_BL TXT", read_file_need_bl_txt, 0, file_size); 00175 } 00176 } 00177 00178 // Default file change hook. 00179 __WEAK bool vfs_user_file_change_handler_hook(const vfs_filename_t filename, vfs_file_change_t change, 00180 vfs_file_t file, vfs_file_t new_file_data) 00181 { 00182 return false; 00183 } 00184 00185 // Default magic file hook. 00186 __WEAK bool vfs_user_magic_file_hook(const vfs_filename_t filename, bool *do_remount) 00187 { 00188 return false; 00189 } 00190 00191 // Callback to handle changes to the root directory. Should be used with vfs_set_file_change_callback 00192 void vfs_user_file_change_handler(const vfs_filename_t filename, vfs_file_change_t change, vfs_file_t file, vfs_file_t new_file_data) 00193 { 00194 // Call file changed hook. If it returns true, then it handled the request and we have nothing 00195 // more to do. 00196 if (vfs_user_file_change_handler_hook(filename, change, file, new_file_data)) { 00197 return; 00198 } 00199 00200 // Allow settings to be changed if automation mode is 00201 // enabled or if the user is holding the reset button 00202 bool btn_pressed = gpio_get_reset_btn(); 00203 00204 if (!btn_pressed && !config_get_automation_allowed()) { 00205 return; 00206 } 00207 00208 if (VFS_FILE_CHANGED == change) { 00209 // Unused 00210 } 00211 00212 else if (VFS_FILE_CREATED == change) { 00213 bool do_remount = true; // Almost all magic files cause a remount. 00214 int32_t which_magic_file = -1; 00215 00216 // Let the hook examine the filename. If it returned false then look for the standard 00217 // magic files. 00218 if (!vfs_user_magic_file_hook(filename, &do_remount)) { 00219 // Compare the new file's name to our table of magic filenames. 00220 for (int32_t i = 0; i < ARRAY_SIZE(s_magic_file_info); ++i) { 00221 if (!memcmp(filename, s_magic_file_info[i].name, sizeof(vfs_filename_t))) { 00222 which_magic_file = i; 00223 } 00224 } 00225 00226 // Check if we matched a magic filename and handle it. 00227 if (which_magic_file != -1) { 00228 switch (which_magic_file) { 00229 case kDAPLinkModeActionFile: 00230 if (daplink_is_interface()) { 00231 config_ram_set_hold_in_bl(true); 00232 } else { 00233 // Do nothing - bootloader will go to interface by default 00234 } 00235 break; 00236 case kTestAssertActionFile: 00237 // Test asserts 00238 util_assert(0); 00239 do_remount = false; 00240 break; 00241 case kRefreshActionFile: 00242 // Remount to update the drive 00243 break; 00244 case kEraseActionFile: 00245 erase_target(); 00246 break; 00247 case kAutoResetConfigFile: 00248 config_set_auto_rst(true); 00249 break; 00250 case kHardResetConfigFile: 00251 config_set_auto_rst(false); 00252 break; 00253 case kAutomationOnConfigFile: 00254 config_set_automation_allowed(true); 00255 break; 00256 case kAutomationOffConfigFile: 00257 config_set_automation_allowed(false); 00258 break; 00259 case kOverflowOnConfigFile: 00260 config_set_overflow_detect(true); 00261 break; 00262 case kOverflowOffConfigFile: 00263 config_set_overflow_detect(false); 00264 break; 00265 case kMSDOnConfigFile: 00266 config_ram_set_disable_msd(false); 00267 break; 00268 case kMSDOffConfigFile: 00269 config_ram_set_disable_msd(true); 00270 break; 00271 case kPageEraseActionFile: 00272 config_ram_set_page_erase(true); 00273 break; 00274 case kChipEraseActionFile: 00275 config_ram_set_page_erase(false); 00276 break; 00277 default: 00278 util_assert(false); 00279 } 00280 } 00281 else { 00282 do_remount = false; 00283 } 00284 } 00285 00286 // Remount if requested. 00287 if (do_remount) { 00288 vfs_mngr_fs_remount(); 00289 } 00290 } 00291 00292 else if (VFS_FILE_DELETED == change) { 00293 if (!memcmp(filename, assert_file, sizeof(vfs_filename_t))) { 00294 // Clear assert and remount to update the drive 00295 util_assert_clear(); 00296 vfs_mngr_fs_remount(); 00297 } 00298 } 00299 } 00300 00301 void vfs_user_disconnecting() 00302 { 00303 // Reset if programming was successful //TODO - move to flash layer 00304 if (daplink_is_bootloader() && (ERROR_SUCCESS == vfs_mngr_get_transfer_status())) { 00305 SystemReset(); 00306 } 00307 00308 // If hold in bootloader has been set then reset after usb is disconnected 00309 if (daplink_is_interface() && (config_ram_get_hold_in_bl() || config_ram_get_disable_msd()==1)) { 00310 SystemReset(); 00311 } 00312 00313 remount_count++; 00314 } 00315 00316 // Get the filesize from a filesize callback. 00317 // The file data must be null terminated for this to work correctly. 00318 static uint32_t get_file_size(vfs_read_cb_t read_func) 00319 { 00320 // Determine size of the file by faking a read 00321 return read_func(0, file_buffer, 1); 00322 } 00323 00324 // File callback to be used with vfs_add_file to return file contents 00325 static uint32_t read_file_mbed_htm(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors) 00326 { 00327 if (sector_offset != 0) { 00328 return 0; 00329 } 00330 00331 return update_html_file(data, VFS_SECTOR_SIZE); 00332 } 00333 00334 // File callback to be used with vfs_add_file to return file contents 00335 static uint32_t read_file_details_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors) 00336 { 00337 00338 if (sector_offset != 0) { 00339 return 0; 00340 } 00341 00342 return update_details_txt_file(data, VFS_SECTOR_SIZE); 00343 } 00344 00345 // Text representation of each error type, starting from the rightmost bit 00346 static const char* const error_type_names[] = { 00347 "internal", 00348 "transient", 00349 "user", 00350 "target", 00351 "interface" 00352 }; 00353 00354 COMPILER_ASSERT(1 << ARRAY_SIZE(error_type_names) == ERROR_TYPE_MASK + 1); 00355 00356 // File callback to be used with vfs_add_file to return file contents 00357 static uint32_t read_file_fail_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors) 00358 { 00359 uint32_t size = 0; 00360 char *buf = (char *)data; 00361 error_t status = vfs_mngr_get_transfer_status(); 00362 const char *contents = error_get_string(status); 00363 error_type_t type = error_get_type(status); 00364 00365 if (sector_offset != 0) { 00366 return 0; 00367 } 00368 00369 size += util_write_string(buf + size, error_prefix); 00370 size += util_write_string(buf + size, contents); 00371 size += util_write_string(buf + size, "\r\n"); 00372 size += util_write_string(buf + size, error_type_prefix); 00373 00374 // Write each applicable error type, separated by commas 00375 int index = 0; 00376 bool first = true; 00377 while (type && index < ARRAY_SIZE(error_type_names)) { 00378 if (!first) { 00379 size += util_write_string(buf + size, ", "); 00380 } 00381 if (type & 1) { 00382 size += util_write_string(buf + size, error_type_names[index]); 00383 first = false; 00384 } 00385 index++; 00386 type >>= 1; 00387 } 00388 00389 size += util_write_string(buf + size, "\r\n"); 00390 return size; 00391 } 00392 00393 // File callback to be used with vfs_add_file to return file contents 00394 static uint32_t read_file_assert_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors) 00395 { 00396 uint32_t pos; 00397 const char *source_str; 00398 char *buf = (char *)data; 00399 uint32_t * hexdumps = 0; 00400 uint8_t valid_hexdumps = 0; 00401 uint8_t index = 0; 00402 00403 if (sector_offset != 0) { 00404 return 0; 00405 } 00406 00407 pos = 0; 00408 00409 if (ASSERT_SOURCE_BL == assert_source) { 00410 source_str = "Bootloader"; 00411 } else if (ASSERT_SOURCE_APP == assert_source) { 00412 source_str = "Application"; 00413 } else { 00414 source_str = 0; 00415 } 00416 00417 pos += util_write_string(buf + pos, "Assert\r\n"); 00418 pos += util_write_string(buf + pos, "File: "); 00419 pos += util_write_string(buf + pos, assert_buf); 00420 pos += util_write_string(buf + pos, "\r\n"); 00421 pos += util_write_string(buf + pos, "Line: "); 00422 pos += util_write_uint32(buf + pos, assert_line); 00423 pos += util_write_string(buf + pos, "\r\n"); 00424 00425 if (source_str != 0) { 00426 pos += util_write_string(buf + pos, "Source: "); 00427 pos += util_write_string(buf + pos, source_str); 00428 pos += util_write_string(buf + pos, "\r\n"); 00429 } 00430 00431 valid_hexdumps = config_ram_get_hexdumps(&hexdumps); 00432 if ((valid_hexdumps > 0) && (hexdumps != 0)) { 00433 //print hexdumps 00434 pos += util_write_string(buf + pos, "Hexdumps\r\n"); 00435 while ((index < valid_hexdumps) && ((pos + 10) < VFS_SECTOR_SIZE)) { //hexdumps + newline is always 10 characters 00436 pos += util_write_hex32(buf + pos, hexdumps[index++]); 00437 pos += util_write_string(buf + pos, "\r\n"); 00438 } 00439 } 00440 00441 return pos; 00442 } 00443 00444 // File callback to be used with vfs_add_file to return file contents 00445 static uint32_t read_file_need_bl_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors) 00446 { 00447 const char *contents = "A bootloader update was started but unable to complete.\r\n" 00448 "Reload the bootloader to fix this error message.\r\n"; 00449 uint32_t size = strlen(contents); 00450 00451 if (sector_offset != 0) { 00452 return 0; 00453 } 00454 00455 memcpy(data, contents, size); 00456 return size; 00457 } 00458 00459 00460 static uint32_t update_html_file(uint8_t *data, uint32_t datasize) 00461 { 00462 char *buf = (char *)data; 00463 //Needed by expand_info strlen 00464 memset(buf, 0, datasize); 00465 memcpy(buf, mbed_redirect_file, strlen(mbed_redirect_file)); 00466 //expand 00467 return expand_info(data, datasize); 00468 } 00469 00470 static uint32_t update_details_txt_file(uint8_t *data, uint32_t datasize) 00471 { 00472 uint32_t pos=0; 00473 const char *mode_str; 00474 00475 char *buf = (char *)data; 00476 00477 //Needed by expand_info strlen 00478 memset(buf, 0, datasize); 00479 00480 pos += util_write_string(buf + pos, "# DAPLink Firmware - see https://mbed.com/daplink\r\n"); 00481 // Unique ID 00482 pos += util_write_string(buf + pos, "Unique ID: @U\r\n"); 00483 // HIC ID 00484 pos += util_write_string(buf + pos, "HIC ID: @D\r\n"); 00485 // Settings 00486 pos += util_write_string(buf + pos, "Auto Reset: "); 00487 pos += util_write_string(buf + pos, config_get_auto_rst() ? "1" : "0"); 00488 pos += util_write_string(buf + pos, "\r\n"); 00489 pos += util_write_string(buf + pos, "Automation allowed: "); 00490 pos += util_write_string(buf + pos, config_get_automation_allowed() ? "1" : "0"); 00491 pos += util_write_string(buf + pos, "\r\n"); 00492 pos += util_write_string(buf + pos, "Overflow detection: "); 00493 pos += util_write_string(buf + pos, config_get_overflow_detect() ? "1" : "0"); 00494 pos += util_write_string(buf + pos, "\r\n"); 00495 pos += util_write_string(buf + pos, "Page erasing: "); 00496 pos += util_write_string(buf + pos, config_ram_get_page_erase() ? "1" : "0"); 00497 pos += util_write_string(buf + pos, "\r\n"); 00498 // Current mode 00499 mode_str = daplink_is_bootloader() ? "Bootloader" : "Interface"; 00500 pos += util_write_string(buf + pos, "Daplink Mode: "); 00501 pos += util_write_string(buf + pos, mode_str); 00502 pos += util_write_string(buf + pos, "\r\n"); 00503 // Current build's version 00504 pos += util_write_string(buf + pos, mode_str); 00505 pos += util_write_string(buf + pos, " Version: @V\r\n"); 00506 00507 // Other builds version (bl or if) 00508 if (!daplink_is_bootloader() && info_get_bootloader_present()) { 00509 pos += util_write_string(buf + pos, "Bootloader Version: "); 00510 pos += util_write_uint32_zp(buf + pos, info_get_bootloader_version(), 4); 00511 pos += util_write_string(buf + pos, "\r\n"); 00512 } 00513 00514 if (!daplink_is_interface() && info_get_interface_present()) { 00515 pos += util_write_string(buf + pos, "Interface Version: "); 00516 pos += util_write_uint32_zp(buf + pos, info_get_interface_version(), 4); 00517 pos += util_write_string(buf + pos, "\r\n"); 00518 } 00519 00520 // GIT sha 00521 pos += util_write_string(buf + pos, "Git SHA: "); 00522 pos += util_write_string(buf + pos, GIT_COMMIT_SHA); 00523 pos += util_write_string(buf + pos, "\r\n"); 00524 // Local modifications when making the build 00525 pos += util_write_string(buf + pos, "Local Mods: "); 00526 pos += util_write_uint32(buf + pos, GIT_LOCAL_MODS); 00527 pos += util_write_string(buf + pos, "\r\n"); 00528 // Supported USB endpoints 00529 pos += util_write_string(buf + pos, "USB Interfaces: "); 00530 #ifdef MSC_ENDPOINT 00531 pos += util_write_string(buf + pos, "MSD"); 00532 #endif 00533 #ifdef CDC_ENDPOINT 00534 pos += util_write_string(buf + pos, ", CDC"); 00535 #endif 00536 #ifdef HID_ENDPOINT 00537 pos += util_write_string(buf + pos, ", HID"); 00538 #endif 00539 #if (WEBUSB_INTERFACE) 00540 pos += util_write_string(buf + pos, ", WebUSB"); 00541 #endif 00542 pos += util_write_string(buf + pos, "\r\n"); 00543 00544 // CRC of the bootloader (if there is one) 00545 if (info_get_bootloader_present()) { 00546 pos += util_write_string(buf + pos, "Bootloader CRC: 0x"); 00547 pos += util_write_hex32(buf + pos, info_get_crc_bootloader()); 00548 pos += util_write_string(buf + pos, "\r\n"); 00549 } 00550 00551 // CRC of the interface 00552 pos += util_write_string(buf + pos, "Interface CRC: 0x"); 00553 pos += util_write_hex32(buf + pos, info_get_crc_interface()); 00554 pos += util_write_string(buf + pos, "\r\n"); 00555 00556 // Number of remounts that have occurred 00557 pos += util_write_string(buf + pos, "Remount count: "); 00558 pos += util_write_uint32(buf + pos, remount_count); 00559 pos += util_write_string(buf + pos, "\r\n"); 00560 00561 //Target URL 00562 pos += util_write_string(buf + pos, "URL: @R\r\n"); 00563 00564 return expand_info(data, datasize); 00565 } 00566 00567 // Fill buf with the contents of the mbed redirect file by 00568 // expanding the special characters in mbed_redirect_file. 00569 static uint32_t expand_info(uint8_t *buf, uint32_t bufsize) 00570 { 00571 uint8_t *orig_buf = buf; 00572 uint8_t *insert_string; 00573 00574 do { 00575 // Look for key or the end of the string 00576 while ((*buf != '@') && (*buf != 0)) { 00577 buf++; 00578 } 00579 00580 // If key was found then replace it 00581 if ('@' == *buf) { 00582 switch (*(buf + 1)) { 00583 case 'm': 00584 case 'M': // MAC address 00585 insert_string = (uint8_t *)info_get_mac(); 00586 break; 00587 00588 case 'u': 00589 case 'U': // UUID 00590 insert_string = (uint8_t *)info_get_unique_id(); 00591 break; 00592 00593 case 'b': 00594 case 'B': // Board ID 00595 insert_string = (uint8_t *)info_get_board_id(); 00596 break; 00597 00598 case 'h': 00599 case 'H': // Host ID 00600 insert_string = (uint8_t *)info_get_host_id(); 00601 break; 00602 00603 case 't': 00604 case 'T': // Target ID 00605 insert_string = (uint8_t *)info_get_target_id(); 00606 break; 00607 00608 case 'd': 00609 case 'D': // HIC 00610 insert_string = (uint8_t *)info_get_hic_id(); 00611 break; 00612 00613 case 'v': 00614 case 'V': // Firmware version 00615 insert_string = (uint8_t *)info_get_version(); 00616 break; 00617 00618 case 'r': 00619 case 'R': // URL replacement 00620 insert_string = (uint8_t *)get_daplink_target_url(); 00621 break; 00622 00623 default: 00624 insert_string = (uint8_t *)"ERROR"; 00625 break; 00626 } 00627 00628 // Remove strip_count characters from the start of buf and then insert 00629 // insert_string at the new start of buf. 00630 uint32_t buf_len = strlen((const char *)buf); 00631 uint32_t str_len = strlen((const char *)insert_string); 00632 //buffer overflow check on insert 00633 if( (buf + str_len + buf_len - 2) < (orig_buf+bufsize)){ 00634 // push out string 00635 memmove(buf + str_len, buf + 2, buf_len - 2); 00636 // insert 00637 memcpy(buf, insert_string, str_len); 00638 }else{ 00639 //stop the string expansion and leave as it is 00640 buf += buf_len; 00641 break; 00642 } 00643 00644 } 00645 } while (*buf != '\0'); 00646 00647 return (buf - orig_buf); 00648 } 00649 00650 // Initialize flash algo, erase flash, uninit algo 00651 static void erase_target(void) 00652 { 00653 flash_intf_target->init(); 00654 flash_intf_target->erase_chip(); 00655 flash_intf_target->uninit(); 00656 }
Generated on Tue Jul 12 2022 15:37:27 by
1.7.2