Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pawel Zarembski 0:01f31e923fe2 1 /**
Pawel Zarembski 0:01f31e923fe2 2 * @file vfs_user.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief Implementation of vfs_user.h
Pawel Zarembski 0:01f31e923fe2 4 *
Pawel Zarembski 0:01f31e923fe2 5 * DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 6 * Copyright (c) 2009-2020, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 7 * Copyright 2019, Cypress Semiconductor Corporation
Pawel Zarembski 0:01f31e923fe2 8 * or a subsidiary of Cypress Semiconductor Corporation.
Pawel Zarembski 0:01f31e923fe2 9 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 10 *
Pawel Zarembski 0:01f31e923fe2 11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 12 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 13 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 14 *
Pawel Zarembski 0:01f31e923fe2 15 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 16 *
Pawel Zarembski 0:01f31e923fe2 17 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 18 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 19 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 20 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 21 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 22 */
Pawel Zarembski 0:01f31e923fe2 23
Pawel Zarembski 0:01f31e923fe2 24 #include <stdbool.h>
Pawel Zarembski 0:01f31e923fe2 25 #include <ctype.h>
Pawel Zarembski 0:01f31e923fe2 26 #include <string.h>
Pawel Zarembski 0:01f31e923fe2 27
Pawel Zarembski 0:01f31e923fe2 28 #include "vfs_user.h"
Pawel Zarembski 0:01f31e923fe2 29 #include "vfs_manager.h"
Pawel Zarembski 0:01f31e923fe2 30 #include "error.h"
Pawel Zarembski 0:01f31e923fe2 31 #include "util.h"
Pawel Zarembski 0:01f31e923fe2 32 #include "settings.h"
Pawel Zarembski 0:01f31e923fe2 33 #include "daplink.h"
Pawel Zarembski 0:01f31e923fe2 34 #include "version_git.h"
Pawel Zarembski 0:01f31e923fe2 35 #include "info.h"
Pawel Zarembski 0:01f31e923fe2 36 #include "gpio.h" // for gpio_get_sw_reset
Pawel Zarembski 0:01f31e923fe2 37 #include "flash_intf.h" // for flash_intf_target
Pawel Zarembski 0:01f31e923fe2 38 #include "cortex_m.h"
Pawel Zarembski 0:01f31e923fe2 39 #include "target_board.h"
Pawel Zarembski 0:01f31e923fe2 40 #include "flash_manager.h"
Pawel Zarembski 0:01f31e923fe2 41
Pawel Zarembski 0:01f31e923fe2 42 //! @brief Size in bytes of the virtual disk.
Pawel Zarembski 0:01f31e923fe2 43 //!
Pawel Zarembski 0:01f31e923fe2 44 //! Must be bigger than 4x the flash size of the biggest supported
Pawel Zarembski 0:01f31e923fe2 45 //! device. This is to accomodate for hex file programming.
Pawel Zarembski 0:01f31e923fe2 46 #define VFS_DISK_SIZE (MB(64))
Pawel Zarembski 0:01f31e923fe2 47
Pawel Zarembski 0:01f31e923fe2 48 //! @brief Constants for magic action or config files.
Pawel Zarembski 0:01f31e923fe2 49 //!
Pawel Zarembski 0:01f31e923fe2 50 //! The "magic files" are files with a special name that if created on the USB MSC volume, will
Pawel Zarembski 0:01f31e923fe2 51 //! cause an event. There are two classes of magic files: action files and config files. The former
Pawel Zarembski 0:01f31e923fe2 52 //! causes a given action to take place, while the latter changes a persistent configuration setting
Pawel Zarembski 0:01f31e923fe2 53 //! to a predetermined value.
Pawel Zarembski 0:01f31e923fe2 54 //!
Pawel Zarembski 0:01f31e923fe2 55 //! See #s_magic_file_info for the mapping of filenames to these enums.
Pawel Zarembski 0:01f31e923fe2 56 typedef enum _magic_file {
Pawel Zarembski 0:01f31e923fe2 57 kDAPLinkModeActionFile, //!< Switch between interface and bootloader.
Pawel Zarembski 0:01f31e923fe2 58 kTestAssertActionFile, //!< Force an assertion for testing.
Pawel Zarembski 0:01f31e923fe2 59 kRefreshActionFile, //!< Force a remount.
Pawel Zarembski 0:01f31e923fe2 60 kEraseActionFile, //!< Erase the target flash.
Pawel Zarembski 0:01f31e923fe2 61 kAutoResetConfigFile, //!< Enable reset after flash.
Pawel Zarembski 0:01f31e923fe2 62 kHardResetConfigFile, //!< Disable reset after flash.
Pawel Zarembski 0:01f31e923fe2 63 kAutomationOnConfigFile, //!< Enable automation.
Pawel Zarembski 0:01f31e923fe2 64 kAutomationOffConfigFile, //!< Disable automation.
Pawel Zarembski 0:01f31e923fe2 65 kOverflowOnConfigFile, //!< Enable UART overflow reporting.
Pawel Zarembski 0:01f31e923fe2 66 kOverflowOffConfigFile, //!< Disable UART overflow reporting.
Pawel Zarembski 0:01f31e923fe2 67 kMSDOnConfigFile, //!< Enable USB MSC. Uh....
Pawel Zarembski 0:01f31e923fe2 68 kMSDOffConfigFile, //!< Disable USB MSC.
Pawel Zarembski 0:01f31e923fe2 69 kPageEraseActionFile, //!< Enable page programming and sector erase for drag and drop.
Pawel Zarembski 0:01f31e923fe2 70 kChipEraseActionFile, //!< Enable page programming and chip erase for drag and drop.
Pawel Zarembski 0:01f31e923fe2 71 } magic_file_t;
Pawel Zarembski 0:01f31e923fe2 72
Pawel Zarembski 0:01f31e923fe2 73 //! @brief Mapping from filename string to magic file enum.
Pawel Zarembski 0:01f31e923fe2 74 typedef struct _magic_file_info {
Pawel Zarembski 0:01f31e923fe2 75 const char *name; //!< Name of the magic file, must be in 8.3 format.
Pawel Zarembski 0:01f31e923fe2 76 magic_file_t which; //!< Enum for the file.
Pawel Zarembski 0:01f31e923fe2 77 } magic_file_info_t;
Pawel Zarembski 0:01f31e923fe2 78
Pawel Zarembski 0:01f31e923fe2 79 static const char mbed_redirect_file[] =
Pawel Zarembski 0:01f31e923fe2 80 "<!doctype html>\r\n"
Pawel Zarembski 0:01f31e923fe2 81 "<!-- mbed Platform Website and Authentication Shortcut -->\r\n"
Pawel Zarembski 0:01f31e923fe2 82 "<html>\r\n"
Pawel Zarembski 0:01f31e923fe2 83 "<head>\r\n"
Pawel Zarembski 0:01f31e923fe2 84 "<meta charset=\"utf-8\">\r\n"
Pawel Zarembski 0:01f31e923fe2 85 "<title>mbed Website Shortcut</title>\r\n"
Pawel Zarembski 0:01f31e923fe2 86 "</head>\r\n"
Pawel Zarembski 0:01f31e923fe2 87 "<body>\r\n"
Pawel Zarembski 0:01f31e923fe2 88 "<script>\r\n"
Pawel Zarembski 0:01f31e923fe2 89 "window.location.replace(\"@R\");\r\n"
Pawel Zarembski 0:01f31e923fe2 90 "</script>\r\n"
Pawel Zarembski 0:01f31e923fe2 91 "</body>\r\n"
Pawel Zarembski 0:01f31e923fe2 92 "</html>\r\n";
Pawel Zarembski 0:01f31e923fe2 93
Pawel Zarembski 0:01f31e923fe2 94 static const char error_prefix[] = "error: ";
Pawel Zarembski 0:01f31e923fe2 95 static const char error_type_prefix[] = "type: ";
Pawel Zarembski 0:01f31e923fe2 96
Pawel Zarembski 0:01f31e923fe2 97 static const vfs_filename_t assert_file = "ASSERT TXT";
Pawel Zarembski 0:01f31e923fe2 98
Pawel Zarembski 0:01f31e923fe2 99 //! @brief Table of magic files and their names.
Pawel Zarembski 0:01f31e923fe2 100 static const magic_file_info_t s_magic_file_info[] = {
Pawel Zarembski 0:01f31e923fe2 101 { daplink_mode_file_name, kDAPLinkModeActionFile },
Pawel Zarembski 0:01f31e923fe2 102 { "ASSERT ACT", kTestAssertActionFile },
Pawel Zarembski 0:01f31e923fe2 103 { "REFRESH ACT", kRefreshActionFile },
Pawel Zarembski 0:01f31e923fe2 104 { "ERASE ACT", kEraseActionFile },
Pawel Zarembski 0:01f31e923fe2 105 { "AUTO_RSTCFG", kAutoResetConfigFile },
Pawel Zarembski 0:01f31e923fe2 106 { "HARD_RSTCFG", kHardResetConfigFile },
Pawel Zarembski 0:01f31e923fe2 107 { "AUTO_ON CFG", kAutomationOnConfigFile },
Pawel Zarembski 0:01f31e923fe2 108 { "AUTO_OFFCFG", kAutomationOffConfigFile },
Pawel Zarembski 0:01f31e923fe2 109 { "OVFL_ON CFG", kOverflowOnConfigFile },
Pawel Zarembski 0:01f31e923fe2 110 { "OVFL_OFFCFG", kOverflowOffConfigFile },
Pawel Zarembski 0:01f31e923fe2 111 { "MSD_ON CFG", kMSDOnConfigFile },
Pawel Zarembski 0:01f31e923fe2 112 { "MSD_OFF CFG", kMSDOffConfigFile },
Pawel Zarembski 0:01f31e923fe2 113 { "PAGE_ON ACT", kPageEraseActionFile },
Pawel Zarembski 0:01f31e923fe2 114 { "PAGE_OFFACT", kChipEraseActionFile },
Pawel Zarembski 0:01f31e923fe2 115 };
Pawel Zarembski 0:01f31e923fe2 116
Pawel Zarembski 0:01f31e923fe2 117 static uint8_t file_buffer[VFS_SECTOR_SIZE];
Pawel Zarembski 0:01f31e923fe2 118 static char assert_buf[64 + 1];
Pawel Zarembski 0:01f31e923fe2 119 static uint16_t assert_line;
Pawel Zarembski 0:01f31e923fe2 120 static assert_source_t assert_source;
Pawel Zarembski 0:01f31e923fe2 121 static uint32_t remount_count;
Pawel Zarembski 0:01f31e923fe2 122
Pawel Zarembski 0:01f31e923fe2 123 static uint32_t get_file_size(vfs_read_cb_t read_func);
Pawel Zarembski 0:01f31e923fe2 124
Pawel Zarembski 0:01f31e923fe2 125 static uint32_t read_file_mbed_htm(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors);
Pawel Zarembski 0:01f31e923fe2 126 static uint32_t read_file_details_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors);
Pawel Zarembski 0:01f31e923fe2 127 static uint32_t read_file_fail_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors);
Pawel Zarembski 0:01f31e923fe2 128 static uint32_t read_file_assert_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors);
Pawel Zarembski 0:01f31e923fe2 129 static uint32_t read_file_need_bl_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors);
Pawel Zarembski 0:01f31e923fe2 130
Pawel Zarembski 0:01f31e923fe2 131 static uint32_t update_html_file(uint8_t *data, uint32_t datasize);
Pawel Zarembski 0:01f31e923fe2 132 static uint32_t update_details_txt_file(uint8_t *data, uint32_t datasize);
Pawel Zarembski 0:01f31e923fe2 133 static void erase_target(void);
Pawel Zarembski 0:01f31e923fe2 134
Pawel Zarembski 0:01f31e923fe2 135 static uint32_t expand_info(uint8_t *buf, uint32_t bufsize);
Pawel Zarembski 0:01f31e923fe2 136
Pawel Zarembski 0:01f31e923fe2 137 void vfs_user_build_filesystem()
Pawel Zarembski 0:01f31e923fe2 138 {
Pawel Zarembski 0:01f31e923fe2 139 uint32_t file_size;
Pawel Zarembski 0:01f31e923fe2 140 vfs_file_t file_handle;
Pawel Zarembski 0:01f31e923fe2 141 // Setup the filesystem based on target parameters
Pawel Zarembski 0:01f31e923fe2 142 vfs_init(get_daplink_drive_name(), VFS_DISK_SIZE);
Pawel Zarembski 0:01f31e923fe2 143 // MBED.HTM
Pawel Zarembski 0:01f31e923fe2 144 file_size = get_file_size(read_file_mbed_htm);
Pawel Zarembski 0:01f31e923fe2 145 vfs_create_file(get_daplink_url_name(), read_file_mbed_htm, 0, file_size);
Pawel Zarembski 0:01f31e923fe2 146 // DETAILS.TXT
Pawel Zarembski 0:01f31e923fe2 147 file_size = get_file_size(read_file_details_txt);
Pawel Zarembski 0:01f31e923fe2 148 vfs_create_file("DETAILS TXT", read_file_details_txt, 0, file_size);
Pawel Zarembski 0:01f31e923fe2 149
Pawel Zarembski 0:01f31e923fe2 150 // FAIL.TXT
Pawel Zarembski 0:01f31e923fe2 151 if (vfs_mngr_get_transfer_status() != ERROR_SUCCESS) {
Pawel Zarembski 0:01f31e923fe2 152 file_size = get_file_size(read_file_fail_txt);
Pawel Zarembski 0:01f31e923fe2 153 vfs_create_file("FAIL TXT", read_file_fail_txt, 0, file_size);
Pawel Zarembski 0:01f31e923fe2 154 }
Pawel Zarembski 0:01f31e923fe2 155
Pawel Zarembski 0:01f31e923fe2 156 // ASSERT.TXT
Pawel Zarembski 0:01f31e923fe2 157 if (config_ram_get_assert(assert_buf, sizeof(assert_buf), &assert_line, &assert_source)) {
Pawel Zarembski 0:01f31e923fe2 158 file_size = get_file_size(read_file_assert_txt);
Pawel Zarembski 0:01f31e923fe2 159 file_handle = vfs_create_file(assert_file, read_file_assert_txt, 0, file_size);
Pawel Zarembski 0:01f31e923fe2 160 vfs_file_set_attr(file_handle, (vfs_file_attr_bit_t)0); // Remove read only attribute
Pawel Zarembski 0:01f31e923fe2 161 }
Pawel Zarembski 0:01f31e923fe2 162
Pawel Zarembski 0:01f31e923fe2 163 // NEED_BL.TXT
Pawel Zarembski 0:01f31e923fe2 164 volatile uint32_t bl_start = DAPLINK_ROM_BL_START; // Silence warnings about null pointer
Pawel Zarembski 0:01f31e923fe2 165 volatile uint32_t if_start = DAPLINK_ROM_IF_START; // Silence warnings about null pointer
Pawel Zarembski 0:01f31e923fe2 166
Pawel Zarembski 0:01f31e923fe2 167 if (daplink_is_interface() &&
Pawel Zarembski 0:01f31e923fe2 168 (DAPLINK_ROM_BL_SIZE > 0) &&
Pawel Zarembski 0:01f31e923fe2 169 (0 == memcmp((void *)bl_start, (void *)if_start, DAPLINK_MIN_WRITE_SIZE))) {
Pawel Zarembski 0:01f31e923fe2 170 // If the bootloader contains a copy of the interfaces vector table
Pawel Zarembski 0:01f31e923fe2 171 // then an error occurred when updating so warn that the bootloader is
Pawel Zarembski 0:01f31e923fe2 172 // missing.
Pawel Zarembski 0:01f31e923fe2 173 file_size = get_file_size(read_file_need_bl_txt);
Pawel Zarembski 0:01f31e923fe2 174 vfs_create_file("NEED_BL TXT", read_file_need_bl_txt, 0, file_size);
Pawel Zarembski 0:01f31e923fe2 175 }
Pawel Zarembski 0:01f31e923fe2 176 }
Pawel Zarembski 0:01f31e923fe2 177
Pawel Zarembski 0:01f31e923fe2 178 // Default file change hook.
Pawel Zarembski 0:01f31e923fe2 179 __WEAK bool vfs_user_file_change_handler_hook(const vfs_filename_t filename, vfs_file_change_t change,
Pawel Zarembski 0:01f31e923fe2 180 vfs_file_t file, vfs_file_t new_file_data)
Pawel Zarembski 0:01f31e923fe2 181 {
Pawel Zarembski 0:01f31e923fe2 182 return false;
Pawel Zarembski 0:01f31e923fe2 183 }
Pawel Zarembski 0:01f31e923fe2 184
Pawel Zarembski 0:01f31e923fe2 185 // Default magic file hook.
Pawel Zarembski 0:01f31e923fe2 186 __WEAK bool vfs_user_magic_file_hook(const vfs_filename_t filename, bool *do_remount)
Pawel Zarembski 0:01f31e923fe2 187 {
Pawel Zarembski 0:01f31e923fe2 188 return false;
Pawel Zarembski 0:01f31e923fe2 189 }
Pawel Zarembski 0:01f31e923fe2 190
Pawel Zarembski 0:01f31e923fe2 191 // Callback to handle changes to the root directory. Should be used with vfs_set_file_change_callback
Pawel Zarembski 0:01f31e923fe2 192 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)
Pawel Zarembski 0:01f31e923fe2 193 {
Pawel Zarembski 0:01f31e923fe2 194 // Call file changed hook. If it returns true, then it handled the request and we have nothing
Pawel Zarembski 0:01f31e923fe2 195 // more to do.
Pawel Zarembski 0:01f31e923fe2 196 if (vfs_user_file_change_handler_hook(filename, change, file, new_file_data)) {
Pawel Zarembski 0:01f31e923fe2 197 return;
Pawel Zarembski 0:01f31e923fe2 198 }
Pawel Zarembski 0:01f31e923fe2 199
Pawel Zarembski 0:01f31e923fe2 200 // Allow settings to be changed if automation mode is
Pawel Zarembski 0:01f31e923fe2 201 // enabled or if the user is holding the reset button
Pawel Zarembski 0:01f31e923fe2 202 bool btn_pressed = gpio_get_reset_btn();
Pawel Zarembski 0:01f31e923fe2 203
Pawel Zarembski 0:01f31e923fe2 204 if (!btn_pressed && !config_get_automation_allowed()) {
Pawel Zarembski 0:01f31e923fe2 205 return;
Pawel Zarembski 0:01f31e923fe2 206 }
Pawel Zarembski 0:01f31e923fe2 207
Pawel Zarembski 0:01f31e923fe2 208 if (VFS_FILE_CHANGED == change) {
Pawel Zarembski 0:01f31e923fe2 209 // Unused
Pawel Zarembski 0:01f31e923fe2 210 }
Pawel Zarembski 0:01f31e923fe2 211
Pawel Zarembski 0:01f31e923fe2 212 else if (VFS_FILE_CREATED == change) {
Pawel Zarembski 0:01f31e923fe2 213 bool do_remount = true; // Almost all magic files cause a remount.
Pawel Zarembski 0:01f31e923fe2 214 int32_t which_magic_file = -1;
Pawel Zarembski 0:01f31e923fe2 215
Pawel Zarembski 0:01f31e923fe2 216 // Let the hook examine the filename. If it returned false then look for the standard
Pawel Zarembski 0:01f31e923fe2 217 // magic files.
Pawel Zarembski 0:01f31e923fe2 218 if (!vfs_user_magic_file_hook(filename, &do_remount)) {
Pawel Zarembski 0:01f31e923fe2 219 // Compare the new file's name to our table of magic filenames.
Pawel Zarembski 0:01f31e923fe2 220 for (int32_t i = 0; i < ARRAY_SIZE(s_magic_file_info); ++i) {
Pawel Zarembski 0:01f31e923fe2 221 if (!memcmp(filename, s_magic_file_info[i].name, sizeof(vfs_filename_t))) {
Pawel Zarembski 0:01f31e923fe2 222 which_magic_file = i;
Pawel Zarembski 0:01f31e923fe2 223 }
Pawel Zarembski 0:01f31e923fe2 224 }
Pawel Zarembski 0:01f31e923fe2 225
Pawel Zarembski 0:01f31e923fe2 226 // Check if we matched a magic filename and handle it.
Pawel Zarembski 0:01f31e923fe2 227 if (which_magic_file != -1) {
Pawel Zarembski 0:01f31e923fe2 228 switch (which_magic_file) {
Pawel Zarembski 0:01f31e923fe2 229 case kDAPLinkModeActionFile:
Pawel Zarembski 0:01f31e923fe2 230 if (daplink_is_interface()) {
Pawel Zarembski 0:01f31e923fe2 231 config_ram_set_hold_in_bl(true);
Pawel Zarembski 0:01f31e923fe2 232 } else {
Pawel Zarembski 0:01f31e923fe2 233 // Do nothing - bootloader will go to interface by default
Pawel Zarembski 0:01f31e923fe2 234 }
Pawel Zarembski 0:01f31e923fe2 235 break;
Pawel Zarembski 0:01f31e923fe2 236 case kTestAssertActionFile:
Pawel Zarembski 0:01f31e923fe2 237 // Test asserts
Pawel Zarembski 0:01f31e923fe2 238 util_assert(0);
Pawel Zarembski 0:01f31e923fe2 239 do_remount = false;
Pawel Zarembski 0:01f31e923fe2 240 break;
Pawel Zarembski 0:01f31e923fe2 241 case kRefreshActionFile:
Pawel Zarembski 0:01f31e923fe2 242 // Remount to update the drive
Pawel Zarembski 0:01f31e923fe2 243 break;
Pawel Zarembski 0:01f31e923fe2 244 case kEraseActionFile:
Pawel Zarembski 0:01f31e923fe2 245 erase_target();
Pawel Zarembski 0:01f31e923fe2 246 break;
Pawel Zarembski 0:01f31e923fe2 247 case kAutoResetConfigFile:
Pawel Zarembski 0:01f31e923fe2 248 config_set_auto_rst(true);
Pawel Zarembski 0:01f31e923fe2 249 break;
Pawel Zarembski 0:01f31e923fe2 250 case kHardResetConfigFile:
Pawel Zarembski 0:01f31e923fe2 251 config_set_auto_rst(false);
Pawel Zarembski 0:01f31e923fe2 252 break;
Pawel Zarembski 0:01f31e923fe2 253 case kAutomationOnConfigFile:
Pawel Zarembski 0:01f31e923fe2 254 config_set_automation_allowed(true);
Pawel Zarembski 0:01f31e923fe2 255 break;
Pawel Zarembski 0:01f31e923fe2 256 case kAutomationOffConfigFile:
Pawel Zarembski 0:01f31e923fe2 257 config_set_automation_allowed(false);
Pawel Zarembski 0:01f31e923fe2 258 break;
Pawel Zarembski 0:01f31e923fe2 259 case kOverflowOnConfigFile:
Pawel Zarembski 0:01f31e923fe2 260 config_set_overflow_detect(true);
Pawel Zarembski 0:01f31e923fe2 261 break;
Pawel Zarembski 0:01f31e923fe2 262 case kOverflowOffConfigFile:
Pawel Zarembski 0:01f31e923fe2 263 config_set_overflow_detect(false);
Pawel Zarembski 0:01f31e923fe2 264 break;
Pawel Zarembski 0:01f31e923fe2 265 case kMSDOnConfigFile:
Pawel Zarembski 0:01f31e923fe2 266 config_ram_set_disable_msd(false);
Pawel Zarembski 0:01f31e923fe2 267 break;
Pawel Zarembski 0:01f31e923fe2 268 case kMSDOffConfigFile:
Pawel Zarembski 0:01f31e923fe2 269 config_ram_set_disable_msd(true);
Pawel Zarembski 0:01f31e923fe2 270 break;
Pawel Zarembski 0:01f31e923fe2 271 case kPageEraseActionFile:
Pawel Zarembski 0:01f31e923fe2 272 config_ram_set_page_erase(true);
Pawel Zarembski 0:01f31e923fe2 273 break;
Pawel Zarembski 0:01f31e923fe2 274 case kChipEraseActionFile:
Pawel Zarembski 0:01f31e923fe2 275 config_ram_set_page_erase(false);
Pawel Zarembski 0:01f31e923fe2 276 break;
Pawel Zarembski 0:01f31e923fe2 277 default:
Pawel Zarembski 0:01f31e923fe2 278 util_assert(false);
Pawel Zarembski 0:01f31e923fe2 279 }
Pawel Zarembski 0:01f31e923fe2 280 }
Pawel Zarembski 0:01f31e923fe2 281 else {
Pawel Zarembski 0:01f31e923fe2 282 do_remount = false;
Pawel Zarembski 0:01f31e923fe2 283 }
Pawel Zarembski 0:01f31e923fe2 284 }
Pawel Zarembski 0:01f31e923fe2 285
Pawel Zarembski 0:01f31e923fe2 286 // Remount if requested.
Pawel Zarembski 0:01f31e923fe2 287 if (do_remount) {
Pawel Zarembski 0:01f31e923fe2 288 vfs_mngr_fs_remount();
Pawel Zarembski 0:01f31e923fe2 289 }
Pawel Zarembski 0:01f31e923fe2 290 }
Pawel Zarembski 0:01f31e923fe2 291
Pawel Zarembski 0:01f31e923fe2 292 else if (VFS_FILE_DELETED == change) {
Pawel Zarembski 0:01f31e923fe2 293 if (!memcmp(filename, assert_file, sizeof(vfs_filename_t))) {
Pawel Zarembski 0:01f31e923fe2 294 // Clear assert and remount to update the drive
Pawel Zarembski 0:01f31e923fe2 295 util_assert_clear();
Pawel Zarembski 0:01f31e923fe2 296 vfs_mngr_fs_remount();
Pawel Zarembski 0:01f31e923fe2 297 }
Pawel Zarembski 0:01f31e923fe2 298 }
Pawel Zarembski 0:01f31e923fe2 299 }
Pawel Zarembski 0:01f31e923fe2 300
Pawel Zarembski 0:01f31e923fe2 301 void vfs_user_disconnecting()
Pawel Zarembski 0:01f31e923fe2 302 {
Pawel Zarembski 0:01f31e923fe2 303 // Reset if programming was successful //TODO - move to flash layer
Pawel Zarembski 0:01f31e923fe2 304 if (daplink_is_bootloader() && (ERROR_SUCCESS == vfs_mngr_get_transfer_status())) {
Pawel Zarembski 0:01f31e923fe2 305 SystemReset();
Pawel Zarembski 0:01f31e923fe2 306 }
Pawel Zarembski 0:01f31e923fe2 307
Pawel Zarembski 0:01f31e923fe2 308 // If hold in bootloader has been set then reset after usb is disconnected
Pawel Zarembski 0:01f31e923fe2 309 if (daplink_is_interface() && (config_ram_get_hold_in_bl() || config_ram_get_disable_msd()==1)) {
Pawel Zarembski 0:01f31e923fe2 310 SystemReset();
Pawel Zarembski 0:01f31e923fe2 311 }
Pawel Zarembski 0:01f31e923fe2 312
Pawel Zarembski 0:01f31e923fe2 313 remount_count++;
Pawel Zarembski 0:01f31e923fe2 314 }
Pawel Zarembski 0:01f31e923fe2 315
Pawel Zarembski 0:01f31e923fe2 316 // Get the filesize from a filesize callback.
Pawel Zarembski 0:01f31e923fe2 317 // The file data must be null terminated for this to work correctly.
Pawel Zarembski 0:01f31e923fe2 318 static uint32_t get_file_size(vfs_read_cb_t read_func)
Pawel Zarembski 0:01f31e923fe2 319 {
Pawel Zarembski 0:01f31e923fe2 320 // Determine size of the file by faking a read
Pawel Zarembski 0:01f31e923fe2 321 return read_func(0, file_buffer, 1);
Pawel Zarembski 0:01f31e923fe2 322 }
Pawel Zarembski 0:01f31e923fe2 323
Pawel Zarembski 0:01f31e923fe2 324 // File callback to be used with vfs_add_file to return file contents
Pawel Zarembski 0:01f31e923fe2 325 static uint32_t read_file_mbed_htm(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors)
Pawel Zarembski 0:01f31e923fe2 326 {
Pawel Zarembski 0:01f31e923fe2 327 if (sector_offset != 0) {
Pawel Zarembski 0:01f31e923fe2 328 return 0;
Pawel Zarembski 0:01f31e923fe2 329 }
Pawel Zarembski 0:01f31e923fe2 330
Pawel Zarembski 0:01f31e923fe2 331 return update_html_file(data, VFS_SECTOR_SIZE);
Pawel Zarembski 0:01f31e923fe2 332 }
Pawel Zarembski 0:01f31e923fe2 333
Pawel Zarembski 0:01f31e923fe2 334 // File callback to be used with vfs_add_file to return file contents
Pawel Zarembski 0:01f31e923fe2 335 static uint32_t read_file_details_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors)
Pawel Zarembski 0:01f31e923fe2 336 {
Pawel Zarembski 0:01f31e923fe2 337
Pawel Zarembski 0:01f31e923fe2 338 if (sector_offset != 0) {
Pawel Zarembski 0:01f31e923fe2 339 return 0;
Pawel Zarembski 0:01f31e923fe2 340 }
Pawel Zarembski 0:01f31e923fe2 341
Pawel Zarembski 0:01f31e923fe2 342 return update_details_txt_file(data, VFS_SECTOR_SIZE);
Pawel Zarembski 0:01f31e923fe2 343 }
Pawel Zarembski 0:01f31e923fe2 344
Pawel Zarembski 0:01f31e923fe2 345 // Text representation of each error type, starting from the rightmost bit
Pawel Zarembski 0:01f31e923fe2 346 static const char* const error_type_names[] = {
Pawel Zarembski 0:01f31e923fe2 347 "internal",
Pawel Zarembski 0:01f31e923fe2 348 "transient",
Pawel Zarembski 0:01f31e923fe2 349 "user",
Pawel Zarembski 0:01f31e923fe2 350 "target",
Pawel Zarembski 0:01f31e923fe2 351 "interface"
Pawel Zarembski 0:01f31e923fe2 352 };
Pawel Zarembski 0:01f31e923fe2 353
Pawel Zarembski 0:01f31e923fe2 354 COMPILER_ASSERT(1 << ARRAY_SIZE(error_type_names) == ERROR_TYPE_MASK + 1);
Pawel Zarembski 0:01f31e923fe2 355
Pawel Zarembski 0:01f31e923fe2 356 // File callback to be used with vfs_add_file to return file contents
Pawel Zarembski 0:01f31e923fe2 357 static uint32_t read_file_fail_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors)
Pawel Zarembski 0:01f31e923fe2 358 {
Pawel Zarembski 0:01f31e923fe2 359 uint32_t size = 0;
Pawel Zarembski 0:01f31e923fe2 360 char *buf = (char *)data;
Pawel Zarembski 0:01f31e923fe2 361 error_t status = vfs_mngr_get_transfer_status();
Pawel Zarembski 0:01f31e923fe2 362 const char *contents = error_get_string(status);
Pawel Zarembski 0:01f31e923fe2 363 error_type_t type = error_get_type(status);
Pawel Zarembski 0:01f31e923fe2 364
Pawel Zarembski 0:01f31e923fe2 365 if (sector_offset != 0) {
Pawel Zarembski 0:01f31e923fe2 366 return 0;
Pawel Zarembski 0:01f31e923fe2 367 }
Pawel Zarembski 0:01f31e923fe2 368
Pawel Zarembski 0:01f31e923fe2 369 size += util_write_string(buf + size, error_prefix);
Pawel Zarembski 0:01f31e923fe2 370 size += util_write_string(buf + size, contents);
Pawel Zarembski 0:01f31e923fe2 371 size += util_write_string(buf + size, "\r\n");
Pawel Zarembski 0:01f31e923fe2 372 size += util_write_string(buf + size, error_type_prefix);
Pawel Zarembski 0:01f31e923fe2 373
Pawel Zarembski 0:01f31e923fe2 374 // Write each applicable error type, separated by commas
Pawel Zarembski 0:01f31e923fe2 375 int index = 0;
Pawel Zarembski 0:01f31e923fe2 376 bool first = true;
Pawel Zarembski 0:01f31e923fe2 377 while (type && index < ARRAY_SIZE(error_type_names)) {
Pawel Zarembski 0:01f31e923fe2 378 if (!first) {
Pawel Zarembski 0:01f31e923fe2 379 size += util_write_string(buf + size, ", ");
Pawel Zarembski 0:01f31e923fe2 380 }
Pawel Zarembski 0:01f31e923fe2 381 if (type & 1) {
Pawel Zarembski 0:01f31e923fe2 382 size += util_write_string(buf + size, error_type_names[index]);
Pawel Zarembski 0:01f31e923fe2 383 first = false;
Pawel Zarembski 0:01f31e923fe2 384 }
Pawel Zarembski 0:01f31e923fe2 385 index++;
Pawel Zarembski 0:01f31e923fe2 386 type >>= 1;
Pawel Zarembski 0:01f31e923fe2 387 }
Pawel Zarembski 0:01f31e923fe2 388
Pawel Zarembski 0:01f31e923fe2 389 size += util_write_string(buf + size, "\r\n");
Pawel Zarembski 0:01f31e923fe2 390 return size;
Pawel Zarembski 0:01f31e923fe2 391 }
Pawel Zarembski 0:01f31e923fe2 392
Pawel Zarembski 0:01f31e923fe2 393 // File callback to be used with vfs_add_file to return file contents
Pawel Zarembski 0:01f31e923fe2 394 static uint32_t read_file_assert_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors)
Pawel Zarembski 0:01f31e923fe2 395 {
Pawel Zarembski 0:01f31e923fe2 396 uint32_t pos;
Pawel Zarembski 0:01f31e923fe2 397 const char *source_str;
Pawel Zarembski 0:01f31e923fe2 398 char *buf = (char *)data;
Pawel Zarembski 0:01f31e923fe2 399 uint32_t * hexdumps = 0;
Pawel Zarembski 0:01f31e923fe2 400 uint8_t valid_hexdumps = 0;
Pawel Zarembski 0:01f31e923fe2 401 uint8_t index = 0;
Pawel Zarembski 0:01f31e923fe2 402
Pawel Zarembski 0:01f31e923fe2 403 if (sector_offset != 0) {
Pawel Zarembski 0:01f31e923fe2 404 return 0;
Pawel Zarembski 0:01f31e923fe2 405 }
Pawel Zarembski 0:01f31e923fe2 406
Pawel Zarembski 0:01f31e923fe2 407 pos = 0;
Pawel Zarembski 0:01f31e923fe2 408
Pawel Zarembski 0:01f31e923fe2 409 if (ASSERT_SOURCE_BL == assert_source) {
Pawel Zarembski 0:01f31e923fe2 410 source_str = "Bootloader";
Pawel Zarembski 0:01f31e923fe2 411 } else if (ASSERT_SOURCE_APP == assert_source) {
Pawel Zarembski 0:01f31e923fe2 412 source_str = "Application";
Pawel Zarembski 0:01f31e923fe2 413 } else {
Pawel Zarembski 0:01f31e923fe2 414 source_str = 0;
Pawel Zarembski 0:01f31e923fe2 415 }
Pawel Zarembski 0:01f31e923fe2 416
Pawel Zarembski 0:01f31e923fe2 417 pos += util_write_string(buf + pos, "Assert\r\n");
Pawel Zarembski 0:01f31e923fe2 418 pos += util_write_string(buf + pos, "File: ");
Pawel Zarembski 0:01f31e923fe2 419 pos += util_write_string(buf + pos, assert_buf);
Pawel Zarembski 0:01f31e923fe2 420 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 421 pos += util_write_string(buf + pos, "Line: ");
Pawel Zarembski 0:01f31e923fe2 422 pos += util_write_uint32(buf + pos, assert_line);
Pawel Zarembski 0:01f31e923fe2 423 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 424
Pawel Zarembski 0:01f31e923fe2 425 if (source_str != 0) {
Pawel Zarembski 0:01f31e923fe2 426 pos += util_write_string(buf + pos, "Source: ");
Pawel Zarembski 0:01f31e923fe2 427 pos += util_write_string(buf + pos, source_str);
Pawel Zarembski 0:01f31e923fe2 428 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 429 }
Pawel Zarembski 0:01f31e923fe2 430
Pawel Zarembski 0:01f31e923fe2 431 valid_hexdumps = config_ram_get_hexdumps(&hexdumps);
Pawel Zarembski 0:01f31e923fe2 432 if ((valid_hexdumps > 0) && (hexdumps != 0)) {
Pawel Zarembski 0:01f31e923fe2 433 //print hexdumps
Pawel Zarembski 0:01f31e923fe2 434 pos += util_write_string(buf + pos, "Hexdumps\r\n");
Pawel Zarembski 0:01f31e923fe2 435 while ((index < valid_hexdumps) && ((pos + 10) < VFS_SECTOR_SIZE)) { //hexdumps + newline is always 10 characters
Pawel Zarembski 0:01f31e923fe2 436 pos += util_write_hex32(buf + pos, hexdumps[index++]);
Pawel Zarembski 0:01f31e923fe2 437 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 438 }
Pawel Zarembski 0:01f31e923fe2 439 }
Pawel Zarembski 0:01f31e923fe2 440
Pawel Zarembski 0:01f31e923fe2 441 return pos;
Pawel Zarembski 0:01f31e923fe2 442 }
Pawel Zarembski 0:01f31e923fe2 443
Pawel Zarembski 0:01f31e923fe2 444 // File callback to be used with vfs_add_file to return file contents
Pawel Zarembski 0:01f31e923fe2 445 static uint32_t read_file_need_bl_txt(uint32_t sector_offset, uint8_t *data, uint32_t num_sectors)
Pawel Zarembski 0:01f31e923fe2 446 {
Pawel Zarembski 0:01f31e923fe2 447 const char *contents = "A bootloader update was started but unable to complete.\r\n"
Pawel Zarembski 0:01f31e923fe2 448 "Reload the bootloader to fix this error message.\r\n";
Pawel Zarembski 0:01f31e923fe2 449 uint32_t size = strlen(contents);
Pawel Zarembski 0:01f31e923fe2 450
Pawel Zarembski 0:01f31e923fe2 451 if (sector_offset != 0) {
Pawel Zarembski 0:01f31e923fe2 452 return 0;
Pawel Zarembski 0:01f31e923fe2 453 }
Pawel Zarembski 0:01f31e923fe2 454
Pawel Zarembski 0:01f31e923fe2 455 memcpy(data, contents, size);
Pawel Zarembski 0:01f31e923fe2 456 return size;
Pawel Zarembski 0:01f31e923fe2 457 }
Pawel Zarembski 0:01f31e923fe2 458
Pawel Zarembski 0:01f31e923fe2 459
Pawel Zarembski 0:01f31e923fe2 460 static uint32_t update_html_file(uint8_t *data, uint32_t datasize)
Pawel Zarembski 0:01f31e923fe2 461 {
Pawel Zarembski 0:01f31e923fe2 462 char *buf = (char *)data;
Pawel Zarembski 0:01f31e923fe2 463 //Needed by expand_info strlen
Pawel Zarembski 0:01f31e923fe2 464 memset(buf, 0, datasize);
Pawel Zarembski 0:01f31e923fe2 465 memcpy(buf, mbed_redirect_file, strlen(mbed_redirect_file));
Pawel Zarembski 0:01f31e923fe2 466 //expand
Pawel Zarembski 0:01f31e923fe2 467 return expand_info(data, datasize);
Pawel Zarembski 0:01f31e923fe2 468 }
Pawel Zarembski 0:01f31e923fe2 469
Pawel Zarembski 0:01f31e923fe2 470 static uint32_t update_details_txt_file(uint8_t *data, uint32_t datasize)
Pawel Zarembski 0:01f31e923fe2 471 {
Pawel Zarembski 0:01f31e923fe2 472 uint32_t pos=0;
Pawel Zarembski 0:01f31e923fe2 473 const char *mode_str;
Pawel Zarembski 0:01f31e923fe2 474
Pawel Zarembski 0:01f31e923fe2 475 char *buf = (char *)data;
Pawel Zarembski 0:01f31e923fe2 476
Pawel Zarembski 0:01f31e923fe2 477 //Needed by expand_info strlen
Pawel Zarembski 0:01f31e923fe2 478 memset(buf, 0, datasize);
Pawel Zarembski 0:01f31e923fe2 479
Pawel Zarembski 0:01f31e923fe2 480 pos += util_write_string(buf + pos, "# DAPLink Firmware - see https://mbed.com/daplink\r\n");
Pawel Zarembski 0:01f31e923fe2 481 // Unique ID
Pawel Zarembski 0:01f31e923fe2 482 pos += util_write_string(buf + pos, "Unique ID: @U\r\n");
Pawel Zarembski 0:01f31e923fe2 483 // HIC ID
Pawel Zarembski 0:01f31e923fe2 484 pos += util_write_string(buf + pos, "HIC ID: @D\r\n");
Pawel Zarembski 0:01f31e923fe2 485 // Settings
Pawel Zarembski 0:01f31e923fe2 486 pos += util_write_string(buf + pos, "Auto Reset: ");
Pawel Zarembski 0:01f31e923fe2 487 pos += util_write_string(buf + pos, config_get_auto_rst() ? "1" : "0");
Pawel Zarembski 0:01f31e923fe2 488 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 489 pos += util_write_string(buf + pos, "Automation allowed: ");
Pawel Zarembski 0:01f31e923fe2 490 pos += util_write_string(buf + pos, config_get_automation_allowed() ? "1" : "0");
Pawel Zarembski 0:01f31e923fe2 491 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 492 pos += util_write_string(buf + pos, "Overflow detection: ");
Pawel Zarembski 0:01f31e923fe2 493 pos += util_write_string(buf + pos, config_get_overflow_detect() ? "1" : "0");
Pawel Zarembski 0:01f31e923fe2 494 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 495 pos += util_write_string(buf + pos, "Page erasing: ");
Pawel Zarembski 0:01f31e923fe2 496 pos += util_write_string(buf + pos, config_ram_get_page_erase() ? "1" : "0");
Pawel Zarembski 0:01f31e923fe2 497 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 498 // Current mode
Pawel Zarembski 0:01f31e923fe2 499 mode_str = daplink_is_bootloader() ? "Bootloader" : "Interface";
Pawel Zarembski 0:01f31e923fe2 500 pos += util_write_string(buf + pos, "Daplink Mode: ");
Pawel Zarembski 0:01f31e923fe2 501 pos += util_write_string(buf + pos, mode_str);
Pawel Zarembski 0:01f31e923fe2 502 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 503 // Current build's version
Pawel Zarembski 0:01f31e923fe2 504 pos += util_write_string(buf + pos, mode_str);
Pawel Zarembski 0:01f31e923fe2 505 pos += util_write_string(buf + pos, " Version: @V\r\n");
Pawel Zarembski 0:01f31e923fe2 506
Pawel Zarembski 0:01f31e923fe2 507 // Other builds version (bl or if)
Pawel Zarembski 0:01f31e923fe2 508 if (!daplink_is_bootloader() && info_get_bootloader_present()) {
Pawel Zarembski 0:01f31e923fe2 509 pos += util_write_string(buf + pos, "Bootloader Version: ");
Pawel Zarembski 0:01f31e923fe2 510 pos += util_write_uint32_zp(buf + pos, info_get_bootloader_version(), 4);
Pawel Zarembski 0:01f31e923fe2 511 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 512 }
Pawel Zarembski 0:01f31e923fe2 513
Pawel Zarembski 0:01f31e923fe2 514 if (!daplink_is_interface() && info_get_interface_present()) {
Pawel Zarembski 0:01f31e923fe2 515 pos += util_write_string(buf + pos, "Interface Version: ");
Pawel Zarembski 0:01f31e923fe2 516 pos += util_write_uint32_zp(buf + pos, info_get_interface_version(), 4);
Pawel Zarembski 0:01f31e923fe2 517 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 518 }
Pawel Zarembski 0:01f31e923fe2 519
Pawel Zarembski 0:01f31e923fe2 520 // GIT sha
Pawel Zarembski 0:01f31e923fe2 521 pos += util_write_string(buf + pos, "Git SHA: ");
Pawel Zarembski 0:01f31e923fe2 522 pos += util_write_string(buf + pos, GIT_COMMIT_SHA);
Pawel Zarembski 0:01f31e923fe2 523 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 524 // Local modifications when making the build
Pawel Zarembski 0:01f31e923fe2 525 pos += util_write_string(buf + pos, "Local Mods: ");
Pawel Zarembski 0:01f31e923fe2 526 pos += util_write_uint32(buf + pos, GIT_LOCAL_MODS);
Pawel Zarembski 0:01f31e923fe2 527 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 528 // Supported USB endpoints
Pawel Zarembski 0:01f31e923fe2 529 pos += util_write_string(buf + pos, "USB Interfaces: ");
Pawel Zarembski 0:01f31e923fe2 530 #ifdef MSC_ENDPOINT
Pawel Zarembski 0:01f31e923fe2 531 pos += util_write_string(buf + pos, "MSD");
Pawel Zarembski 0:01f31e923fe2 532 #endif
Pawel Zarembski 0:01f31e923fe2 533 #ifdef CDC_ENDPOINT
Pawel Zarembski 0:01f31e923fe2 534 pos += util_write_string(buf + pos, ", CDC");
Pawel Zarembski 0:01f31e923fe2 535 #endif
Pawel Zarembski 0:01f31e923fe2 536 #ifdef HID_ENDPOINT
Pawel Zarembski 0:01f31e923fe2 537 pos += util_write_string(buf + pos, ", HID");
Pawel Zarembski 0:01f31e923fe2 538 #endif
Pawel Zarembski 0:01f31e923fe2 539 #if (WEBUSB_INTERFACE)
Pawel Zarembski 0:01f31e923fe2 540 pos += util_write_string(buf + pos, ", WebUSB");
Pawel Zarembski 0:01f31e923fe2 541 #endif
Pawel Zarembski 0:01f31e923fe2 542 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 543
Pawel Zarembski 0:01f31e923fe2 544 // CRC of the bootloader (if there is one)
Pawel Zarembski 0:01f31e923fe2 545 if (info_get_bootloader_present()) {
Pawel Zarembski 0:01f31e923fe2 546 pos += util_write_string(buf + pos, "Bootloader CRC: 0x");
Pawel Zarembski 0:01f31e923fe2 547 pos += util_write_hex32(buf + pos, info_get_crc_bootloader());
Pawel Zarembski 0:01f31e923fe2 548 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 549 }
Pawel Zarembski 0:01f31e923fe2 550
Pawel Zarembski 0:01f31e923fe2 551 // CRC of the interface
Pawel Zarembski 0:01f31e923fe2 552 pos += util_write_string(buf + pos, "Interface CRC: 0x");
Pawel Zarembski 0:01f31e923fe2 553 pos += util_write_hex32(buf + pos, info_get_crc_interface());
Pawel Zarembski 0:01f31e923fe2 554 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 555
Pawel Zarembski 0:01f31e923fe2 556 // Number of remounts that have occurred
Pawel Zarembski 0:01f31e923fe2 557 pos += util_write_string(buf + pos, "Remount count: ");
Pawel Zarembski 0:01f31e923fe2 558 pos += util_write_uint32(buf + pos, remount_count);
Pawel Zarembski 0:01f31e923fe2 559 pos += util_write_string(buf + pos, "\r\n");
Pawel Zarembski 0:01f31e923fe2 560
Pawel Zarembski 0:01f31e923fe2 561 //Target URL
Pawel Zarembski 0:01f31e923fe2 562 pos += util_write_string(buf + pos, "URL: @R\r\n");
Pawel Zarembski 0:01f31e923fe2 563
Pawel Zarembski 0:01f31e923fe2 564 return expand_info(data, datasize);
Pawel Zarembski 0:01f31e923fe2 565 }
Pawel Zarembski 0:01f31e923fe2 566
Pawel Zarembski 0:01f31e923fe2 567 // Fill buf with the contents of the mbed redirect file by
Pawel Zarembski 0:01f31e923fe2 568 // expanding the special characters in mbed_redirect_file.
Pawel Zarembski 0:01f31e923fe2 569 static uint32_t expand_info(uint8_t *buf, uint32_t bufsize)
Pawel Zarembski 0:01f31e923fe2 570 {
Pawel Zarembski 0:01f31e923fe2 571 uint8_t *orig_buf = buf;
Pawel Zarembski 0:01f31e923fe2 572 uint8_t *insert_string;
Pawel Zarembski 0:01f31e923fe2 573
Pawel Zarembski 0:01f31e923fe2 574 do {
Pawel Zarembski 0:01f31e923fe2 575 // Look for key or the end of the string
Pawel Zarembski 0:01f31e923fe2 576 while ((*buf != '@') && (*buf != 0)) {
Pawel Zarembski 0:01f31e923fe2 577 buf++;
Pawel Zarembski 0:01f31e923fe2 578 }
Pawel Zarembski 0:01f31e923fe2 579
Pawel Zarembski 0:01f31e923fe2 580 // If key was found then replace it
Pawel Zarembski 0:01f31e923fe2 581 if ('@' == *buf) {
Pawel Zarembski 0:01f31e923fe2 582 switch (*(buf + 1)) {
Pawel Zarembski 0:01f31e923fe2 583 case 'm':
Pawel Zarembski 0:01f31e923fe2 584 case 'M': // MAC address
Pawel Zarembski 0:01f31e923fe2 585 insert_string = (uint8_t *)info_get_mac();
Pawel Zarembski 0:01f31e923fe2 586 break;
Pawel Zarembski 0:01f31e923fe2 587
Pawel Zarembski 0:01f31e923fe2 588 case 'u':
Pawel Zarembski 0:01f31e923fe2 589 case 'U': // UUID
Pawel Zarembski 0:01f31e923fe2 590 insert_string = (uint8_t *)info_get_unique_id();
Pawel Zarembski 0:01f31e923fe2 591 break;
Pawel Zarembski 0:01f31e923fe2 592
Pawel Zarembski 0:01f31e923fe2 593 case 'b':
Pawel Zarembski 0:01f31e923fe2 594 case 'B': // Board ID
Pawel Zarembski 0:01f31e923fe2 595 insert_string = (uint8_t *)info_get_board_id();
Pawel Zarembski 0:01f31e923fe2 596 break;
Pawel Zarembski 0:01f31e923fe2 597
Pawel Zarembski 0:01f31e923fe2 598 case 'h':
Pawel Zarembski 0:01f31e923fe2 599 case 'H': // Host ID
Pawel Zarembski 0:01f31e923fe2 600 insert_string = (uint8_t *)info_get_host_id();
Pawel Zarembski 0:01f31e923fe2 601 break;
Pawel Zarembski 0:01f31e923fe2 602
Pawel Zarembski 0:01f31e923fe2 603 case 't':
Pawel Zarembski 0:01f31e923fe2 604 case 'T': // Target ID
Pawel Zarembski 0:01f31e923fe2 605 insert_string = (uint8_t *)info_get_target_id();
Pawel Zarembski 0:01f31e923fe2 606 break;
Pawel Zarembski 0:01f31e923fe2 607
Pawel Zarembski 0:01f31e923fe2 608 case 'd':
Pawel Zarembski 0:01f31e923fe2 609 case 'D': // HIC
Pawel Zarembski 0:01f31e923fe2 610 insert_string = (uint8_t *)info_get_hic_id();
Pawel Zarembski 0:01f31e923fe2 611 break;
Pawel Zarembski 0:01f31e923fe2 612
Pawel Zarembski 0:01f31e923fe2 613 case 'v':
Pawel Zarembski 0:01f31e923fe2 614 case 'V': // Firmware version
Pawel Zarembski 0:01f31e923fe2 615 insert_string = (uint8_t *)info_get_version();
Pawel Zarembski 0:01f31e923fe2 616 break;
Pawel Zarembski 0:01f31e923fe2 617
Pawel Zarembski 0:01f31e923fe2 618 case 'r':
Pawel Zarembski 0:01f31e923fe2 619 case 'R': // URL replacement
Pawel Zarembski 0:01f31e923fe2 620 insert_string = (uint8_t *)get_daplink_target_url();
Pawel Zarembski 0:01f31e923fe2 621 break;
Pawel Zarembski 0:01f31e923fe2 622
Pawel Zarembski 0:01f31e923fe2 623 default:
Pawel Zarembski 0:01f31e923fe2 624 insert_string = (uint8_t *)"ERROR";
Pawel Zarembski 0:01f31e923fe2 625 break;
Pawel Zarembski 0:01f31e923fe2 626 }
Pawel Zarembski 0:01f31e923fe2 627
Pawel Zarembski 0:01f31e923fe2 628 // Remove strip_count characters from the start of buf and then insert
Pawel Zarembski 0:01f31e923fe2 629 // insert_string at the new start of buf.
Pawel Zarembski 0:01f31e923fe2 630 uint32_t buf_len = strlen((const char *)buf);
Pawel Zarembski 0:01f31e923fe2 631 uint32_t str_len = strlen((const char *)insert_string);
Pawel Zarembski 0:01f31e923fe2 632 //buffer overflow check on insert
Pawel Zarembski 0:01f31e923fe2 633 if( (buf + str_len + buf_len - 2) < (orig_buf+bufsize)){
Pawel Zarembski 0:01f31e923fe2 634 // push out string
Pawel Zarembski 0:01f31e923fe2 635 memmove(buf + str_len, buf + 2, buf_len - 2);
Pawel Zarembski 0:01f31e923fe2 636 // insert
Pawel Zarembski 0:01f31e923fe2 637 memcpy(buf, insert_string, str_len);
Pawel Zarembski 0:01f31e923fe2 638 }else{
Pawel Zarembski 0:01f31e923fe2 639 //stop the string expansion and leave as it is
Pawel Zarembski 0:01f31e923fe2 640 buf += buf_len;
Pawel Zarembski 0:01f31e923fe2 641 break;
Pawel Zarembski 0:01f31e923fe2 642 }
Pawel Zarembski 0:01f31e923fe2 643
Pawel Zarembski 0:01f31e923fe2 644 }
Pawel Zarembski 0:01f31e923fe2 645 } while (*buf != '\0');
Pawel Zarembski 0:01f31e923fe2 646
Pawel Zarembski 0:01f31e923fe2 647 return (buf - orig_buf);
Pawel Zarembski 0:01f31e923fe2 648 }
Pawel Zarembski 0:01f31e923fe2 649
Pawel Zarembski 0:01f31e923fe2 650 // Initialize flash algo, erase flash, uninit algo
Pawel Zarembski 0:01f31e923fe2 651 static void erase_target(void)
Pawel Zarembski 0:01f31e923fe2 652 {
Pawel Zarembski 0:01f31e923fe2 653 flash_intf_target->init();
Pawel Zarembski 0:01f31e923fe2 654 flash_intf_target->erase_chip();
Pawel Zarembski 0:01f31e923fe2 655 flash_intf_target->uninit();
Pawel Zarembski 0:01f31e923fe2 656 }