diff options
Diffstat (limited to 'src/SPI_Firmware.h')
-rw-r--r-- | src/SPI_Firmware.h | 706 |
1 files changed, 355 insertions, 351 deletions
diff --git a/src/SPI_Firmware.h b/src/SPI_Firmware.h index 8557604..ad66a0a 100644 --- a/src/SPI_Firmware.h +++ b/src/SPI_Firmware.h @@ -24,10 +24,10 @@ #include "types.h" #include "Platform.h" -namespace SPI_Firmware -{ - u16 CRC16(const u8* data, u32 len, u32 start); + + + using MacAddress = std::array<u8, 6>; using IpAddress = std::array<u8, 4>; @@ -44,382 +44,384 @@ constexpr const char* const DEFAULT_SSID = "melonAP"; */ constexpr int EXTENDED_WIFI_SETTINGS_OFFSET = -0xA00; -enum class WepMode : u8 -{ - None = 0, - Hex5 = 1, - Hex13 = 2, - Hex16 = 3, - Ascii5 = 5, - Ascii13 = 6, - Ascii16 = 7, -}; +using FirmwareIdentifier = std::array<u8, 4>; +using MacAddress = std::array<u8, 6>; -enum class WpaMode : u8 -{ - Normal = 0, - WPA_WPA2 = 0x10, - WPS_WPA = 0x13, - Unused = 0xff, -}; +constexpr FirmwareIdentifier GENERATED_FIRMWARE_IDENTIFIER = {'M', 'E', 'L', 'N'}; -enum class WpaSecurity : u8 -{ - None = 0, - WPA_TKIP = 4, - WPA2_TKIP = 5, - WPA_AES = 6, - WPA2_AES = 7, -}; -enum class AccessPointStatus : u8 +class Firmware { - Normal = 0, - Aoss = 1, - NotConfigured = 0xff -}; +public: -/** - * @see https://problemkaputt.de/gbatek.htm#dsfirmwarewifiinternetaccesspoints - */ -union WifiAccessPoint -{ - /** - * Constructs an unconfigured access point. - */ - WifiAccessPoint(); + enum class WepMode : u8 + { + None = 0, + Hex5 = 1, + Hex13 = 2, + Hex16 = 3, + Ascii5 = 5, + Ascii13 = 6, + Ascii16 = 7, + }; - /** - * Constructs an access point configured with melonDS's defaults. - */ - explicit WifiAccessPoint(int consoletype); - void UpdateChecksum(); - u8 Bytes[256]; - struct + enum class WpaMode : u8 { - char ProxyUsername[32]; - char ProxyPassword[32]; - char SSID[32]; - char SSIDWEP64[32]; - u8 WEPKey1[16]; - u8 WEPKey2[16]; - u8 WEPKey3[16]; - u8 WEPKey4[16]; - IpAddress Address; - IpAddress Gateway; - IpAddress PrimaryDns; - IpAddress SecondaryDns; - u8 SubnetMask; - u8 Unknown0[21]; - enum WepMode WepMode; - AccessPointStatus Status; - u8 SSIDLength; - u8 Unknown1; - u16 Mtu; - u8 Unknown2[3]; - u8 ConnectionConfigured; - u8 NintendoWFCID[6]; - u8 Unknown3[8]; - u16 Checksum; + Normal = 0, + WPA_WPA2 = 0x10, + WPS_WPA = 0x13, + Unused = 0xff, }; -}; -static_assert(sizeof(WifiAccessPoint) == 256, "WifiAccessPoint should be 256 bytes"); + enum class WpaSecurity : u8 + { + None = 0, + WPA_TKIP = 4, + WPA2_TKIP = 5, + WPA_AES = 6, + WPA2_AES = 7, + }; -union ExtendedWifiAccessPoint -{ - ExtendedWifiAccessPoint(); - void UpdateChecksum(); - u8 Bytes[512]; - struct + enum class AccessPointStatus : u8 { - WifiAccessPoint Base; - - // DSi-specific entries now - u8 PrecomputedPSK[32]; - char WPAPassword[64]; - char Unused0[33]; - WpaSecurity Security; - bool ProxyEnabled; - bool ProxyAuthentication; - char ProxyName[48]; - u8 Unused1[52]; - u16 ProxyPort; - u8 Unused2[20]; - u16 ExtendedChecksum; - } Data; -}; + Normal = 0, + Aoss = 1, + NotConfigured = 0xff + }; -static_assert(sizeof(ExtendedWifiAccessPoint) == 512, "WifiAccessPoint should be 512 bytes"); + /** + * @see https://problemkaputt.de/gbatek.htm#dsfirmwarewifiinternetaccesspoints + */ + union WifiAccessPoint + { + /** + * Constructs an unconfigured access point. + */ + WifiAccessPoint(); + + /** + * Constructs an access point configured with melonDS's defaults. + */ + explicit WifiAccessPoint(int consoletype); + void UpdateChecksum(); + u8 Bytes[256]; + struct + { + char ProxyUsername[32]; + char ProxyPassword[32]; + char SSID[32]; + char SSIDWEP64[32]; + u8 WEPKey1[16]; + u8 WEPKey2[16]; + u8 WEPKey3[16]; + u8 WEPKey4[16]; + IpAddress Address; + IpAddress Gateway; + IpAddress PrimaryDns; + IpAddress SecondaryDns; + u8 SubnetMask; + u8 Unknown0[21]; + enum WepMode WepMode; + AccessPointStatus Status; + u8 SSIDLength; + u8 Unknown1; + u16 Mtu; + u8 Unknown2[3]; + u8 ConnectionConfigured; + u8 NintendoWFCID[6]; + u8 Unknown3[8]; + u16 Checksum; + }; + }; + static_assert(sizeof(WifiAccessPoint) == 256, "WifiAccessPoint should be 256 bytes"); -enum class FirmwareConsoleType : u8 -{ - DS = 0xFF, - DSLite = 0x20, - DSi = 0x57, - iQueDS = 0x43, - iQueDSLite = 0x63, -}; + union ExtendedWifiAccessPoint + { + ExtendedWifiAccessPoint(); + void UpdateChecksum(); + u8 Bytes[512]; + struct + { + WifiAccessPoint Base; + + // DSi-specific entries now + u8 PrecomputedPSK[32]; + char WPAPassword[64]; + char Unused0[33]; + WpaSecurity Security; + bool ProxyEnabled; + bool ProxyAuthentication; + char ProxyName[48]; + u8 Unused1[52]; + u16 ProxyPort; + u8 Unused2[20]; + u16 ExtendedChecksum; + } Data; + }; -enum class WifiVersion : u8 -{ - V1_4 = 0, - V5 = 3, - V6_7 = 5, - W006 = 6, - W015 = 15, - W024 = 24, - N3DS = 34, -}; + static_assert(sizeof(ExtendedWifiAccessPoint) == 512, "WifiAccessPoint should be 512 bytes"); -enum RFChipType : u8 -{ - Type2 = 0x2, - Type3 = 0x3, -}; -enum class WifiBoard : u8 -{ - W015 = 0x1, - W024 = 0x2, - W028 = 0x3, - Unused = 0xff, -}; + enum class FirmwareConsoleType : u8 + { + DS = 0xFF, + DSLite = 0x20, + DSi = 0x57, + iQueDS = 0x43, + iQueDSLite = 0x63, + }; -enum Language : u8 -{ - Japanese = 0, - English = 1, - French = 2, - German = 3, - Italian = 4, - Spanish = 5, - Chinese = 6, - Reserved = 7, -}; + enum class WifiVersion : u8 + { + V1_4 = 0, + V5 = 3, + V6_7 = 5, + W006 = 6, + W015 = 15, + W024 = 24, + N3DS = 34, + }; -enum GBAScreen : u8 -{ - Upper = 0, - Lower = (1 << 3), -}; + enum RFChipType : u8 + { + Type2 = 0x2, + Type3 = 0x3, + }; -enum BacklightLevel : u8 -{ - Low = 0, - Medium = 1 << 4, - High = 2 << 4, - Max = 3 << 4 -}; + enum class WifiBoard : u8 + { + W015 = 0x1, + W024 = 0x2, + W028 = 0x3, + Unused = 0xff, + }; -enum BootMenu : u8 -{ - Manual = 0, - Autostart = 1 << 6, -}; + enum Language : u8 + { + Japanese = 0, + English = 1, + French = 2, + German = 3, + Italian = 4, + Spanish = 5, + Chinese = 6, + Reserved = 7, + }; -using FirmwareIdentifier = std::array<u8, 4>; -using MacAddress = std::array<u8, 6>; + enum GBAScreen : u8 + { + Upper = 0, + Lower = (1 << 3), + }; -constexpr FirmwareIdentifier GENERATED_FIRMWARE_IDENTIFIER = {'M', 'E', 'L', 'N'}; + enum BacklightLevel : u8 + { + Low = 0, + Medium = 1 << 4, + High = 2 << 4, + Max = 3 << 4 + }; -/** - * @note GBATek says the header is actually 511 bytes; - * this header struct is 512 bytes due to padding, - * but the last byte is just the first byte of the firmware's code. - * It doesn't affect the offset of any of the fields, - * so leaving that last byte in there is harmless. - * @see https://problemkaputt.de/gbatek.htm#dsfirmwareheader - * @see https://problemkaputt.de/gbatek.htm#dsfirmwarewificalibrationdata -*/ -union FirmwareHeader -{ - explicit FirmwareHeader(int consoletype); - void UpdateChecksum(); - u8 Bytes[512]; - struct + enum BootMenu : u8 { - u16 ARM9GUICodeOffset; - u16 ARM7WifiCodeOffset; - u16 GUIWifiCodeChecksum; - u16 BootCodeChecksum; + Manual = 0, + Autostart = 1 << 6, + }; - FirmwareIdentifier Identifier; + /** + * @note GBATek says the header is actually 511 bytes; + * this header struct is 512 bytes due to padding, + * but the last byte is just the first byte of the firmware's code. + * It doesn't affect the offset of any of the fields, + * so leaving that last byte in there is harmless. + * @see https://problemkaputt.de/gbatek.htm#dsfirmwareheader + * @see https://problemkaputt.de/gbatek.htm#dsfirmwarewificalibrationdata + */ + union FirmwareHeader + { + explicit FirmwareHeader(int consoletype); + void UpdateChecksum(); + u8 Bytes[512]; + struct + { + u16 ARM9GUICodeOffset; + u16 ARM7WifiCodeOffset; + u16 GUIWifiCodeChecksum; + u16 BootCodeChecksum; - u16 ARM9BootCodeROMAddress; - u16 ARM9BootCodeRAMAddress; - u16 ARM7BootCodeRAMAddress; - u16 ARM7BootCodeROMAddress; - u16 ShiftAmounts; - u16 DataGfxRomAddress; + FirmwareIdentifier Identifier; - u8 BuildMinute; - u8 BuildHour; - u8 BuildDay; - u8 BuildMonth; - u8 BuildYear; + u16 ARM9BootCodeROMAddress; + u16 ARM9BootCodeRAMAddress; + u16 ARM7BootCodeRAMAddress; + u16 ARM7BootCodeROMAddress; + u16 ShiftAmounts; + u16 DataGfxRomAddress; - FirmwareConsoleType ConsoleType; + u8 BuildMinute; + u8 BuildHour; + u8 BuildDay; + u8 BuildMonth; + u8 BuildYear; - u8 Unused0[2]; + FirmwareConsoleType ConsoleType; - u16 UserSettingsOffset; - u8 Unknown0[2]; - u8 Unknown1[2]; - u16 DataGfxChecksum; - u8 Unused2[2]; + u8 Unused0[2]; - // Begin wi-fi settings - u16 WifiConfigChecksum; - u16 WifiConfigLength; - u8 Unused1; - enum WifiVersion WifiVersion; + u16 UserSettingsOffset; + u8 Unknown0[2]; + u8 Unknown1[2]; + u16 DataGfxChecksum; + u8 Unused2[2]; - u8 Unused3[6]; + // Begin wi-fi settings + u16 WifiConfigChecksum; + u16 WifiConfigLength; + u8 Unused1; + enum WifiVersion WifiVersion; - SPI_Firmware::MacAddress MacAddress; + u8 Unused3[6]; - u16 EnabledChannels; + MacAddress MacAddress; - u8 Unknown2[2]; + u16 EnabledChannels; - enum RFChipType RFChipType; - u8 RFBitsPerEntry; - u8 RFEntries; - u8 Unknown3; + u8 Unknown2[2]; - u8 InitialValues[32]; - u8 InitialBBValues[105]; - u8 Unused4; - union - { - struct - { - u8 InitialRFValues[36]; - u8 InitialRF56Values[84]; - u8 InitialBB1EValues[14]; - u8 InitialRf9Values[14]; - } Type2Config; + enum RFChipType RFChipType; + u8 RFBitsPerEntry; + u8 RFEntries; + u8 Unknown3; - struct + u8 InitialValues[32]; + u8 InitialBBValues[105]; + u8 Unused4; + union { - u8 InitialRFValues[41]; - u8 BBIndicesPerChannel; - u8 BBIndex1; - u8 BBData1[14]; - u8 BBIndex2; - u8 BBData2[14]; - u8 RFIndex1; - u8 RFData1[14]; - u8 RFIndex2; - u8 RFData2[14]; - u8 Unused0[46]; - } Type3Config; + struct + { + u8 InitialRFValues[36]; + u8 InitialRF56Values[84]; + u8 InitialBB1EValues[14]; + u8 InitialRf9Values[14]; + } Type2Config; + + struct + { + u8 InitialRFValues[41]; + u8 BBIndicesPerChannel; + u8 BBIndex1; + u8 BBData1[14]; + u8 BBIndex2; + u8 BBData2[14]; + u8 RFIndex1; + u8 RFData1[14]; + u8 RFIndex2; + u8 RFData2[14]; + u8 Unused0[46]; + } Type3Config; + }; + + u8 Unknown4; + u8 Unused5; + u8 Unused6[153]; + enum WifiBoard WifiBoard; + u8 WifiFlash; + u8 Unused7; }; - - u8 Unknown4; - u8 Unused5; - u8 Unused6[153]; - enum WifiBoard WifiBoard; - u8 WifiFlash; - u8 Unused7; }; -}; -static_assert(sizeof(FirmwareHeader) == 512, "FirmwareHeader should be 512 bytes"); + static_assert(sizeof(FirmwareHeader) == 512, "FirmwareHeader should be 512 bytes"); -struct ExtendedUserSettings -{ - char ID[8]; - u16 Checksum; - u16 ChecksumLength; - u8 Version; - u8 UpdateCount; - u8 BootMenuFlags; - u8 GBABorder; - u16 TemperatureCalibration0; - u16 TemperatureCalibration1; - u16 TemperatureCalibrationDegrees; - u8 TemperatureFlags; - u8 BacklightIntensity; - u32 DateCenturyOffset; - u8 DateMonthRecovery; - u8 DateDayRecovery; - u8 DateYearRecovery; - u8 DateTimeFlags; - char DateSeparator; - char TimeSeparator; - char DecimalSeparator; - char ThousandsSeparator; - u8 DaylightSavingsTimeNth; - u8 DaylightSavingsTimeDay; - u8 DaylightSavingsTimeOfMonth; - u8 DaylightSavingsTimeFlags; -}; + struct ExtendedUserSettings + { + char ID[8]; + u16 Checksum; + u16 ChecksumLength; + u8 Version; + u8 UpdateCount; + u8 BootMenuFlags; + u8 GBABorder; + u16 TemperatureCalibration0; + u16 TemperatureCalibration1; + u16 TemperatureCalibrationDegrees; + u8 TemperatureFlags; + u8 BacklightIntensity; + u32 DateCenturyOffset; + u8 DateMonthRecovery; + u8 DateDayRecovery; + u8 DateYearRecovery; + u8 DateTimeFlags; + char DateSeparator; + char TimeSeparator; + char DecimalSeparator; + char ThousandsSeparator; + u8 DaylightSavingsTimeNth; + u8 DaylightSavingsTimeDay; + u8 DaylightSavingsTimeOfMonth; + u8 DaylightSavingsTimeFlags; + }; -static_assert(sizeof(ExtendedUserSettings) == 0x28, "ExtendedUserSettings should be 40 bytes"); + static_assert(sizeof(ExtendedUserSettings) == 0x28, "ExtendedUserSettings should be 40 bytes"); -union UserData -{ - UserData(); - void UpdateChecksum(); - [[nodiscard]] bool ChecksumValid() const + union UserData { - bool baseChecksumOk = Checksum == CRC16(Bytes, 0x70, 0xFFFF); - bool extendedChecksumOk = Bytes[0x74] != 1 || ExtendedSettings.Checksum == CRC16(Bytes + 0x74, 0x8A, 0xFFFF); - // For our purposes, the extended checksum is OK if we're not using extended data + UserData(); + void UpdateChecksum(); + [[nodiscard]] bool ChecksumValid() const + { + bool baseChecksumOk = Checksum == CRC16(Bytes, 0x70, 0xFFFF); + bool extendedChecksumOk = Bytes[0x74] != 1 || ExtendedSettings.Checksum == CRC16(Bytes + 0x74, 0x8A, 0xFFFF); + // For our purposes, the extended checksum is OK if we're not using extended data - return baseChecksumOk && extendedChecksumOk; - } + return baseChecksumOk && extendedChecksumOk; + } - u8 Bytes[256]; - struct - { - u16 Version; - u8 FavoriteColor; - u8 BirthdayMonth; - u8 BirthdayDay; - u8 Unused0; - char16_t Nickname[10]; - u16 NameLength; - char16_t Message[26]; - u16 MessageLength; - u8 AlarmHour; - u8 AlarmMinute; - u8 Unknown0[2]; - u8 AlarmFlags; - u8 Unused1; - u16 TouchCalibrationADC1[2]; - u8 TouchCalibrationPixel1[2]; - u16 TouchCalibrationADC2[2]; - u8 TouchCalibrationPixel2[2]; - u16 Settings; - u8 Year; - u8 RTCClockAdjust; - u32 RTCOffset; - u8 Unused2[4]; - u16 UpdateCounter; - u16 Checksum; - union + u8 Bytes[256]; + struct { - u8 Unused3[0x8C]; - struct + u16 Version; + u8 FavoriteColor; + u8 BirthdayMonth; + u8 BirthdayDay; + u8 Unused0; + char16_t Nickname[10]; + u16 NameLength; + char16_t Message[26]; + u16 MessageLength; + u8 AlarmHour; + u8 AlarmMinute; + u8 Unknown0[2]; + u8 AlarmFlags; + u8 Unused1; + u16 TouchCalibrationADC1[2]; + u8 TouchCalibrationPixel1[2]; + u16 TouchCalibrationADC2[2]; + u8 TouchCalibrationPixel2[2]; + u16 Settings; + u8 Year; + u8 RTCClockAdjust; + u32 RTCOffset; + u8 Unused2[4]; + u16 UpdateCounter; + u16 Checksum; + union { - u8 Unknown0; - Language ExtendedLanguage; // padded - u16 SupportedLanguageMask; - u8 Unused0[0x86]; - u16 Checksum; - } ExtendedSettings; + u8 Unused3[0x8C]; + struct + { + u8 Unknown0; + Language ExtendedLanguage; // padded + u16 SupportedLanguageMask; + u8 Unused0[0x86]; + u16 Checksum; + } ExtendedSettings; + }; }; }; -}; -static_assert(sizeof(UserData) == 256, "UserData should be 256 bytes"); + static_assert(sizeof(UserData) == 256, "UserData should be 256 bytes"); -class Firmware -{ -public: /** * Constructs a default firmware blob * filled with data necessary for booting and configuring NDS games. @@ -449,28 +451,28 @@ public: Firmware& operator=(Firmware&& other) noexcept; ~Firmware(); - [[nodiscard]] FirmwareHeader& Header() { return *reinterpret_cast<FirmwareHeader*>(FirmwareBuffer); } - [[nodiscard]] const FirmwareHeader& Header() const { return *reinterpret_cast<const FirmwareHeader*>(FirmwareBuffer); } + [[nodiscard]] FirmwareHeader& GetHeader() { return *reinterpret_cast<FirmwareHeader*>(FirmwareBuffer); } + [[nodiscard]] const FirmwareHeader& GetHeader() const { return *reinterpret_cast<const FirmwareHeader*>(FirmwareBuffer); } /// @return The offset of the first basic Wi-fi settings block in the firmware /// (not the extended Wi-fi settings block used by the DSi). /// @see WifiAccessPointPosition - [[nodiscard]] u32 WifiAccessPointOffset() const { return UserDataOffset() - 0x400; } + [[nodiscard]] u32 GetWifiAccessPointOffset() const { return GetUserDataOffset() - 0x400; } /// @return The address of the first basic Wi-fi settings block in the firmware. - [[nodiscard]] u8* WifiAccessPointPosition() { return FirmwareBuffer + WifiAccessPointOffset(); } - [[nodiscard]] const u8* WifiAccessPointPosition() const { return FirmwareBuffer + WifiAccessPointOffset(); } + [[nodiscard]] u8* GetWifiAccessPointPosition() { return FirmwareBuffer + GetWifiAccessPointOffset(); } + [[nodiscard]] const u8* GetWifiAccessPointPosition() const { return FirmwareBuffer + GetWifiAccessPointOffset(); } - [[nodiscard]] const std::array<WifiAccessPoint, 3>& AccessPoints() const + [[nodiscard]] const std::array<WifiAccessPoint, 3>& GetAccessPoints() const { // An std::array is a wrapper around a C array, so this cast is fine. - return *reinterpret_cast<const std::array<WifiAccessPoint, 3>*>(WifiAccessPointPosition()); + return *reinterpret_cast<const std::array<WifiAccessPoint, 3>*>(GetWifiAccessPointPosition()); } - [[nodiscard]] std::array<WifiAccessPoint, 3>& AccessPoints() + [[nodiscard]] std::array<WifiAccessPoint, 3>& GetAccessPoints() { // An std::array is a wrapper around a C array, so this cast is fine. - return *reinterpret_cast<std::array<WifiAccessPoint, 3>*>(WifiAccessPointPosition()); + return *reinterpret_cast<std::array<WifiAccessPoint, 3>*>(GetWifiAccessPointPosition()); } /// @returns \c true if this firmware image contains bootable code. @@ -481,20 +483,20 @@ public: /// @return The address of the first extended Wi-fi settings block in the firmware. /// @warning Only meaningful if this is DSi firmware. - [[nodiscard]] u32 ExtendedAccessPointOffset() const { return UserDataOffset() + EXTENDED_WIFI_SETTINGS_OFFSET; } - [[nodiscard]] u8* ExtendedAccessPointPosition() { return FirmwareBuffer + ExtendedAccessPointOffset(); } - [[nodiscard]] const u8* ExtendedAccessPointPosition() const { return FirmwareBuffer + ExtendedAccessPointOffset(); } + [[nodiscard]] u32 GetExtendedAccessPointOffset() const { return GetUserDataOffset() + EXTENDED_WIFI_SETTINGS_OFFSET; } + [[nodiscard]] u8* GetExtendedAccessPointPosition() { return FirmwareBuffer + GetExtendedAccessPointOffset(); } + [[nodiscard]] const u8* GetExtendedAccessPointPosition() const { return FirmwareBuffer + GetExtendedAccessPointOffset(); } - [[nodiscard]] const std::array<ExtendedWifiAccessPoint, 3>& ExtendedAccessPoints() const + [[nodiscard]] const std::array<ExtendedWifiAccessPoint, 3>& GetExtendedAccessPoints() const { // An std::array is a wrapper around a C array, so this cast is fine. - return *reinterpret_cast<const std::array<ExtendedWifiAccessPoint, 3>*>(ExtendedAccessPointPosition()); + return *reinterpret_cast<const std::array<ExtendedWifiAccessPoint, 3>*>(GetExtendedAccessPointPosition()); } - [[nodiscard]] std::array<ExtendedWifiAccessPoint, 3>& ExtendedAccessPoints() + [[nodiscard]] std::array<ExtendedWifiAccessPoint, 3>& GetExtendedAccessPoints() { // An std::array is a wrapper around a C array, so this cast is fine. - return *reinterpret_cast<std::array<ExtendedWifiAccessPoint, 3>*>(ExtendedAccessPointPosition()); + return *reinterpret_cast<std::array<ExtendedWifiAccessPoint, 3>*>(GetExtendedAccessPointPosition()); } /// @return The pointer to the firmware buffer, @@ -508,21 +510,21 @@ public: /// @return The offset of the first user data section in the firmware. /// @see UserDataPosition - [[nodiscard]] u32 UserDataOffset() const { return Header().UserSettingsOffset << 3; } + [[nodiscard]] u32 GetUserDataOffset() const { return GetHeader().UserSettingsOffset << 3; } /// @return The address of the first user data section in the firmware. /// @see UserDataOffset - [[nodiscard]] u8* UserDataPosition() { return FirmwareBuffer + UserDataOffset(); } - [[nodiscard]] const u8* UserDataPosition() const { return FirmwareBuffer + UserDataOffset(); } + [[nodiscard]] u8* GetUserDataPosition() { return FirmwareBuffer + GetUserDataOffset(); } + [[nodiscard]] const u8* GetUserDataPosition() const { return FirmwareBuffer + GetUserDataOffset(); } /// @return Reference to the two user data sections. /// @note Either \c UserData object could be the "effective" one, /// so prefer using \c EffectiveUserData() if you're not modifying both. - [[nodiscard]] const std::array<union UserData, 2>& UserData() const + [[nodiscard]] const std::array<union UserData, 2>& GetUserData() const { // An std::array is a wrapper around a C array, so this cast is fine. - return *reinterpret_cast<const std::array<union UserData, 2>*>(UserDataPosition()); + return *reinterpret_cast<const std::array<union UserData, 2>*>(GetUserDataPosition()); }; /** @@ -531,10 +533,10 @@ public: * so prefer using \c EffectiveUserData() if you're not modifying both. * @warning Remember to call UserData::UpdateChecksum() after modifying any of its fields. */ - [[nodiscard]] std::array<union UserData, 2>& UserData() + [[nodiscard]] std::array<union UserData, 2>& GetUserData() { // An std::array is a wrapper around a C array, so this cast is fine. - return *reinterpret_cast<std::array<union UserData, 2>*>(UserDataPosition()); + return *reinterpret_cast<std::array<union UserData, 2>*>(GetUserDataPosition()); } /** @@ -543,13 +545,16 @@ public: * Specifically, the firmware will use whichever one has the valid checksum * (or the newer one if they're both valid). */ - [[nodiscard]] const union UserData& EffectiveUserData() const; + [[nodiscard]] const union UserData& GetEffectiveUserData() const; /** * @return Reference to whichever of the two user data sections * has the highest update counter. */ - [[nodiscard]] union UserData& EffectiveUserData(); + [[nodiscard]] union UserData& GetEffectiveUserData(); + + /// Fix the given firmware length to an acceptable length + u32 FixFirmwareLength(u32 originalLength); /// Updates the checksums of all used sections of the firmware. void UpdateChecksums(); @@ -558,6 +563,5 @@ private: u32 FirmwareBufferLength; u32 FirmwareMask; }; -} #endif //MELONDS_SPI_FIRMWARE_H |