From 6decce705e0bff8fe61a555709b7c58ae44fc56f Mon Sep 17 00:00:00 2001 From: kangping Date: Mon, 29 Apr 2024 21:32:39 +0800 Subject: [PATCH] [API] remove the PanId struct It's an overkill to define a dedicated class/struct for a simple `uint16_t` just for pretty print to json in HEX string. --- include/commissioner/error.hpp | 11 +++++- include/commissioner/network_data.hpp | 22 +---------- src/app/cli/interpreter.cpp | 29 ++++---------- src/app/cli/interpreter_test.cpp | 6 ++- src/app/commissioner_app.cpp | 4 +- src/app/commissioner_app.hpp | 4 +- src/app/commissioner_app_dummy.cpp | 4 +- src/app/commissioner_app_mock.hpp | 4 +- src/app/json.cpp | 25 ++++++------- src/app/ps/persistent_storage_json.cpp | 4 +- src/app/ps/registry.cpp | 26 +++++++++---- src/app/ps/registry_entries.cpp | 7 ++-- src/app/ps/registry_entries.hpp | 2 +- src/common/error.cpp | 2 +- src/common/utils.hpp | 24 ++++++++++++ src/java/commissioner.i | 4 +- src/library/commissioner_impl.cpp | 2 +- src/library/network_data.cpp | 52 -------------------------- 18 files changed, 92 insertions(+), 140 deletions(-) diff --git a/include/commissioner/error.hpp b/include/commissioner/error.hpp index 5771eed55..9b5dba768 100644 --- a/include/commissioner/error.hpp +++ b/include/commissioner/error.hpp @@ -264,14 +264,21 @@ inline bool operator!=(const ErrorCode &aErrorCode, const Error &aError) return !(aErrorCode == aError); } +std::string ErrorCodeToString(ErrorCode code); + /** * Allows pretty-print in unit tests. * * See https://google.github.io/googletest/advanced.html#teaching-googletest-how-to-print-your-values */ -inline void PrintTo(const Error &error, std::ostream *os) +inline void PrintTo(const Error &aError, std::ostream *os) +{ + *os << aError.ToString(); +} + +inline void PrintTo(ErrorCode aErrorCode, std::ostream *os) { - *os << error.ToString(); + *os << ErrorCodeToString(aErrorCode); } } // namespace commissioner diff --git a/include/commissioner/network_data.hpp b/include/commissioner/network_data.hpp index fb488b6a4..9628f2cae 100644 --- a/include/commissioner/network_data.hpp +++ b/include/commissioner/network_data.hpp @@ -249,26 +249,6 @@ enum SecurityPolicyFlags kSecurityPolicyMask_VR = 1 << 5 | 1 << 6 | 1 << 7, /// Protocol version }; -/** - * A PAN identifier. - */ -struct PanId -{ - static constexpr uint64_t kEmptyPanId = 0; - - uint16_t mValue; - explicit PanId(uint16_t aValue); - PanId(const PanId &aOther) = default; - PanId(); - - PanId &operator=(const PanId &aValue) = default; - PanId &operator=(uint16_t aValue); - explicit operator uint16_t() const; - explicit operator std::string() const; - - Error FromHex(const std::string &aInput); -}; - /** * @brief The Active Operational Dataset of the Thread Network Data. * @@ -289,7 +269,7 @@ struct ActiveOperationalDataset ByteArray mMeshLocalPrefix; ByteArray mNetworkMasterKey; std::string mNetworkName; - PanId mPanId; + uint16_t mPanId; ByteArray mPSKc; SecurityPolicy mSecurityPolicy; diff --git a/src/app/cli/interpreter.cpp b/src/app/cli/interpreter.cpp index e38b1071c..ed10f2c24 100644 --- a/src/app/cli/interpreter.cpp +++ b/src/app/cli/interpreter.cpp @@ -121,6 +121,8 @@ namespace ot { namespace commissioner { using ot::commissioner::persistent_storage::Network; +using ot::commissioner::utils::Hex; +using ot::commissioner::utils::ParseInteger; namespace { /** @@ -349,23 +351,6 @@ template static std::string ToHex(T aInteger) return "0x" + utils::Hex(utils::Encode(aInteger)); }; -template static Error ParseInteger(T &aInteger, const std::string &aStr) -{ - Error error; - uint64_t integer; - char *endPtr = nullptr; - - integer = strtoull(aStr.c_str(), &endPtr, 0); - - VerifyOrExit(endPtr != nullptr && endPtr > aStr.c_str(), - error = ERROR_INVALID_ARGS("{} is not a valid integer", aStr)); - - aInteger = integer; - -exit: - return error; -} - static inline std::string ToLower(const std::string &aStr) { return utils::ToLower(aStr); @@ -2100,7 +2085,7 @@ Interpreter::Value Interpreter::ProcessOpDatasetJob(CommissionerAppPtr &aCommiss } else if (CaseInsensitiveEqual(aExpr[2], "panid")) { - PanId panid; + uint16_t panid; if (isSet) { uint32_t delay; @@ -2112,7 +2097,7 @@ Interpreter::Value Interpreter::ProcessOpDatasetJob(CommissionerAppPtr &aCommiss else { SuccessOrExit(value = aCommissioner->GetPanId(panid)); - value = std::string(panid); + value = Hex(panid); } } else if (CaseInsensitiveEqual(aExpr[2], "pskc")) @@ -2177,7 +2162,7 @@ Interpreter::Value Interpreter::ProcessOpDatasetJob(CommissionerAppPtr &aCommiss { if ((dataset.mPresentFlags & ActiveOperationalDataset::kPanIdBit) != 0) { - nwkAliases.push_back(fmt::format(FMT_STRING("0x{:04X}"), dataset.mPanId.mValue)); + nwkAliases.push_back(Hex(dataset.mPanId)); } else if ((dataset.mPresentFlags & ActiveOperationalDataset::kNetworkNameBit) != 0) { @@ -2215,10 +2200,10 @@ Interpreter::Value Interpreter::ProcessOpDatasetJob(CommissionerAppPtr &aCommiss nwk.mName = AODS_FIELD_IF_IS_SET(NetworkName, ""); nwk.mXpan = AODS_FIELD_IF_IS_SET(ExtendedPanId, XpanId{}); nwk.mChannel = AODS_FIELD_IF_IS_SET(Channel, (Channel{0, 0})).mNumber; - nwk.mPan = AODS_FIELD_IF_IS_SET(PanId, PanId{}); + nwk.mPan = AODS_FIELD_IF_IS_SET(PanId, 0); if ((dataset.mPresentFlags & ActiveOperationalDataset::kPanIdBit) == 0) { - nwk.mPan = PanId::kEmptyPanId; + nwk.mPan = 0; } else { diff --git a/src/app/cli/interpreter_test.cpp b/src/app/cli/interpreter_test.cpp index 7cf36b602..6305b9d1e 100644 --- a/src/app/cli/interpreter_test.cpp +++ b/src/app/cli/interpreter_test.cpp @@ -56,6 +56,7 @@ #include "commissioner/defines.hpp" #include "commissioner/error.hpp" #include "commissioner/network_data.hpp" +#include "common/utils.hpp" #include "fmt/core.h" #include "gmock/gmock-matchers.h" #include "gmock/gmock-spec-builders.h" @@ -63,6 +64,7 @@ #include "nlohmann/json.hpp" using namespace ot::commissioner; +using namespace ot::commissioner::utils; using namespace ot::commissioner::persistent_storage; using testing::_; @@ -1802,7 +1804,7 @@ TEST_F(InterpreterTestSuite, PC_OpdatasetGetActive) PersistentStorage::Status::kSuccess); Network nwk; EXPECT_EQ(ctx.mRegistry->mStorage->Get(nwk_id, nwk), PersistentStorage::Status::kSuccess); - EXPECT_EQ((std::string)nwk.mPan, "0x0000"); + EXPECT_EQ(utils::Hex(nwk.mPan), "0x0000"); EXPECT_CALL(*ctx.mDefaultCommissionerObject, GetActiveDataset(_, _)) .Times(2) @@ -1821,7 +1823,7 @@ TEST_F(InterpreterTestSuite, PC_OpdatasetGetActive) EXPECT_TRUE(value.HasNoError()); EXPECT_EQ(ctx.mRegistry->mStorage->Get(nwk_id, nwk), PersistentStorage::Status::kSuccess); - EXPECT_EQ(nwk.mPan.mValue, 0x0001); + EXPECT_EQ(nwk.mPan, 0x0001); EXPECT_EQ(system("rm -f ./aods.json"), 0); EXPECT_NE(PathExists("./aods.json").GetCode(), ErrorCode::kNone); diff --git a/src/app/commissioner_app.cpp b/src/app/commissioner_app.cpp index 6eb7cb2be..aed66c5df 100644 --- a/src/app/commissioner_app.cpp +++ b/src/app/commissioner_app.cpp @@ -680,7 +680,7 @@ Error CommissionerApp::SetNetworkName(const std::string &aNetworkName) return error; } -Error CommissionerApp::GetPanId(PanId &aPanId) +Error CommissionerApp::GetPanId(uint16_t &aPanId) { Error error; @@ -696,7 +696,7 @@ Error CommissionerApp::GetPanId(PanId &aPanId) return error; } -Error CommissionerApp::SetPanId(PanId aPanId, MilliSeconds aDelay) +Error CommissionerApp::SetPanId(uint16_t aPanId, MilliSeconds aDelay) { Error error; PendingOperationalDataset pendingDataset; diff --git a/src/app/commissioner_app.hpp b/src/app/commissioner_app.hpp index 288a0933c..fe08d5dfe 100644 --- a/src/app/commissioner_app.hpp +++ b/src/app/commissioner_app.hpp @@ -202,8 +202,8 @@ class CommissionerApp : public CommissionerHandler MOCKABLE Error SetNetworkMasterKey(const ByteArray &aMasterKey, MilliSeconds aDelay); MOCKABLE Error GetNetworkName(std::string &aNetworkName) const; MOCKABLE Error SetNetworkName(const std::string &aNetworkName); - MOCKABLE Error GetPanId(PanId &aPanId); - MOCKABLE Error SetPanId(PanId aPanId, MilliSeconds aDelay); + MOCKABLE Error GetPanId(uint16_t &aPanId); + MOCKABLE Error SetPanId(uint16_t aPanId, MilliSeconds aDelay); MOCKABLE Error GetPSKc(ByteArray &aPSKc) const; MOCKABLE Error SetPSKc(const ByteArray &aPSKc); diff --git a/src/app/commissioner_app_dummy.cpp b/src/app/commissioner_app_dummy.cpp index f9024be2e..248ab00ac 100644 --- a/src/app/commissioner_app_dummy.cpp +++ b/src/app/commissioner_app_dummy.cpp @@ -303,13 +303,13 @@ Error CommissionerApp::SetNetworkName(const std::string &aNetworkName) return Error{}; } -Error CommissionerApp::GetPanId(PanId &aPanId) +Error CommissionerApp::GetPanId(uint16_t &aPanId) { UNUSED(aPanId); return Error{}; } -Error CommissionerApp::SetPanId(PanId aPanId, MilliSeconds aDelay) +Error CommissionerApp::SetPanId(uint16_t aPanId, MilliSeconds aDelay) { UNUSED(aPanId); UNUSED(aDelay); diff --git a/src/app/commissioner_app_mock.hpp b/src/app/commissioner_app_mock.hpp index 5ce32476c..5b31862f6 100644 --- a/src/app/commissioner_app_mock.hpp +++ b/src/app/commissioner_app_mock.hpp @@ -104,8 +104,8 @@ class CommissionerAppMock : public ::ot::commissioner::CommissionerApp MOCK_METHOD(Error, SetNetworkMasterKey, (const ByteArray &, MilliSeconds)); MOCK_METHOD(Error, GetNetworkName, (std::string &), (const)); MOCK_METHOD(Error, SetNetworkName, (const std::string &)); - MOCK_METHOD(Error, GetPanId, (PanId &)); - MOCK_METHOD(Error, SetPanId, (PanId, MilliSeconds)); + MOCK_METHOD(Error, GetPanId, (uint16_t &)); + MOCK_METHOD(Error, SetPanId, (uint16_t, MilliSeconds)); MOCK_METHOD(Error, GetPSKc, (ByteArray &), (const)); MOCK_METHOD(Error, SetPSKc, (const ByteArray &)); MOCK_METHOD(Error, GetSecurityPolicy, (SecurityPolicy &), (const)); diff --git a/src/app/json.cpp b/src/app/json.cpp index d81323583..140a3d980 100644 --- a/src/app/json.cpp +++ b/src/app/json.cpp @@ -417,18 +417,6 @@ static void from_json(const Json &aJson, SecurityPolicy &aSecurityPolicy) #undef SET } -static void to_json(Json &aJson, const ot::commissioner::PanId &aPanId) -{ - aJson = std::string(aPanId); -} - -static void from_json(const Json &aJson, ot::commissioner::PanId &aPanId) -{ - std::string panIdStr; - panIdStr = aJson.get(); - SuccessOrThrow(aPanId.FromHex(panIdStr)); -} - static void to_json(Json &aJson, const ActiveOperationalDataset &aDataset) { #define SET_IF_PRESENT(name) \ @@ -447,9 +435,13 @@ static void to_json(Json &aJson, const ActiveOperationalDataset &aDataset) aJson["MeshLocalPrefix"] = Ipv6PrefixToString(aDataset.mMeshLocalPrefix); }; + if (aDataset.mPresentFlags & ActiveOperationalDataset::kPanIdBit) + { + aJson["PanId"] = utils::Hex(aDataset.mPanId); + } + SET_IF_PRESENT(NetworkMasterKey); SET_IF_PRESENT(NetworkName); - SET_IF_PRESENT(PanId); SET_IF_PRESENT(PSKc); SET_IF_PRESENT(SecurityPolicy); @@ -484,9 +476,14 @@ static void from_json(const Json &aJson, ActiveOperationalDataset &aDataset) aDataset.mPresentFlags |= ActiveOperationalDataset::kMeshLocalPrefixBit; }; + if (aJson.contains("PanId")) + { + SuccessOrThrow(utils::ParseInteger(aDataset.mPanId, aJson["PanId"])); + aDataset.mPresentFlags |= ActiveOperationalDataset::kPanIdBit; + } + SET_IF_PRESENT(NetworkMasterKey); SET_IF_PRESENT(NetworkName); - SET_IF_PRESENT(PanId); SET_IF_PRESENT(PSKc); SET_IF_PRESENT(SecurityPolicy); diff --git a/src/app/ps/persistent_storage_json.cpp b/src/app/ps/persistent_storage_json.cpp index 5f1539615..177e7562b 100644 --- a/src/app/ps/persistent_storage_json.cpp +++ b/src/app/ps/persistent_storage_json.cpp @@ -372,7 +372,7 @@ PersistentStorage::Status PersistentStorageJson::Lookup(Network const &aValue, s (aValue.mDomainId.mId == EMPTY_ID || (el.mDomainId.mId == aValue.mDomainId.mId)) && (aValue.mName.empty() || (aValue.mName == el.mName)) && (aValue.mXpan.mValue == XpanId::kEmptyXpanId || aValue.mXpan == el.mXpan) && - (aValue.mPan.mValue == PanId::kEmptyPanId || (aValue.mPan.mValue == el.mPan.mValue)) && + (aValue.mPan == 0 || (aValue.mPan == el.mPan)) && (aValue.mMlp.empty() || CaseInsensitiveEqual(aValue.mMlp, el.mMlp)) && (aValue.mChannel == 0 || (aValue.mChannel == el.mChannel)); @@ -477,7 +477,7 @@ PersistentStorage::Status PersistentStorageJson::LookupAny(Network const &aValue (aValue.mDomainId.mId == EMPTY_ID || (el.mDomainId.mId == aValue.mDomainId.mId)) || (aValue.mName.empty() || (aValue.mName == el.mName)) || (aValue.mXpan.mValue == XpanId::kEmptyXpanId || aValue.mXpan == el.mXpan) || - (aValue.mPan.mValue == PanId::kEmptyPanId || (aValue.mPan.mValue == el.mPan.mValue)) || + (aValue.mPan == 0 || (aValue.mPan == el.mPan)) || (aValue.mMlp.empty() || CaseInsensitiveEqual(aValue.mMlp, el.mMlp)) || (aValue.mChannel == 0 || (aValue.mChannel == el.mChannel)); diff --git a/src/app/ps/registry.cpp b/src/app/ps/registry.cpp index eef177afe..06e9cfcc3 100644 --- a/src/app/ps/registry.cpp +++ b/src/app/ps/registry.cpp @@ -484,23 +484,32 @@ Registry::Status Registry::GetNetworksByAliases(const StringArray &aAliases, } else { - Network nwk; - XpanId xpid; - PanId pid; + Network nwk; + XpanId xpid; + uint16_t pid; status = Registry::Status::kNotFound; if (xpid.FromHex(alias) == ERROR_NONE) { status = GetNetworkByXpan(xpid, nwk); } + if (status != Registry::Status::kSuccess) { status = GetNetworkByName(alias, nwk); } - if (status != Registry::Status::kSuccess && pid.FromHex(alias) == ERROR_NONE) + + if (status != Registry::Status::kSuccess) { - status = GetNetworkByPan(alias, nwk); + bool hasHexPrefix = utils::ToLower(alias.substr(0, 2)) != "0x"; + std::string aliasAsPanId = std::string(hasHexPrefix ? "0x" : "") + alias; + + if (utils::ParseInteger(pid, aliasAsPanId) == ERROR_NONE) + { + status = GetNetworkByPan(aliasAsPanId, nwk); + } } + if (status == Registry::Status::kSuccess) { networks.push_back(nwk); @@ -608,9 +617,10 @@ Registry::Status Registry::GetNetworkByName(const std::string &aName, Network &a Registry::Status Registry::GetNetworkByPan(const std::string &aPan, Network &aRet) { - Network nwk{}; - PanId panId; - if (panId.FromHex(aPan).GetCode() != ErrorCode::kNone) + Network nwk{}; + uint16_t panId = 0; + + if (utils::ParseInteger(panId, aPan).GetCode() != ErrorCode::kNone) { return Registry::Status::kError; } diff --git a/src/app/ps/registry_entries.cpp b/src/app/ps/registry_entries.cpp index 2ee214942..a6ec8f58a 100644 --- a/src/app/ps/registry_entries.cpp +++ b/src/app/ps/registry_entries.cpp @@ -156,7 +156,7 @@ void to_json(json &aJson, const Network &aValue) aJson = json{{JSON_ID, aValue.mId}, {JSON_DOM_REF, aValue.mDomainId}, {JSON_NAME, aValue.mName}, - {JSON_PAN, std::string(aValue.mPan)}, + {JSON_PAN, utils::Hex(aValue.mPan)}, {JSON_XPAN, std::string(aValue.mXpan)}, {JSON_CHANNEL, aValue.mChannel}, {JSON_MLP, aValue.mMlp}, @@ -165,13 +165,14 @@ void to_json(json &aJson, const Network &aValue) void from_json(const json &aJson, Network &aValue) { + std::string hexStr; + aJson.at(JSON_ID).get_to(aValue.mId); aJson.at(JSON_DOM_REF).get_to(aValue.mDomainId); aJson.at(JSON_NAME).get_to(aValue.mName); - std::string hexStr; aJson.at(JSON_PAN).get_to(hexStr); - SuccessOrThrow(aValue.mPan.FromHex(hexStr)); + SuccessOrThrow(utils::ParseInteger(aValue.mPan, hexStr)); aJson.at(JSON_XPAN).get_to(hexStr); SuccessOrThrow(aValue.mXpan.FromHex(hexStr)); diff --git a/src/app/ps/registry_entries.hpp b/src/app/ps/registry_entries.hpp index cf69e8c4e..b62418302 100644 --- a/src/app/ps/registry_entries.hpp +++ b/src/app/ps/registry_entries.hpp @@ -140,7 +140,7 @@ struct Network std::string mName; /**< network name */ XpanId mXpan; /**< Extended PAN_ID */ unsigned int mChannel; /**< network channel */ - PanId mPan; /**< PAN_ID */ + uint16_t mPan; /**< PAN_ID */ std::string mMlp; /**< Mesh-local prefix */ int mCcm; /**< Commercial commissioning mode;<0 not set, * 0 false, >0 true */ diff --git a/src/common/error.cpp b/src/common/error.cpp index 37c0f6acb..7467cd9ad 100644 --- a/src/common/error.cpp +++ b/src/common/error.cpp @@ -42,7 +42,7 @@ namespace ot { namespace commissioner { // Returns the std::string representation of the status code. -static std::string ErrorCodeToString(ErrorCode code) +std::string ErrorCodeToString(ErrorCode code) { switch (code) { diff --git a/src/common/utils.hpp b/src/common/utils.hpp index fa900ffaf..336e3db7b 100644 --- a/src/common/utils.hpp +++ b/src/common/utils.hpp @@ -42,6 +42,7 @@ #include "commissioner/defines.hpp" #include "commissioner/error.hpp" +#include "common/error_macros.hpp" #define ASSERT(aCondition) \ do \ @@ -188,6 +189,29 @@ std::string ToLower(const std::string &aStr); bool CaseInsensitiveEqual(const std::string &aLhs, const std::string &aRhs); +/** Returns the Hex string of a `uint16_t` integer with zero paddings. */ +inline static std::string Hex(uint16_t aInteger) +{ + return fmt::format(FMT_STRING("0x{:04X}"), aInteger); +} + +template static Error ParseInteger(T &aInteger, const std::string &aStr) +{ + Error error; + uint64_t integer; + char *endPtr = nullptr; + + integer = strtoull(aStr.c_str(), &endPtr, 0); + + VerifyOrExit(endPtr != nullptr && endPtr > aStr.c_str(), + error = ERROR_INVALID_ARGS("{} is not a valid integer", aStr)); + + aInteger = integer; + +exit: + return error; +} + } // namespace utils } // namespace commissioner diff --git a/src/java/commissioner.i b/src/java/commissioner.i index 4d65d5aa2..1847cbe44 100644 --- a/src/java/commissioner.i +++ b/src/java/commissioner.i @@ -169,7 +169,7 @@ namespace commissioner { uint32_t aTimeout); %ignore Commissioner::RequestToken(Handler aHandler, const std::string &aAddr, uint16_t aPort); - // Remove operators and move constructor of Error, XpanId, PanId. + // Remove operators and move constructor of Error, XpanId. %ignore Error::operator=(const Error &aError); %ignore Error::Error(Error &&aError) noexcept; %ignore Error::operator=(Error &&aError) noexcept; @@ -179,8 +179,6 @@ namespace commissioner { %ignore XpanId::operator!=(const uint64_t aOther) const; %ignore XpanId::operator<(const XpanId aOther) const; %ignore XpanId::operator std::string() const; - %ignore PanId::operator=(uint16_t aValue); - %ignore PanId::operator uint16_t() const; %ignore operator==(const Error &aError, const ErrorCode &aErrorCode); %ignore operator!=(const Error &aError, const ErrorCode &aErrorCode); %ignore operator==(const ErrorCode &aErrorCode, const Error &aError); diff --git a/src/library/commissioner_impl.cpp b/src/library/commissioner_impl.cpp index de96b1586..e39284132 100644 --- a/src/library/commissioner_impl.cpp +++ b/src/library/commissioner_impl.cpp @@ -1647,7 +1647,7 @@ Error CommissionerImpl::EncodeActiveOperationalDataset(coap::Request if (aDataset.mPresentFlags & ActiveOperationalDataset::kPanIdBit) { - SuccessOrExit(error = AppendTlv(aRequest, {tlv::Type::kPanId, aDataset.mPanId.mValue})); + SuccessOrExit(error = AppendTlv(aRequest, {tlv::Type::kPanId, aDataset.mPanId})); } if (aDataset.mPresentFlags & ActiveOperationalDataset::kPSKcBit) diff --git a/src/library/network_data.cpp b/src/library/network_data.cpp index cbb8cc396..408f1835e 100644 --- a/src/library/network_data.cpp +++ b/src/library/network_data.cpp @@ -188,58 +188,6 @@ Error XpanId::FromHex(const std::string &aInput) return ERROR_NONE; } -PanId::PanId(uint16_t aValue) - : mValue(aValue) -{ -} - -PanId::PanId() - : PanId(kEmptyPanId) -{ -} - -PanId &PanId::operator=(uint16_t aValue) -{ - mValue = aValue; - return *this; -} - -PanId::operator uint16_t() const -{ - return mValue; -} - -PanId::operator std::string() const -{ - std::ostringstream value; - value << "0x" << std::uppercase << std::hex << std::setw(sizeof(mValue) * 2) << std::setfill('0') << mValue; - return value.str(); -} - -Error PanId::FromHex(const std::string &aInput) -{ - mValue = 0; - - std::string input = aInput; - if (utils::ToLower(input.substr(0, 2)) == "0x") - { - input = input.substr(2); - } - if (input.empty() || input.length() > 4) - return ERROR_BAD_FORMAT("{}: wrong PAN ID string length", input.length()); - for (auto c : input) - { - if (!std::isxdigit(c)) - { - return ERROR_BAD_FORMAT("{}: not a hex string", input); - } - } - - std::istringstream is(input); - is >> std::hex >> mValue; - return ERROR_NONE; -} - ActiveOperationalDataset::ActiveOperationalDataset() : mActiveTimestamp(Timestamp::Cur()) , mPresentFlags(kActiveTimestampBit)