diff --git a/include/openthread-types.h b/include/openthread-types.h index 9dca52b36..f867847e8 100644 --- a/include/openthread-types.h +++ b/include/openthread-types.h @@ -362,6 +362,18 @@ typedef enum otMleAttachFilter kMleAttachBetterPartition = 2, ///< Attach to a better (i.e. higher weight/partition id) Thread partition. } otMleAttachFilter; +/** + * This structure represents a whitelist entry. + * + */ +typedef struct otMacWhitelistEntry +{ + otExtAddress mExtAddress; ///< IEEE 802.15.4 Extended Address + int8_t mRssi; ///< RSSI value + bool mValid : 1; ///< Indicates whether or not the whitelist entry is vaild + bool mFixedRssi : 1; ///< Indicates whether or not the RSSI value is fixed. +} otMacWhitelistEntry; + /** * @} * diff --git a/include/openthread.h b/include/openthread.h index e2196373f..82bd870c2 100644 --- a/include/openthread.h +++ b/include/openthread.h @@ -732,6 +732,7 @@ ThreadError otReleaseRouterId(uint8_t aRouterId); * @sa otAddMacWhitelistRssi * @sa otRemoveMacWhitelist * @sa otClearMacWhitelist + * @sa otGetMacWhitelistEntry * @sa otDisableMacWhitelist * @sa otEnableMacWhitelist */ @@ -749,6 +750,7 @@ ThreadError otAddMacWhitelist(const uint8_t *aExtAddr); * @sa otAddMacWhitelistRssi * @sa otRemoveMacWhitelist * @sa otClearMacWhitelist + * @sa otGetMacWhitelistEntry * @sa otDisableMacWhitelist * @sa otEnableMacWhitelist */ @@ -762,17 +764,31 @@ ThreadError otAddMacWhitelistRssi(const uint8_t *aExtAddr, int8_t aRssi); * @sa otAddMacWhitelist * @sa otAddMacWhitelistRssi * @sa otClearMacWhitelist + * @sa otGetMacWhitelistEntry * @sa otDisableMacWhitelist * @sa otEnableMacWhitelist */ void otRemoveMacWhitelist(const uint8_t *aExtAddr); +/** + * This function gets a MAC whitelist entry. + * + * @param[in] aIndex An index into the MAC whitelist table. + * @param[out] aEntry A pointer to where the information is placed. + * + * @retval kThreadError_None Successfully retrieved the MAC whitelist entry. + * @retval kThreadError_InvalidArgs @p aIndex is out of bounds or @p aEntry is NULL. + * + */ +ThreadError otGetMacWhitelistEntry(uint8_t aIndex, otMacWhitelistEntry *aEntry); + /** * Remove all entries from the MAC whitelist. * * @sa otAddMacWhitelist * @sa otAddMacWhitelistRssi * @sa otRemoveMacWhitelist + * @sa otGetMacWhitelistEntry * @sa otDisableMacWhitelist * @sa otEnableMacWhitelist */ @@ -786,6 +802,7 @@ void otClearMacWhitelist(void); * @sa otAddMacWhitelistRssi * @sa otRemoveMacWhitelist * @sa otClearMacWhitelist + * @sa otGetMacWhitelistEntry * @sa otEnableMacWhitelist */ void otDisableMacWhitelist(void); @@ -793,14 +810,31 @@ void otDisableMacWhitelist(void); /** * Enable MAC whitelist filtering. * - * @sa otAccMacWhitelist + * @sa otAddMacWhitelist * @sa otAddMacWhitelistRssi * @sa otRemoveMacWhitelist * @sa otClearMacWhitelist + * @sa otGetMacWhitelistEntry * @sa otDisableMacWhitelist */ void otEnableMacWhitelist(void); +/** + * This function indicates whether or not the MAC whitelist is enabled. + * + * @returns TRUE if the MAC whitelist is enabled, FALSE otherwise. + * + * @sa otAddMacWhitelist + * @sa otAddMacWhitelistRssi + * @sa otRemoveMacWhitelist + * @sa otClearMacWhitelist + * @sa otGetMacWhitelistEntry + * @sa otDisableMacWhitelist + * @sa otEnableMacWhitelist + * + */ +bool otIsMacWhitelistEnabled(void); + /** * Detach from the Thread network. * diff --git a/src/cli/README.md b/src/cli/README.md index 45abe862b..30ae9d4bd 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -546,6 +546,19 @@ Disable OpenThread. Done ``` +### whitelist + +List the whitelist entries. + +```bash +> whitelist +Enabled +e2b3540590b0fd87 +d38d7f875888fccb +c467a90a2060fa0e +Done +``` + ### whitelist add \ Add an IEEE 802.15.4 Extended Address to the whitelist. diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index dc93d83c4..7479bd58f 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -153,6 +153,14 @@ void Interpreter::AppendResult(ThreadError error) } } +void Interpreter::OutputBytes(const uint8_t *aBytes, uint8_t aLength) +{ + for (int i = 0; i < aLength; i++) + { + sServer->OutputFormat("%02x", aBytes[i]); + } +} + ThreadError Interpreter::ParseLong(char *argv, long &value) { char *endptr; @@ -340,10 +348,8 @@ void Interpreter::ProcessCounters(int argc, char *argv[]) void Interpreter::ProcessExtAddress(int argc, char *argv[]) { - const uint8_t *extAddress = otGetExtendedAddress(); - sServer->OutputFormat("%02x%02x%02x%02x%02x%02x%02x%02x\r\n", - extAddress[0], extAddress[1], extAddress[2], extAddress[3], - extAddress[4], extAddress[5], extAddress[6], extAddress[7]); + OutputBytes(otGetExtendedAddress(), OT_EXT_ADDRESS_SIZE); + sServer->OutputFormat("\r\n"); AppendResult(kThreadError_None); } @@ -353,10 +359,8 @@ void Interpreter::ProcessExtPanId(int argc, char *argv[]) if (argc == 0) { - const uint8_t *extPanId = otGetExtendedPanId(); - sServer->OutputFormat("%02x%02x%02x%02x%02x%02x%02x%02x\r\n", - extPanId[0], extPanId[1], extPanId[2], extPanId[3], - extPanId[4], extPanId[5], extPanId[6], extPanId[7]); + OutputBytes(otGetExtendedPanId(), OT_EXT_PAN_ID_SIZE); + sServer->OutputFormat("\r\n"); } else { @@ -1098,8 +1102,6 @@ exit: void Interpreter::HandleActiveScanResult(otActiveScanResult *aResult) { - const uint8_t *bytes; - if (aResult == NULL) { sServer->OutputFormat("Done\r\n"); @@ -1119,20 +1121,16 @@ void Interpreter::HandleActiveScanResult(otActiveScanResult *aResult) if (aResult->mExtPanId != NULL) { - bytes = aResult->mExtPanId; - sServer->OutputFormat("| %02x%02x%02x%02x%02x%02x%02x%02x ", - bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]); + OutputBytes(aResult->mExtPanId, OT_EXT_PAN_ID_SIZE); } else { sServer->OutputFormat("| ---------------- "); } - sServer->OutputFormat("| %04x ", aResult->mPanId); + sServer->OutputFormat("| %04x | ", aResult->mPanId); - bytes = aResult->mExtAddress.m8; - sServer->OutputFormat("| %02x%02x%02x%02x%02x%02x%02x%02x ", - bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]); + OutputBytes(aResult->mExtAddress.m8, OT_EXT_ADDRESS_SIZE); sServer->OutputFormat("| %2d ", aResult->mChannel); sServer->OutputFormat("| %3d ", aResult->mRssi); sServer->OutputFormat("| %3d |\r\n", aResult->mLqi); @@ -1221,13 +1219,43 @@ exit: void Interpreter::ProcessWhitelist(int argc, char *argv[]) { ThreadError error = kThreadError_None; + otMacWhitelistEntry entry; int argcur = 0; uint8_t extAddr[8]; int8_t rssi; if (argcur >= argc) { - ExitNow(error = kThreadError_Parse); + if (otIsMacWhitelistEnabled()) + { + sServer->OutputFormat("Enabled\r\n"); + } + else + { + sServer->OutputFormat("Disabled\r\n"); + } + + for (int i = 0; ; i++) + { + if (otGetMacWhitelistEntry(i, &entry) != kThreadError_None) + { + break; + } + + if (entry.mValid == false) + { + continue; + } + + OutputBytes(entry.mExtAddress.m8, OT_EXT_ADDRESS_SIZE); + + if (entry.mFixedRssi) + { + sServer->OutputFormat(" %d", entry.mRssi); + } + + sServer->OutputFormat("\r\n"); + } } else if (strcmp(argv[argcur], "add") == 0) { diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index 43b3ce627..8d296e57d 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -85,6 +85,7 @@ private: }; static void AppendResult(ThreadError error); + static void OutputBytes(const uint8_t *aBytes, uint8_t aLength); static void ProcessHelp(int argc, char *argv[]); static void ProcessChannel(int argc, char *argv[]); diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index a5c52b8cb..b30e6f5b0 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -787,7 +787,7 @@ void Mac::ReceiveDoneTask(Frame *aFrame, ThreadError aError) Address dstaddr; PanId panid; Neighbor *neighbor; - Whitelist::Entry *entry; + otMacWhitelistEntry *entry; int8_t rssi; ThreadError error = aError; @@ -834,7 +834,7 @@ void Mac::ReceiveDoneTask(Frame *aFrame, ThreadError aError) { VerifyOrExit((entry = mWhitelist.Find(srcaddr.mExtAddress)) != NULL, error = kThreadError_WhitelistFiltered); - if (mWhitelist.GetConstantRssi(*entry, rssi) == kThreadError_None) + if (mWhitelist.GetFixedRssi(*entry, rssi) == kThreadError_None) { aFrame->mPower = rssi; } diff --git a/src/core/mac/mac_whitelist.cpp b/src/core/mac/mac_whitelist.cpp index e1ed1cf1f..def53fb1a 100644 --- a/src/core/mac/mac_whitelist.cpp +++ b/src/core/mac/mac_whitelist.cpp @@ -69,9 +69,19 @@ int Whitelist::GetMaxEntries(void) const return kMaxEntries; } -const Whitelist::Entry *Whitelist::GetEntries(void) const +ThreadError Whitelist::GetEntry(uint8_t aIndex, Entry &aEntry) const { - return mWhitelist; + ThreadError error = kThreadError_None; + + VerifyOrExit(aIndex < kMaxEntries, error = kThreadError_InvalidArgs); + + memcpy(&aEntry.mExtAddress, &mWhitelist[aIndex].mExtAddress, sizeof(aEntry.mExtAddress)); + aEntry.mRssi = mWhitelist[aIndex].mRssi; + aEntry.mValid = mWhitelist[aIndex].mValid; + aEntry.mFixedRssi = mWhitelist[aIndex].mFixedRssi; + +exit: + return error; } Whitelist::Entry *Whitelist::Add(const ExtAddress &address) @@ -89,7 +99,7 @@ Whitelist::Entry *Whitelist::Add(const ExtAddress &address) memcpy(&mWhitelist[i].mExtAddress, &address, sizeof(mWhitelist[i].mExtAddress)); mWhitelist[i].mValid = true; - mWhitelist[i].mConstantRssi = false; + mWhitelist[i].mFixedRssi = false; ExitNow(rval = &mWhitelist[i]); } @@ -137,25 +147,25 @@ exit: return rval; } -void Whitelist::ClearConstantRssi(Entry &aEntry) +void Whitelist::ClearFixedRssi(Entry &aEntry) { - aEntry.mConstantRssi = false; + aEntry.mFixedRssi = false; } -ThreadError Whitelist::GetConstantRssi(Entry &aEntry, int8_t &rssi) const +ThreadError Whitelist::GetFixedRssi(Entry &aEntry, int8_t &rssi) const { ThreadError error = kThreadError_None; - VerifyOrExit(aEntry.mValid && aEntry.mConstantRssi, error = kThreadError_Error); + VerifyOrExit(aEntry.mValid && aEntry.mFixedRssi, error = kThreadError_Error); rssi = aEntry.mRssi; exit: return error; } -void Whitelist::SetConstantRssi(Entry &aEntry, int8_t aRssi) +void Whitelist::SetFixedRssi(Entry &aEntry, int8_t aRssi) { - aEntry.mConstantRssi = true; + aEntry.mFixedRssi = true; aEntry.mRssi = aRssi; } diff --git a/src/core/mac/mac_whitelist.hpp b/src/core/mac/mac_whitelist.hpp index c1e335f73..ff84a5462 100644 --- a/src/core/mac/mac_whitelist.hpp +++ b/src/core/mac/mac_whitelist.hpp @@ -56,23 +56,13 @@ namespace Mac { class Whitelist { public: + typedef otMacWhitelistEntry Entry; + enum { kMaxEntries = 32, }; - /** - * This structure represents a whitelist entry. - * - */ - struct Entry - { - ExtAddress mExtAddress; ///< The IEEE 802.15.4 Extended Address. - int8_t mRssi; ///< The constant RSSI value. - bool mValid : 1; ///< TRUE if the entry is valid, FALSE otherwise. - bool mConstantRssi : 1; ///< TRUE if the constant RSSI value is used, FALSE otherwise. - }; - /** * This constructor initializes the whitelist filter. * @@ -109,12 +99,16 @@ public: int GetMaxEntries(void) const; /** - * This method returns the whitelist entries. + * This method gets a whitelist entry. * - * @returns The whitelist entries. + * @param[in] aIndex An index into the MAC whitelist table. + * @param[out] aEntry A reference to where the information is placed. + * + * @retval kThreadError_None Successfully retrieved the MAC whitelist entry. + * @retval kThreadError_InvalidArgs @p aIndex is out of bounds or @p aEntry is NULL. * */ - const Entry *GetEntries(void) const; + ThreadError GetEntry(uint8_t aIndex, Entry &aEntry) const; /** * This method adds an Extended Address to the whitelist filter. @@ -151,33 +145,33 @@ public: Entry *Find(const ExtAddress &aAddress); /** - * This method clears the constant RSSI value and uses the measured value provided by the radio instead. + * This method clears the fixed RSSI value and uses the measured value provided by the radio instead. * * @param[in] aEntry A reference to the whitelist entry. * */ - void ClearConstantRssi(Entry &aEntry); + void ClearFixedRssi(Entry &aEntry); /** - * This method indicates whether or not the constant RSSI is set. + * This method indicates whether or not the fixed RSSI is set. * * @param[in] aEntry A reference to the whitelist entry. * @param[out] aRssi A reference to the RSSI variable. * - * @retval kThreadError_None A constant RSSI is set and written to @p aRssi. - * @retval kThreadError_InvalidArg A constant RSSI was not set. + * @retval kThreadError_None A fixed RSSI is set and written to @p aRssi. + * @retval kThreadError_InvalidArg A fixed RSSI was not set. * */ - ThreadError GetConstantRssi(Entry &aEntry, int8_t &aRssi) const; + ThreadError GetFixedRssi(Entry &aEntry, int8_t &aRssi) const; /** - * This method sets a constant RSSI value for all received messages matching @p aEntry. + * This method sets a fixed RSSI value for all received messages matching @p aEntry. * * @param[in] aEntry A reference to the whitelist entry. * @param[in] aRssi An RSSI value in dBm. * */ - void SetConstantRssi(Entry &aEntry, int8_t aRssi); + void SetFixedRssi(Entry &aEntry, int8_t aRssi); private: Entry mWhitelist[kMaxEntries]; diff --git a/src/core/openthread.cpp b/src/core/openthread.cpp index ce23da20a..32b8d83d8 100644 --- a/src/core/openthread.cpp +++ b/src/core/openthread.cpp @@ -404,11 +404,11 @@ ThreadError otAddMacWhitelist(const uint8_t *aExtAddr) ThreadError otAddMacWhitelistRssi(const uint8_t *aExtAddr, int8_t aRssi) { ThreadError error = kThreadError_None; - Thread::Mac::Whitelist::Entry *entry; + otMacWhitelistEntry *entry; entry = sThreadNetif->GetMac().GetWhitelist().Add(*reinterpret_cast(aExtAddr)); VerifyOrExit(entry != NULL, error = kThreadError_NoBufs); - sThreadNetif->GetMac().GetWhitelist().SetConstantRssi(*entry, aRssi); + sThreadNetif->GetMac().GetWhitelist().SetFixedRssi(*entry, aRssi); exit: return error; @@ -424,6 +424,17 @@ void otClearMacWhitelist(void) sThreadNetif->GetMac().GetWhitelist().Clear(); } +ThreadError otGetMacWhitelistEntry(uint8_t aIndex, otMacWhitelistEntry *aEntry) +{ + ThreadError error; + + VerifyOrExit(aEntry != NULL, error = kThreadError_InvalidArgs); + error = sThreadNetif->GetMac().GetWhitelist().GetEntry(aIndex, *aEntry); + +exit: + return error; +} + void otDisableMacWhitelist(void) { sThreadNetif->GetMac().GetWhitelist().Disable(); @@ -434,6 +445,11 @@ void otEnableMacWhitelist(void) sThreadNetif->GetMac().GetWhitelist().Enable(); } +bool otIsMacWhitelistEnabled(void) +{ + return sThreadNetif->GetMac().GetWhitelist().IsEnabled(); +} + ThreadError otBecomeDetached(void) { return sThreadNetif->GetMle().BecomeDetached();