| 126 | } |
| 127 | |
| 128 | size_t BasicStream::write(const uint8_t* data, size_t size) |
| 129 | { |
| 130 | const size_t origSize = size; |
| 131 | |
| 132 | while(!hasError() && (size > 0)) { |
| 133 | switch(state) { |
| 134 | case State::Header: |
| 135 | if(consume(data, size)) { |
| 136 | if(fileHeader.magic == expectedHeaderMagic) { |
| 137 | #ifndef ENABLE_OTA_DOWNGRADE |
| 138 | const auto buildTimestampFirmware = FSTR::readValue(&BuildTimestamp); |
| 139 | debug_i("Build timestamp of current firmware: %ull", buildTimestampFirmware); |
| 140 | uint64_t buildTimestampUpgrade = |
| 141 | ((uint64_t)fileHeader.buildTimestampHigh << 32) | fileHeader.buildTimestampLow; |
| 142 | debug_i("Build timestamp of OTA upgrade file: %ull", buildTimestampUpgrade); |
| 143 | if(buildTimestampUpgrade < buildTimestampFirmware) { |
| 144 | setError(Error::DowngradeNotAllowed); |
| 145 | break; |
| 146 | } |
| 147 | #endif |
| 148 | debug_i("Starting firmware upgrade, receive %u image(s)", fileHeader.romCount); |
| 149 | nextRom(); |
| 150 | } else { |
| 151 | setError(Error::InvalidFormat); |
| 152 | } |
| 153 | } |
| 154 | break; |
| 155 | |
| 156 | case State::RomHeader: |
| 157 | if(consume(data, size)) { |
| 158 | processRomHeader(); |
| 159 | } |
| 160 | break; |
| 161 | |
| 162 | case State::WriteRom: { |
| 163 | bool ok = ota.write(data, std::min(remainingBytes, size)); |
| 164 | if(ok) { |
| 165 | if(consume(data, size)) { |
| 166 | ok = slot.updated = ota.end(); |
| 167 | nextRom(); |
| 168 | } |
| 169 | } |
| 170 | if(!ok) { |
| 171 | setError(Error::FlashWriteFailed); |
| 172 | } |
| 173 | } break; |
| 174 | |
| 175 | case State::SkipRom: |
| 176 | if(consume(data, size)) { |
| 177 | nextRom(); |
| 178 | } |
| 179 | break; |
| 180 | |
| 181 | case State::VerifyRoms: |
| 182 | if(consume(data, size)) { |
| 183 | verifyRoms(); |
| 184 | } |
| 185 | break; |
no test coverage detected