| 17 | namespace Mqtt |
| 18 | { |
| 19 | int PayloadParser::parse(MqttPayloadParserState& state, mqtt_message_t* message, const char* buffer, int length) |
| 20 | { |
| 21 | if(message == nullptr) { |
| 22 | debug_e("Invalid MQTT message"); |
| 23 | return ERROR_INVALID_MQTT_MESSAGE; |
| 24 | } |
| 25 | |
| 26 | if(length == MQTT_PAYLOAD_PARSER_START) { |
| 27 | state = MqttPayloadParserState{new UpdateState}; |
| 28 | return 0; |
| 29 | } |
| 30 | |
| 31 | auto updateState = static_cast<UpdateState*>(state.userData); |
| 32 | if(updateState == nullptr) { |
| 33 | debug_e("Update failed for unknown reason!"); |
| 34 | return ERROR_UNKNOWN_REASON; |
| 35 | } |
| 36 | |
| 37 | if(length == MQTT_PAYLOAD_PARSER_END) { |
| 38 | bool skip = !updateState->stream; |
| 39 | if(!skip) { |
| 40 | bool success = switchRom(*updateState); |
| 41 | if(success) { |
| 42 | debug_d("Switching was successful. Restarting..."); |
| 43 | System.restart(1000); |
| 44 | } else { |
| 45 | debug_e("Switching failed!"); |
| 46 | } |
| 47 | } |
| 48 | delete updateState; |
| 49 | state.userData = nullptr; |
| 50 | return 0; |
| 51 | } |
| 52 | |
| 53 | if(buffer == nullptr) { |
| 54 | debug_e("Invalid MQTT message"); |
| 55 | return ERROR_INVALID_MQTT_MESSAGE; |
| 56 | } |
| 57 | |
| 58 | if(!updateState->started) { |
| 59 | size_t offset = 0; |
| 60 | int patchVersion = getPatchVersion(buffer, length, offset, updateState->version); |
| 61 | state.offset += offset; |
| 62 | #if ENABLE_OTA_VARINT_VERSION |
| 63 | if(patchVersion < 0) { |
| 64 | if(state.offset > allowedVersionBytes) { |
| 65 | debug_e("Invalid patch version."); |
| 66 | return ERROR_INVALID_PATCH_VERSION; |
| 67 | } |
| 68 | return 0; |
| 69 | } |
| 70 | #endif |
| 71 | |
| 72 | updateState->started = true; |
| 73 | if(size_t(patchVersion) < currentPatchVersion) { |
| 74 | // The update is not newer than our current patch version |
| 75 | return 0; |
| 76 | } |