blob: c0919799bed2ba06bbc99e06c08f79c960f287be [file] [log] [blame]
/*
* Copyright (c) 2016-2018, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file
* This file includes definitions for Thread child table.
*/
#ifndef CHILD_TABLE_HPP_
#define CHILD_TABLE_HPP_
#include "openthread-core-config.h"
#include "common/locator.hpp"
#include "thread/topology.hpp"
namespace ot {
#if OPENTHREAD_FTD
/**
* This class represents the Thread child table.
*
*/
class ChildTable : public InstanceLocator
{
public:
/**
* This class represents an iterator for iterating through the child entries in the child table.
*
*/
class Iterator : public InstanceLocator
{
public:
/**
* This constructor initializes an `Iterator` instance to start from beginning of the child table.
*
* @param[in] aInstance A reference to the OpenThread instance.
* @param[in] aFilter A child state filter.
*
*/
Iterator(Instance &aInstance, Child::StateFilter aFilter);
/**
* This constructor initializes an `Iterator` instance to start from a given child.
*
* This constructor allows the iterator to start from a given `Child` entry. The iterator will start from the
* given child and will go through all entries in the child table (matching the filter) till it gets back to
* the starting `Child` entry.
*
* If the given starting `Child` pointer is `NULL`, then the iterator starts from beginning of the child table.
*
* @param[in] aInstance A reference to the OpenThread instance.
* @param[in] aFilter A child state filter.
* @param[in] aStartingChild A pointer to a child. If non-NULL, the iterator starts from the given entry.
*
*/
Iterator(Instance &aInstance, Child::StateFilter aFilter, Child *aStartingChild);
/**
* This method resets the iterator to start over.
*
*/
void Reset(void);
/**
* This method indicates whether there are no more `Child` entries in the list (iterator has reached end of
* the list).
*
* @retval TRUE There are no more entries in the list (reached end of the list).
* @retval FALSE The current entry is valid.
*
*/
bool IsDone(void) const { return (mChild == NULL); }
/**
* This method advances the iterator.
*
* The iterator is moved to point to the next `Child` entry matching the given state filter in the constructor.
* If there are no more `Child` entries matching the given filter, the iterator becomes empty (i.e.,
* `GetChild()` returns `NULL` and `IsDone()` returns `true`).
*
*/
void Advance(void);
/**
* This method overloads `++` operator (pre-increment) to advance the iterator.
*
* The iterator is moved to point to the next `Child` entry matching the given state filter in the constructor.
* If there are no more `Child` entries matching the given filter, the iterator becomes empty (i.e.,
* `GetChild()` returns `NULL` and `IsDone()` returns `true`).
*
*/
void operator++(void) { Advance(); }
/**
* This method overloads `++` operator (post-increment) to advance the iterator.
*
* The iterator is moved to point to the next `Child` entry matching the given state filter in the constructor.
* If there are no more `Child` entries matching the given filter, the iterator becomes empty (i.e.,
* `GetChild()` returns `NULL` and `IsDone()` returns `true`).
*
*/
void operator++(int) { Advance(); }
/**
* This method gets the `Child` entry to which the iterator is currently pointing.
*
* @returns A pointer to the `Child` entry, or `NULL` if the iterator is done and/or empty.
*
*/
Child *GetChild(void) { return mChild; }
private:
Child::StateFilter mFilter;
Child * mStart;
Child * mChild;
};
/**
* This constructor initializes a `ChildTable` instance.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
*/
explicit ChildTable(Instance &aInstance);
/**
* This method clears the child table.
*
*/
void Clear(void);
/**
* This method returns the child table index for a given `Child` instance.
*
* @param[in] aChild A reference to a `Child`
*
* @returns The index corresponding to @p aChild.
*
*/
uint16_t GetChildIndex(const Child &aChild) const { return static_cast<uint16_t>(&aChild - mChildren); }
/**
* This method returns a pointer to a `Child` entry at a given index, or `NULL` if the index is out of bounds,
* i.e., index is larger or equal to maximum number of children allowed (@sa GetMaxChildrenAllowed()).
*
* @param[in] aChildIndex A child index.
*
* @returns A pointer to the `Child` corresponding to the given index, or `NULL` if the index is out of bounds.
*
*/
Child *GetChildAtIndex(uint16_t aChildIndex);
/**
* This method gets a new/unused `Child` entry from the child table.
*
* @note The returned child entry will be cleared (`memset` to zero).
*
* @returns A pointer to a new `Child` entry, or `NULL` if all `Child` entries are in use.
*
*/
Child *GetNewChild(void);
/**
* This method searches the child table for a `Child` with a given RLOC16 also matching a given state filter.
*
* @param[in] aRloc16 A RLOC16 address.
* @param[in] aFilter A child state filter.
*
* @returns A pointer to the `Child` entry if one is found, or `NULL` otherwise.
*
*/
Child *FindChild(uint16_t aRloc16, Child::StateFilter aFilter);
/**
* This method searches the child table for a `Child` with a given extended address also matching a given state
* filter.
*
* @param[in] aAddress A reference to an extended address.
* @param[in] aFilter A child state filter.
*
* @returns A pointer to the `Child` entry if one is found, or `NULL` otherwise.
*
*/
Child *FindChild(const Mac::ExtAddress &aAddress, Child::StateFilter aFilter);
/**
* This method searches the child table for a `Child` with a given address also matching a given state filter.
*
* @param[in] aAddress A reference to a MAC address.
* @param[in] aFilter A child state filter.
*
* @returns A pointer to the `Child` entry if one is found, or `NULL` otherwise.
*
*/
Child *FindChild(const Mac::Address &aAddress, Child::StateFilter aFilter);
/**
* This method indicates whether the child table contains any child matching a given state filter.
*
* @param[in] aFilter A child state filter.
*
* @returns TRUE if the table contains at least one child table matching the given filter, FALSE otherwise.
*
*/
bool HasChildren(Child::StateFilter aFilter) const;
/**
* This method returns the number of children in the child table matching a given state filter.
*
* @param[in] aFilter A child state filter.
*
* @returns Number of children matching the given state filer.
*
*/
uint16_t GetNumChildren(Child::StateFilter aFilter) const;
/**
* This method returns the maximum number of children that can be supported (build-time constant).
*
* @note Number of children allowed (from `GetMaxChildrenAllowed()`) can be less than maximum number of supported
* children.
*
* @returns The maximum number of children supported
*
*/
uint16_t GetMaxChildren(void) const { return kMaxChildren; }
/**
* This method get the maximum number of children allowed.
*
* @returns The maximum number of children allowed.
*
*/
uint16_t GetMaxChildrenAllowed(void) const { return mMaxChildrenAllowed; }
/**
* This method sets the maximum number of children allowed.
*
* The number of children allowed must be at least one and at most same as maximum supported children (@sa
* GetMaxChildren()). It can be changed only if the child table is empty.
*
* @param[in] aMaxChildren Maximum number of children allowed.
*
* @retval OT_ERROR_NONE The number of allowed children changed successfully.
* @retval OT_ERROR_INVALID_ARGS If @p aMaxChildren is not in the range [1, Max supported children].
* @retval OT_ERROR_INVALID_STATE The child table is not empty.
*
*/
otError SetMaxChildrenAllowed(uint16_t aMaxChildren);
private:
enum
{
kMaxChildren = OPENTHREAD_CONFIG_MLE_MAX_CHILDREN,
};
uint16_t mMaxChildrenAllowed;
Child mChildren[kMaxChildren];
};
#endif // OPENTHREAD_FTD
#if OPENTHREAD_MTD
class ChildTable : public InstanceLocator
{
public:
class Iterator
{
public:
Iterator(Instance &, Child::StateFilter) {}
Iterator(Instance &, Child::StateFilter, Child *) {}
void Reset(void) {}
bool IsDone(void) const { return true; }
void Advance(void) {}
void operator++(void) {}
void operator++(int) {}
Child *GetChild(void) { return NULL; }
};
explicit ChildTable(Instance &aInstance)
: InstanceLocator(aInstance)
{
}
void Clear(void) {}
uint16_t GetChildIndex(const Child &) const { return 0; }
Child * GetChildAtIndex(uint16_t) { return NULL; }
Child *GetNewChild(void) { return NULL; }
Child *FindChild(uint16_t, Child::StateFilter) { return NULL; }
Child *FindChild(const Mac::ExtAddress &, Child::StateFilter) { return NULL; }
Child *FindChild(const Mac::Address &, Child::StateFilter) { return NULL; }
bool HasChildren(Child::StateFilter) const { return false; }
uint16_t GetNumChildren(Child::StateFilter) const { return 0; }
uint16_t GetMaxChildren(void) const { return 0; }
uint16_t GetMaxChildrenAllowed(void) const { return 0; }
otError SetMaxChildrenAllowed(uint16_t) { return OT_ERROR_INVALID_STATE; }
};
#endif // OPENTHREAD_MTD
} // namespace ot
#endif // CHILD_TABLE_HPP_