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.
Dependents: DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#
Diff: MaximInterfaceDevices/DS28E15_22_25.hpp
- Revision:
- 7:9cd16581b578
- Child:
- 8:5ea891c7d1a1
diff -r 471901a04573 -r 9cd16581b578 MaximInterfaceDevices/DS28E15_22_25.hpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MaximInterfaceDevices/DS28E15_22_25.hpp Mon Jul 22 11:44:07 2019 -0500
@@ -0,0 +1,909 @@
+/*******************************************************************************
+* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************/
+
+#ifndef MaximInterfaceDevices_DS28E15_22_25
+#define MaximInterfaceDevices_DS28E15_22_25
+
+#include <stdint.h>
+#include <MaximInterfaceCore/Algorithm.hpp>
+#include <MaximInterfaceCore/array_span.hpp>
+#include <MaximInterfaceCore/ManId.hpp>
+#include <MaximInterfaceCore/OneWireMaster.hpp>
+#include <MaximInterfaceCore/RomId.hpp>
+#include <MaximInterfaceCore/SelectRom.hpp>
+#include <MaximInterfaceCore/Sleep.hpp>
+#include "Config.hpp"
+
+namespace MaximInterfaceDevices {
+
+/// @brief
+/// Interface to the DS28E15/22/25 series of authenticators
+/// including low power variants.
+class DS28E15_22_25 {
+public:
+ enum ErrorValue { CrcError = 1, OperationFailure };
+
+ /// Holds the contents of a device memory segment.
+ typedef Core::array_span<uint_least8_t, 4> Segment;
+
+ /// Holds the contents of a device memory page.
+ typedef Core::array_span<uint_least8_t, 32> Page;
+
+ /// Number of segments per page.
+ static const int segmentsPerPage = Page::size / Segment::size;
+
+ /// Container for the device personality.
+ struct Personality {
+ uint_least8_t PB1;
+ uint_least8_t PB2;
+ Core::ManId::array manId;
+
+ bool secretLocked() const { return PB2 & 0x01; }
+ };
+
+ // Represents the status of a memory protection block.
+ class BlockProtection;
+
+ // Format data to hash for an Authenticated Write to a memory segment.
+ class SegmentWriteMacData;
+
+ // Format data to hash for an Authenticated Write to a memory protection block.
+ class ProtectionWriteMacData;
+
+ // Format data to hash for device authentication or computing the next secret
+ // from the existing secret.
+ class AuthenticationData;
+
+ void setSleep(Core::Sleep & sleep) { this->sleep = &sleep; }
+
+ void setMaster(Core::OneWireMaster & master) { this->master = &master; }
+
+ void setSelectRom(const Core::SelectRom & selectRom) {
+ this->selectRom = selectRom;
+ }
+
+ // Const member functions should not affect the state of the memory,
+ // block protection, or secret on the device.
+
+ /// @brief Read memory segment using the Read Memory command on the device.
+ /// @param pageNum Page number for read operation.
+ /// @param segmentNum Segment number within page for read operation.
+ /// @param[out] data Buffer to read data from the segment into.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ readSegment(int pageNum, int segmentNum, Segment::span data) const;
+
+ /// @brief Continue an in-progress readSegment operation.
+ /// @note A CRC16 will encountered after reading the last segment of a page.
+ /// @param[out] data Buffer to read data from the segment into.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ continueReadSegment(Segment::span data) const;
+
+ /// @brief Write memory segment using the Write Memory command.
+ /// @note 1-Wire ROM selection should have already occurred.
+ /// @param pageNum Page number for write operation.
+ /// @param segmentNum Segment number within page for write operation.
+ /// @param[in] data Data to write to the memory segment.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ writeSegment(int pageNum, int segmentNum, Segment::const_span data);
+
+ /// @brief Continue an in-progress Write Memory command.
+ /// @param[in] data Data to write to the memory segment.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ continueWriteSegment(Segment::const_span data);
+
+ /// @brief Read memory page using the Read Memory command on the device.
+ /// @param pageNum Page number for write operation.
+ /// @param[out] rdbuf Buffer to read data from the page into.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ readPage(int pageNum, Page::span rdbuf) const;
+
+ /// @brief Continue an in-progress readPageOperation.
+ /// @param[out] rdbuf Buffer to read data from the page into.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ continueReadPage(Page::span rdbuf) const;
+
+ /// @brief
+ /// Perform a Compute Page MAC command on the device.
+ /// Read back the MAC and verify the CRC16.
+ /// @param pageNum Page number to use for the computation.
+ /// @param anon True to compute in anonymous mode where ROM ID is not used.
+ /// @param[out] mac The device computed MAC.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ computeReadPageMac(int pageNum, bool anon, Page::span mac) const;
+
+ /// @brief
+ /// Update the status of a memory protection block using the
+ /// Write Page Protection command.
+ /// @param protection
+ /// Desired protection status for the block.
+ /// It is not possible to disable existing protections.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ writeBlockProtection(BlockProtection protection);
+
+ /// @brief
+ /// Update the status of a memory protection block using the
+ /// Authenticated Write Page Protection command.
+ /// @param newProtection New protection status to write.
+ /// @param[in] mac Write MAC computed for this operation.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ writeAuthBlockProtection(BlockProtection newProtection, Page::const_span mac);
+
+ /// @brief Perform Load and Lock Secret command on the device.
+ /// @note The secret should already be stored in the scratchpad on the device.
+ /// @param lock
+ /// Prevent further changes to the secret on the device after loading.
+ MaximInterfaceDevices_EXPORT Core::error_code loadSecret(bool lock);
+
+ /// @brief Perform a Compute and Lock Secret command on the device.
+ /// @param pageNum Page number to use as the binding data.
+ /// @param lock
+ /// Prevent further changes to the secret on the device after computing.
+ MaximInterfaceDevices_EXPORT Core::error_code computeSecret(int pageNum,
+ bool lock);
+
+ /// @brief Read the personality bytes using the Read Status command.
+ /// @param[out] personality Receives personality read from device.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ readPersonality(Personality & personality) const;
+
+ MaximInterfaceDevices_EXPORT static const Core::error_category &
+ errorCategory();
+
+protected:
+ enum Variant { DS28E15, DS28E22, DS28E25 };
+
+ DS28E15_22_25(Core::Sleep & sleep, Core::OneWireMaster & master,
+ const Core::SelectRom & selectRom)
+ : selectRom(selectRom), master(&master), sleep(&sleep) {}
+
+ ~DS28E15_22_25() {}
+
+ Core::error_code doWriteScratchpad(Page::const_span data, Variant variant);
+
+ Core::error_code doReadScratchpad(Page::span data, Variant variant) const;
+
+ Core::error_code doReadBlockProtection(int blockNum,
+ BlockProtection & protection,
+ Variant variant) const;
+
+ Core::error_code doWriteAuthSegment(int pageNum, int segmentNum,
+ Segment::const_span newData,
+ Page::const_span mac, Variant variant);
+
+ Core::error_code doContinueWriteAuthSegment(Segment::const_span newData,
+ Page::const_span mac,
+ Variant variant);
+
+ Core::error_code
+ doReadAllBlockProtection(Core::span<BlockProtection> protection,
+ Variant variant) const;
+
+ Core::error_code doLoadSecret(bool lock, bool lowPower);
+
+ Core::error_code doComputeSecret(int pageNum, bool lock, bool lowPower);
+
+private:
+ enum Command {
+ WriteMemory = 0x55,
+ ReadMemory = 0xF0,
+ LoadAndLockSecret = 0x33,
+ ComputeAndLockSecret = 0x3C,
+ ReadWriteScratchpad = 0x0F,
+ ComputePageMac = 0xA5,
+ ReadStatus = 0xAA,
+ WriteBlockProtection = 0xC3,
+ AuthWriteMemory = 0x5A,
+ AuthWriteBlockProtection = 0xCC,
+ };
+
+ Core::error_code doWriteAuthSegment(Segment::const_span newData,
+ Page::const_span mac, Variant variant,
+ bool continuing);
+
+ Core::error_code
+ writeCommandWithCrc(Command command, uint_least8_t parameter,
+ Core::OneWireMaster::Level level =
+ Core::OneWireMaster::NormalLevel) const;
+
+ Core::SelectRom selectRom;
+ Core::OneWireMaster * master;
+ Core::Sleep * sleep;
+};
+
+inline Core::error_code make_error_code(DS28E15_22_25::ErrorValue e) {
+ return Core::error_code(e, DS28E15_22_25::errorCategory());
+}
+
+/// Interface to the DS28EL15 (low power) authenticator.
+class DS28EL15 : public DS28E15_22_25 {
+public:
+ // DS28E15_22_25 traits
+ static const int memoryPages = 2;
+ static const int protectionBlocks = 4;
+
+ DS28EL15(Core::Sleep & sleep, Core::OneWireMaster & master,
+ const Core::SelectRom & selectRom)
+ : DS28E15_22_25(sleep, master, selectRom) {}
+
+ /// @brief Perform Write Scratchpad operation on the device.
+ /// @param[in] data Data to write to the scratchpad.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ writeScratchpad(Page::const_span data);
+
+ /// @brief Perform a Read Scratchpad operation on the device.
+ /// @param[out] data Buffer to read data from the scratchpad into.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ readScratchpad(Page::span data) const;
+
+ /// @brief
+ /// Read the status of a memory protection block using the Read Status command.
+ /// @param blockNum Block number to to read status of.
+ /// @param[out] protection Receives protection status read from device.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ readBlockProtection(int blockNum, BlockProtection & protection) const;
+
+ /// @brief Write memory segment using the Authenticated Write Memory command.
+ /// @param pageNum Page number for write operation.
+ /// @param segmentNum Segment number within page for write operation.
+ /// @param[in] newData New data to write to the segment.
+ /// @param[in] mac Write MAC computed for this operation.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ writeAuthSegment(int pageNum, int segmentNum, Segment::const_span newData,
+ Page::const_span mac);
+
+ /// @brief Continue an in-progress Authenticated Write Memory command.
+ /// @param[in] newData New data to write to the segment.
+ /// @param[in] mac Write MAC computed for this operation.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ continueWriteAuthSegment(Segment::const_span newData, Page::const_span mac);
+
+ /// @brief
+ /// Read the status of all memory protection blocks using the Read Status command.
+ /// @param[out] protection Receives protection statuses read from device.
+ MaximInterfaceDevices_EXPORT Core::error_code readAllBlockProtection(
+ Core::span<BlockProtection, protectionBlocks> protection) const;
+};
+
+/// Interface to the DS28E15 authenticator.
+class DS28E15 : public DS28EL15 {
+public:
+ DS28E15(Core::Sleep & sleep, Core::OneWireMaster & master,
+ const Core::SelectRom & selectRom)
+ : DS28EL15(sleep, master, selectRom) {}
+
+ /// @brief Perform Load and Lock Secret command on the device.
+ /// @note The secret should already be stored in the scratchpad on the device.
+ /// @param lock
+ /// Prevent further changes to the secret on the device after loading.
+ MaximInterfaceDevices_EXPORT Core::error_code loadSecret(bool lock);
+
+ /// @brief Perform a Compute and Lock Secret command on the device.
+ /// @param pageNum Page number to use as the binding data.
+ /// @param lock
+ /// Prevent further changes to the secret on the device after computing.
+ MaximInterfaceDevices_EXPORT Core::error_code computeSecret(int pageNum,
+ bool lock);
+};
+
+/// Interface to the DS28EL22 (low power) authenticator.
+class DS28EL22 : public DS28E15_22_25 {
+public:
+ // DS28E15_22_25 traits
+ static const int memoryPages = 8;
+ static const int protectionBlocks = 4;
+
+ DS28EL22(Core::Sleep & sleep, Core::OneWireMaster & master,
+ const Core::SelectRom & selectRom)
+ : DS28E15_22_25(sleep, master, selectRom) {}
+
+ /// @brief Perform Write Scratchpad operation on the device.
+ /// @param[in] data Data to write to the scratchpad.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ writeScratchpad(Page::const_span data);
+
+ /// @brief Perform a Read Scratchpad operation on the device.
+ /// @param[out] data Buffer to read data from the scratchpad into.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ readScratchpad(Page::span data) const;
+
+ /// @brief
+ /// Read the status of a memory protection block using the Read Status command.
+ /// @param blockNum Block number to to read status of.
+ /// @param[out] protection Receives protection status read from device.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ readBlockProtection(int blockNum, BlockProtection & protection) const;
+
+ /// @brief Write memory segment using the Authenticated Write Memory command.
+ /// @param pageNum Page number for write operation.
+ /// @param segmentNum Segment number within page for write operation.
+ /// @param[in] newData New data to write to the segment.
+ /// @param[in] mac Write MAC computed for this operation.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ writeAuthSegment(int pageNum, int segmentNum, Segment::const_span newData,
+ Page::const_span mac);
+
+ /// @brief Continue an in-progress Authenticated Write Memory command.
+ /// @param[in] newData New data to write to the segment.
+ /// @param[in] mac Write MAC computed for this operation.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ continueWriteAuthSegment(Segment::const_span newData, Page::const_span mac);
+
+ /// @brief
+ /// Read the status of all memory protection blocks using the Read Status command.
+ /// @param[out] protection Receives protection statuses read from device.
+ MaximInterfaceDevices_EXPORT Core::error_code readAllBlockProtection(
+ Core::span<BlockProtection, protectionBlocks> protection) const;
+};
+
+/// Interface to the DS28E22 authenticator.
+class DS28E22 : public DS28EL22 {
+public:
+ DS28E22(Core::Sleep & sleep, Core::OneWireMaster & master,
+ const Core::SelectRom & selectRom)
+ : DS28EL22(sleep, master, selectRom) {}
+
+ /// @brief Perform Load and Lock Secret command on the device.
+ /// @note The secret should already be stored in the scratchpad on the device.
+ /// @param lock
+ /// Prevent further changes to the secret on the device after loading.
+ MaximInterfaceDevices_EXPORT Core::error_code loadSecret(bool lock);
+
+ /// @brief Perform a Compute and Lock Secret command on the device.
+ /// @param pageNum Page number to use as the binding data.
+ /// @param lock
+ /// Prevent further changes to the secret on the device after computing.
+ MaximInterfaceDevices_EXPORT Core::error_code computeSecret(int pageNum,
+ bool lock);
+};
+
+/// Interface to the DS28EL25 (low power) authenticator.
+class DS28EL25 : public DS28E15_22_25 {
+public:
+ // DS28E15_22_25 traits
+ static const int memoryPages = 16;
+ static const int protectionBlocks = 8;
+
+ DS28EL25(Core::Sleep & sleep, Core::OneWireMaster & master,
+ const Core::SelectRom & selectRom)
+ : DS28E15_22_25(sleep, master, selectRom) {}
+
+ /// @brief Perform Write Scratchpad operation on the device.
+ /// @param[in] data Data to write to the scratchpad.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ writeScratchpad(Page::const_span data);
+
+ /// @brief Perform a Read Scratchpad operation on the device.
+ /// @param[out] data Buffer to read data from the scratchpad into.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ readScratchpad(Page::span data) const;
+
+ /// @brief
+ /// Read the status of a memory protection block using the Read Status command.
+ /// @param blockNum Block number to to read status of.
+ /// @param[out] protection Receives protection status read from device.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ readBlockProtection(int blockNum, BlockProtection & protection) const;
+
+ /// Write memory segment using the Authenticated Write Memory command.
+ /// @param pageNum Page number for write operation.
+ /// @param segmentNum Segment number within page for write operation.
+ /// @param[in] newData New data to write to the segment.
+ /// @param[in] mac Write MAC computed for this operation.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ writeAuthSegment(int pageNum, int segmentNum, Segment::const_span newData,
+ Page::const_span mac);
+
+ /// @brief Continue an in-progress Authenticated Write Memory command.
+ /// @param[in] newData New data to write to the segment.
+ /// @param[in] mac Write MAC computed for this operation.
+ MaximInterfaceDevices_EXPORT Core::error_code
+ continueWriteAuthSegment(Segment::const_span newData, Page::const_span mac);
+
+ /// @brief
+ /// Read the status of all memory protection blocks using the Read Status command.
+ /// @param[out] protection Receives protection statuses read from device.
+ MaximInterfaceDevices_EXPORT Core::error_code readAllBlockProtection(
+ Core::span<BlockProtection, protectionBlocks> protection) const;
+};
+
+/// Interface to the DS28E25 authenticator.
+class DS28E25 : public DS28EL25 {
+public:
+ DS28E25(Core::Sleep & sleep, Core::OneWireMaster & master,
+ const Core::SelectRom & selectRom)
+ : DS28EL25(sleep, master, selectRom) {}
+
+ /// @brief Perform Load and Lock Secret command on the device.
+ /// @note The secret should already be stored in the scratchpad on the device.
+ /// @param lock Prevent further changes to the secret on the device after loading.
+ MaximInterfaceDevices_EXPORT Core::error_code loadSecret(bool lock);
+
+ /// @brief Perform a Compute and Lock Secret command on the device.
+ /// @param pageNum Page number to use as the binding data.
+ /// @param lock
+ /// Prevent further changes to the secret on the device after computing.
+ MaximInterfaceDevices_EXPORT Core::error_code computeSecret(int pageNum,
+ bool lock);
+};
+
+/// Represents the status of a memory protection block.
+class DS28E15_22_25::BlockProtection {
+public:
+ explicit BlockProtection(uint_least8_t status = 0x00) : status(status) {}
+
+ /// Get the byte representation used by the device.
+ uint_least8_t statusByte() const { return status; }
+
+ /// Set the byte representation used by the device.
+ BlockProtection & setStatusByte(uint_least8_t status) {
+ this->status = status;
+ return *this;
+ }
+
+ /// Get the Block Number which is indexed from zero.
+ int blockNum() const { return (status & blockNumMask); }
+
+ /// Set the Block Number which is indexed from zero.
+ MaximInterfaceDevices_EXPORT BlockProtection & setBlockNum(int blockNum);
+
+ /// @brief Get the Read Protection status.
+ /// @returns True if Read Protection is enabled.
+ bool readProtection() const {
+ return ((status & readProtectionMask) == readProtectionMask);
+ }
+
+ /// Set the Read Protection status.
+ MaximInterfaceDevices_EXPORT BlockProtection &
+ setReadProtection(bool readProtection);
+
+ /// @brief Get the Write Protection status.
+ /// @returns True if Write Protection is enabled.
+ bool writeProtection() const {
+ return ((status & writeProtectionMask) == writeProtectionMask);
+ }
+
+ /// Set the Write Protection status.
+ MaximInterfaceDevices_EXPORT BlockProtection &
+ setWriteProtection(bool writeProtection);
+
+ /// @brief Get the EEPROM Emulation Mode status.
+ /// @returns True if EEPROM Emulation Mode is enabled.
+ bool eepromEmulation() const {
+ return ((status & eepromEmulationMask) == eepromEmulationMask);
+ }
+
+ /// Set the EEPROM Emulation Mode status.
+ MaximInterfaceDevices_EXPORT BlockProtection &
+ setEepromEmulation(bool eepromEmulation);
+
+ /// @brief Get the Authentication Protection status.
+ /// @returns True if Authentication Protection is enabled.
+ bool authProtection() const {
+ return ((status & authProtectionMask) == authProtectionMask);
+ }
+
+ /// Set the Authentication Protection status.
+ MaximInterfaceDevices_EXPORT BlockProtection &
+ setAuthProtection(bool authProtection);
+
+ /// @brief Check if no protection options are enabled.
+ /// @returns True if no protection options are enabled.
+ MaximInterfaceDevices_EXPORT bool noProtection() const;
+
+private:
+ static const unsigned int readProtectionMask = 0x80,
+ writeProtectionMask = 0x40,
+ eepromEmulationMask = 0x20,
+ authProtectionMask = 0x10, blockNumMask = 0x0F;
+ uint_least8_t status;
+};
+
+inline bool operator==(DS28E15_22_25::BlockProtection lhs,
+ DS28E15_22_25::BlockProtection rhs) {
+ return lhs.statusByte() == rhs.statusByte();
+}
+
+inline bool operator!=(DS28E15_22_25::BlockProtection lhs,
+ DS28E15_22_25::BlockProtection rhs) {
+ return !operator==(lhs, rhs);
+}
+
+/// Format data to hash for an Authenticated Write to a memory segment.
+class DS28E15_22_25::SegmentWriteMacData {
+public:
+ typedef Core::array_span<uint_least8_t, 20> Result;
+
+ SegmentWriteMacData() : result_() {}
+
+ /// Formatted data result.
+ Result::const_span result() const { return result_; }
+
+ /// @name ROM ID
+ /// @brief 1-Wire ROM ID of the device.
+ /// @{
+
+ /// Get mutable ROM ID.
+ Core::RomId::span romId() {
+ return make_span(result_).subspan<romIdIdx, Core::RomId::size>();
+ }
+
+ /// Get immutable ROM ID.
+ Core::RomId::const_span romId() const {
+ return const_cast<SegmentWriteMacData &>(*this).romId();
+ }
+
+ /// Set ROM ID.
+ SegmentWriteMacData & setRomId(Core::RomId::const_span romId) {
+ copy(romId, this->romId());
+ return *this;
+ }
+
+ /// @}
+
+ /// @name MAN ID
+ /// @brief Manufacturer ID of the device.
+ /// @{
+
+ /// Get mutable MAN ID.
+ Core::ManId::span manId() {
+ return make_span(result_).subspan<manIdIdx, Core::ManId::size>();
+ }
+
+ /// Get immutable MAN ID.
+ Core::ManId::const_span manId() const {
+ return const_cast<SegmentWriteMacData &>(*this).manId();
+ }
+
+ /// Set MAN ID.
+ SegmentWriteMacData & setManId(Core::ManId::const_span manId) {
+ copy(manId, this->manId());
+ return *this;
+ }
+
+ /// @}
+
+ /// @name Page number
+ /// @brief Page number for write operation.
+ /// @{
+
+ /// Get page number.
+ int pageNum() const { return result_[pageNumIdx]; }
+
+ /// Set page number.
+ SegmentWriteMacData & setPageNum(int pageNum) {
+ result_[pageNumIdx] = pageNum;
+ return *this;
+ }
+
+ /// @}
+
+ /// @name Segment number
+ /// @brief Segment number within page for write operation.
+ /// @{
+
+ /// Get segment number.
+ int segmentNum() const { return result_[segmentNumIdx]; }
+
+ /// Set segment number.
+ SegmentWriteMacData & setSegmentNum(int segmentNum) {
+ result_[segmentNumIdx] = segmentNum;
+ return *this;
+ }
+
+ /// @}
+
+ /// @name Old data
+ /// @brief Existing data contained in the segment.
+ /// @{
+
+ /// Get mutable old data.
+ Segment::span oldData() {
+ return make_span(result_).subspan<oldDataIdx, Segment::size>();
+ }
+
+ /// Get immutable old data.
+ Segment::const_span oldData() const {
+ return const_cast<SegmentWriteMacData &>(*this).oldData();
+ }
+
+ /// Set old data.
+ SegmentWriteMacData & setOldData(Segment::const_span oldData) {
+ copy(oldData, this->oldData());
+ return *this;
+ }
+
+ /// @}
+
+ /// @name New data
+ /// @brief New data to write to the segment.
+ /// @{
+
+ /// Get mutable new data.
+ Segment::span newData() {
+ return make_span(result_).subspan<newDataIdx, Segment::size>();
+ }
+
+ /// Get immutable new data.
+ Segment::const_span newData() const {
+ return const_cast<SegmentWriteMacData &>(*this).newData();
+ }
+
+ /// Set new data.
+ SegmentWriteMacData & setNewData(Segment::const_span newData) {
+ copy(newData, this->newData());
+ return *this;
+ }
+
+ /// @}
+
+private:
+ typedef Result::span::index_type index;
+
+ static const index romIdIdx = 0;
+ static const index manIdIdx = romIdIdx + Core::RomId::size;
+ static const index pageNumIdx = manIdIdx + Core::ManId::size;
+ static const index segmentNumIdx = pageNumIdx + 1;
+ static const index oldDataIdx = segmentNumIdx + 1;
+ static const index newDataIdx = oldDataIdx + Segment::size;
+
+ Result::array result_;
+};
+
+/// Format data to hash for an Authenticated Write to a memory protection block.
+class DS28E15_22_25::ProtectionWriteMacData {
+public:
+ typedef Core::array_span<uint_least8_t, 20> Result;
+
+ MaximInterfaceDevices_EXPORT ProtectionWriteMacData();
+
+ /// Formatted data result.
+ Result::const_span result() const { return result_; }
+
+ /// @name ROM ID
+ /// @brief 1-Wire ROM ID of the device.
+ /// @{
+
+ /// Get mutable ROM ID.
+ Core::RomId::span romId() {
+ return make_span(result_).subspan<romIdIdx, Core::RomId::size>();
+ }
+
+ /// Get immutable ROM ID.
+ Core::RomId::const_span romId() const {
+ return const_cast<ProtectionWriteMacData &>(*this).romId();
+ }
+
+ /// Set ROM ID.
+ ProtectionWriteMacData & setRomId(Core::RomId::const_span romId) {
+ copy(romId, this->romId());
+ return *this;
+ }
+
+ /// @}
+
+ /// @name MAN ID
+ /// @brief Manufacturer ID of the device.
+ /// @{
+
+ /// Get mutable MAN ID.
+ Core::ManId::span manId() {
+ return make_span(result_).subspan<manIdIdx, Core::ManId::size>();
+ }
+
+ /// Get immutable MAN ID.
+ Core::ManId::const_span manId() const {
+ return const_cast<ProtectionWriteMacData &>(*this).manId();
+ }
+
+ /// Set MAN ID.
+ ProtectionWriteMacData & setManId(Core::ManId::const_span manId) {
+ copy(manId, this->manId());
+ return *this;
+ }
+
+ /// @}
+
+ /// @name Old protection
+ /// @brief Existing protection status in device.
+ /// @{
+
+ /// Get old protection.
+ BlockProtection oldProtection() const { return oldProtection_; }
+
+ /// Set old protection.
+ MaximInterfaceDevices_EXPORT ProtectionWriteMacData &
+ setOldProtection(BlockProtection oldProtection);
+
+ /// @}
+
+ /// @name New protection
+ /// @brief New protection status to write.
+ /// @{
+
+ /// Get new protection.
+ BlockProtection newProtection() const { return newProtection_; }
+
+ /// Set new protection.
+ MaximInterfaceDevices_EXPORT ProtectionWriteMacData &
+ setNewProtection(BlockProtection newProtection);
+
+ /// @}
+
+private:
+ typedef Result::span::index_type index;
+
+ static const index romIdIdx = 0;
+ static const index manIdIdx = romIdIdx + Core::RomId::size;
+ static const index blockNumIdx = manIdIdx + Core::ManId::size;
+ static const index oldProtectionIdx = blockNumIdx + 2;
+ static const index newProtectionIdx = oldProtectionIdx + 4;
+
+ Result::array result_;
+ BlockProtection oldProtection_;
+ BlockProtection newProtection_;
+};
+
+/// @brief
+/// Format data to hash for device authentication or computing the next secret
+/// from the existing secret.
+class DS28E15_22_25::AuthenticationData {
+public:
+ typedef Core::array_span<uint_least8_t, 76> Result;
+
+ AuthenticationData() : result_() {}
+
+ /// Formatted data result.
+ Result::const_span result() const { return result_; }
+
+ /// @name Page
+ /// @brief Data from a device memory page.
+ /// @{
+
+ /// Get mutable page.
+ Page::span page() {
+ return make_span(result_).subspan<pageIdx, Page::size>();
+ }
+
+ /// Get immutable page.
+ Page::const_span page() const {
+ return const_cast<AuthenticationData &>(*this).page();
+ }
+
+ /// Set page.
+ AuthenticationData & setPage(Page::const_span page) {
+ copy(page, this->page());
+ return *this;
+ }
+
+ /// @}
+
+ /// @name Scratchpad
+ /// @brief
+ /// Data from device scratchpad used as a random challenge in device
+ /// authentication and a partial secret in secret computation.
+ /// @{
+
+ /// Get mutable scratchpad.
+ Page::span scratchpad() {
+ return make_span(result_).subspan<scratchpadIdx, Page::size>();
+ }
+
+ /// Get immutable scratchpad.
+ Page::const_span scratchpad() const {
+ return const_cast<AuthenticationData &>(*this).scratchpad();
+ }
+
+ /// Set scratchpad.
+ AuthenticationData & setScratchpad(Page::const_span scratchpad) {
+ copy(scratchpad, this->scratchpad());
+ return *this;
+ }
+
+ /// @}
+
+ /// @name ROM ID
+ /// @brief 1-Wire ROM ID of the device.
+ /// @{
+
+ /// Get mutable ROM ID.
+ Core::RomId::span romId() {
+ return make_span(result_).subspan<romIdIdx, Core::RomId::size>();
+ }
+
+ /// Get immutable ROM ID.
+ Core::RomId::const_span romId() const {
+ return const_cast<AuthenticationData &>(*this).romId();
+ }
+
+ /// Set ROM ID.
+ AuthenticationData & setRomId(Core::RomId::const_span romId) {
+ copy(romId, this->romId());
+ return *this;
+ }
+
+ /// Set ROM ID for use in anonymous mode.
+ MaximInterfaceDevices_EXPORT AuthenticationData & setAnonymousRomId();
+
+ /// @}
+
+ /// @name MAN ID
+ /// @brief Manufacturer ID of the device.
+ /// @{
+
+ /// Get mutable MAN ID.
+ Core::ManId::span manId() {
+ return make_span(result_).subspan<manIdIdx, Core::ManId::size>();
+ }
+
+ /// Get immutable MAN ID.
+ Core::ManId::const_span manId() const {
+ return const_cast<AuthenticationData &>(*this).manId();
+ }
+
+ /// Set MAN ID.
+ AuthenticationData & setManId(Core::ManId::const_span manId) {
+ copy(manId, this->manId());
+ return *this;
+ }
+
+ /// @}
+
+ /// @name Page number
+ /// @brief Number of the page to use data from.
+ /// @{
+
+ /// Get page number.
+ int pageNum() const { return result_[pageNumIdx]; }
+
+ /// Set page number.
+ AuthenticationData & setPageNum(int pageNum) {
+ result_[pageNumIdx] = pageNum;
+ return *this;
+ }
+
+ /// @}
+
+private:
+ typedef Result::span::index_type index;
+
+ static const index pageIdx = 0;
+ static const index scratchpadIdx = pageIdx + Page::size;
+ static const index romIdIdx = scratchpadIdx + Page::size;
+ static const index manIdIdx = romIdIdx + Core::RomId::size;
+ static const index pageNumIdx = manIdIdx + Core::ManId::size;
+
+ Result::array result_;
+};
+
+} // namespace MaximInterfaceDevices
+
+#endif