mirror of
https://github.com/espressif/openthread.git
synced 2026-08-02 00:57:47 +00:00
[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:
committed by
Jonathan Hui
parent
ee4bc9cb12
commit
451a72f750
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user