[address-resolver] update public OT API for getting cache table (#4599)

This commit updates the public OpenThread APIs to get the address
cache table. The new APIs allows to iterate through all entries
(including in query or retry mode) and provides more info about the
entries, e.g., current timeout, retry delay (if entry is in
query/retry state), or the mesh-local EID, last transaction time (if
entry is in cached state).
This commit is contained in:
Abtin Keshavarzian
2020-03-31 12:11:24 -07:00
committed by Jonathan Hui
parent ee4bc9cb12
commit 451a72f750
6 changed files with 148 additions and 53 deletions
+44 -13
View File
@@ -78,17 +78,46 @@ typedef struct
typedef uint16_t otChildIp6AddressIterator; ///< Used to iterate through IPv6 addresses of a Thread Child entry.
/**
* This enumeration defines the EID cache entry state.
*
*/
typedef enum otCacheEntryState
{
OT_CACHE_ENTRY_STATE_CACHED = 0, // Entry is cached and in-use.
OT_CACHE_ENTRY_STATE_SNOOPED = 1, // Entry is created by snoop optimization (inspection of received msg).
OT_CACHE_ENTRY_STATE_QUERY = 2, // Entry represents an ongoing query for the EID.
OT_CACHE_ENTRY_STATE_RETRY_QUERY = 3, // Entry is in retry wait mode (a prior query did not get a response).
} otCacheEntryState;
/**
* This structure represents an EID cache entry.
*
*/
typedef struct otEidCacheEntry
typedef struct otCacheEntryInfo
{
otIp6Address mTarget; ///< Target
otShortAddress mRloc16; ///< RLOC16
uint8_t mAge; ///< Age (order of use, 0 indicates most recently used entry)
bool mValid : 1; ///< Indicates whether or not the cache entry is valid
} otEidCacheEntry;
otIp6Address mTarget; ///< Target EID
otShortAddress mRloc16; ///< RLOC16
otCacheEntryState mState; ///< Entry state
bool mCanEvict : 1; ///< Indicates whether the entry can be evicted.
bool mValidLastTrans : 1; ///< Indicates whether last transaction time and ML-EID are valid.
uint32_t mLastTransTime; ///< Last transaction time (applicable in cached state).
otIp6Address mMeshLocalEid; ///< Mesh Local EID (applicable if entry in cached state).
uint16_t mTimeout; ///< Timeout in seconds (applicable if in snooped/query/retry-query states).
uint16_t mRetryDelay; ///< Retry delay in seconds (applicable if in query-retry state).
} otCacheEntryInfo;
/**
* This type represents an iterator used for iterating through the EID cache table entries.
*
* To initialize the iterator and start from the first entry in the cache table, set all its fields in the structure to
* zero (e.g., `memset` the iterator to zero).
*
*/
typedef struct otCacheEntryIterator
{
const void *mData[2]; ///< Opaque data used by the core implementation. Should not be changed by user.
} otCacheEntryIterator;
/**
* Get the maximum number of children currently allowed.
@@ -507,17 +536,19 @@ uint8_t otThreadGetMaxRouterId(otInstance *aInstance);
otError otThreadGetRouterInfo(otInstance *aInstance, uint16_t aRouterId, otRouterInfo *aRouterInfo);
/**
* This function gets an EID cache entry.
* This function gets the next EID cache entry (using an iterator).
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aIndex An index into the EID cache table.
* @param[out] aEntry A pointer to where the EID information is placed.
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[out] aEntryInfo A pointer to where the EID cache entry information is placed.
* @param[inout] aIterator A pointer to an iterator. It will be updated to point to next entry on success. To get the
* first entry, initialize the iterator by setting all its fields to zero (e.g., `memset` the
* the iterator structure to zero).
*
* @retval OT_ERROR_NONE Successfully retrieved the EID cache entry.
* @retval OT_ERROR_INVALID_ARGS @p aIndex was out of bounds or @p aEntry was NULL.
* @retval OT_ERROR_NONE Successfully populated @p aEntryInfo for next EID cache entry.
* @retval OT_ERROR_NOT_FOUND No more entries in the address cache table.
*
*/
otError otThreadGetEidCacheEntry(otInstance *aInstance, uint8_t aIndex, otEidCacheEntry *aEntry);
otError otThreadGetNextCacheEntry(otInstance *aInstance, otCacheEntryInfo *aEntryInfo, otCacheEntryIterator *aIterator);
/**
* Get the Thread PSKc
+5 -7
View File
@@ -1294,16 +1294,14 @@ void Interpreter::ProcessEidCache(uint8_t aArgsLength, char *aArgs[])
OT_UNUSED_VARIABLE(aArgsLength);
OT_UNUSED_VARIABLE(aArgs);
otEidCacheEntry entry;
otCacheEntryIterator iterator;
otCacheEntryInfo entry;
memset(&iterator, 0, sizeof(iterator));
for (uint8_t i = 0;; i++)
{
SuccessOrExit(otThreadGetEidCacheEntry(mInstance, i, &entry));
if (!entry.mValid)
{
continue;
}
SuccessOrExit(otThreadGetNextCacheEntry(mInstance, &entry, &iterator));
OutputIp6Address(entry.mTarget);
mServer->OutputFormat(" %04x\r\n", entry.mRloc16);
+4 -3
View File
@@ -316,12 +316,13 @@ otError otThreadGetRouterInfo(otInstance *aInstance, uint16_t aRouterId, otRoute
return instance.Get<RouterTable>().GetRouterInfo(aRouterId, *aRouterInfo);
}
otError otThreadGetEidCacheEntry(otInstance *aInstance, uint8_t aIndex, otEidCacheEntry *aEntry)
otError otThreadGetNextCacheEntry(otInstance *aInstance, otCacheEntryInfo *aEntryInfo, otCacheEntryIterator *aIterator)
{
Instance &instance = *static_cast<Instance *>(aInstance);
OT_ASSERT(aEntry != NULL);
return instance.Get<AddressResolver>().GetEntry(aIndex, *aEntry);
OT_ASSERT((aIterator != NULL) && (aEntryInfo != NULL));
return instance.Get<AddressResolver>().GetNextCacheEntry(*aEntryInfo, *aIterator);
}
#if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
+66 -15
View File
@@ -99,30 +99,81 @@ void AddressResolver::Clear(void)
}
}
otError AddressResolver::GetEntry(uint8_t aIndex, otEidCacheEntry &aEntry) const
otError AddressResolver::GetNextCacheEntry(EntryInfo &aInfo, Iterator &aIterator) const
{
otError error = OT_ERROR_NONE;
uint8_t age = aIndex;
const CacheEntryList *lists[] = {&mCachedList, &mSnoopedList};
otError error = OT_ERROR_NONE;
const CacheEntryList *list;
const CacheEntry * entry;
for (uint8_t index = 0; index < OT_ARRAY_LENGTH(lists); index++)
{
for (entry = lists[index]->GetHead(); (aIndex != 0) && (entry != NULL); aIndex--, entry = entry->GetNext())
;
list = reinterpret_cast<const CacheEntryList *>(aIterator.mData[kIteratorListIndex]);
entry = reinterpret_cast<const CacheEntry *>(aIterator.mData[kIteratorEntryIndex]);
if (entry != NULL)
while (entry == NULL)
{
if (list == NULL)
{
break;
list = &mCachedList;
}
else if (list == &mCachedList)
{
list = &mSnoopedList;
}
else if (list == &mSnoopedList)
{
list = &mQueryList;
}
else if (list == &mQueryList)
{
list = &mQueryRetryList;
}
else
{
ExitNow(error = OT_ERROR_NOT_FOUND);
}
entry = list->GetHead();
}
VerifyOrExit(entry != NULL, error = OT_ERROR_NOT_FOUND);
// Update the iterator then populate the `aInfo`.
aEntry.mTarget = entry->GetTarget();
aEntry.mRloc16 = entry->GetRloc16();
aEntry.mAge = age;
aEntry.mValid = true;
aIterator.mData[kIteratorEntryIndex] = entry->GetNext();
aIterator.mData[kIteratorListIndex] = list;
memset(&aInfo, 0, sizeof(aInfo));
aInfo.mTarget = entry->GetTarget();
aInfo.mRloc16 = entry->GetRloc16();
if (list == &mCachedList)
{
aInfo.mState = OT_CACHE_ENTRY_STATE_CACHED;
aInfo.mCanEvict = true;
aInfo.mValidLastTrans = entry->IsLastTransactionTimeValid();
VerifyOrExit(entry->IsLastTransactionTimeValid());
aInfo.mLastTransTime = entry->GetLastTransactionTime();
static_cast<Ip6::Address &>(aInfo.mMeshLocalEid).SetPrefix(Get<Mle::MleRouter>().GetMeshLocalPrefix());
static_cast<Ip6::Address &>(aInfo.mMeshLocalEid).SetIid(entry->GetMeshLocalIid());
ExitNow();
}
if (list == &mSnoopedList)
{
aInfo.mState = OT_CACHE_ENTRY_STATE_SNOOPED;
}
else if (list == &mQueryList)
{
aInfo.mState = OT_CACHE_ENTRY_STATE_QUERY;
}
else
{
aInfo.mState = OT_CACHE_ENTRY_STATE_RETRY_QUERY;
}
aInfo.mCanEvict = entry->CanEvict();
aInfo.mTimeout = entry->GetTimeout();
aInfo.mRetryDelay = entry->GetRetryDelay();
exit:
return error;
+22 -6
View File
@@ -63,6 +63,18 @@ namespace ot {
class AddressResolver : public InstanceLocator
{
public:
/**
* This type represents an iterator used for iterating through the EID cache table entries.
*
*/
typedef otCacheEntryIterator Iterator;
/**
* This type represents an EID cache entry.
*
*/
typedef otCacheEntryInfo EntryInfo;
/**
* This constructor initializes the object.
*
@@ -76,16 +88,18 @@ public:
void Clear(void);
/**
* This method gets an EID cache entry.
* This method gets the information about the next EID cache entry (using an iterator).
*
* @param[in] aIndex An index into the EID cache table.
* @param[out] aEntry A reference to where the EID information is placed.
* @param[out] aInfo An `EntryInfo` where the EID cache entry information is placed.
* @param[inout] aIterator An iterator. It will be updated to point to the next entry on success.
* To get the first entry, initialize the iterator by setting all its fields to zero.
* e.g., `memset` the the iterator structure to zero.
*
* @retval OT_ERROR_NONE Successfully retrieved the EID cache entry.
* @retval OT_ERROR_INVALID_ARGS @p aIndex was out of bounds.
* @retval OT_ERROR_NONE Successfully populated @p aInfo with the info for the next EID cache entry.
* @retval OT_ERROR_NOT_FOUND No more entries in the address cache table.
*
*/
otError GetEntry(uint8_t aIndex, otEidCacheEntry &aEntry) const;
otError GetNextCacheEntry(EntryInfo &aInfo, Iterator &aIterator) const;
/**
* This method removes the EID-to-RLOC cache entries corresponding to an RLOC16.
@@ -170,6 +184,8 @@ private:
kAddressQueryMaxRetryDelay = OPENTHREAD_CONFIG_TMF_ADDRESS_QUERY_MAX_RETRY_DELAY, // in seconds
kSnoopBlockEvictionTimeout = OPENTHREAD_CONFIG_TMF_SNOOP_CACHE_ENTRY_TIMEOUT, // in seconds
kStateUpdatePeriod = 1000u, // in milliseconds
kIteratorListIndex = 0,
kIteratorEntryIndex = 1,
};
class CacheEntry : public InstanceLocatorInit
+7 -9
View File
@@ -911,22 +911,20 @@ exit:
template <> otError NcpBase::HandlePropertyGet<SPINEL_PROP_THREAD_ADDRESS_CACHE_TABLE>(void)
{
otError error = OT_ERROR_NONE;
otEidCacheEntry entry;
otError error = OT_ERROR_NONE;
otCacheEntryIterator iterator;
otCacheEntryInfo entry;
memset(&iterator, 0, sizeof(iterator));
for (uint8_t index = 0;; index++)
{
SuccessOrExit(otThreadGetEidCacheEntry(mInstance, index, &entry));
if (!entry.mValid)
{
continue;
}
SuccessOrExit(otThreadGetNextCacheEntry(mInstance, &entry, &iterator));
SuccessOrExit(error = mEncoder.OpenStruct());
SuccessOrExit(error = mEncoder.WriteIp6Address(entry.mTarget));
SuccessOrExit(error = mEncoder.WriteUint16(entry.mRloc16));
SuccessOrExit(error = mEncoder.WriteUint8(entry.mAge));
SuccessOrExit(error = mEncoder.WriteUint8(index));
SuccessOrExit(error = mEncoder.CloseStruct());
}