1 /*
2  *  Copyright (c) 2016-2020, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file includes definitions for Thread neighbor table.
32  */
33 
34 #ifndef NEIGHBOR_TABLE_HPP_
35 #define NEIGHBOR_TABLE_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include "common/locator.hpp"
40 #include "common/non_copyable.hpp"
41 #include "thread/topology.hpp"
42 
43 namespace ot {
44 
45 /**
46  * This class represents the Thread neighbor table.
47  *
48  */
49 class NeighborTable : public InstanceLocator, private NonCopyable
50 {
51 public:
52     /**
53      * This function pointer is called to notify that a child or router neighbor is being added to or removed from
54      * neighbor table.
55      *
56      * Note that this callback in invoked while the neighbor/child table is being updated and always before the related
57      * `Notifier` event.
58      *
59      */
60     typedef otNeighborTableCallback Callback;
61 
62     /**
63      * This type represents a neighbor table entry info (child or router) and is used as a parameter in the neighbor
64      * table callback.
65      *
66      */
67     typedef otNeighborTableEntryInfo EntryInfo;
68 
69     /**
70      * This enumeration defines the constants used in `NeighborTable::Callback` to indicate whether a child or router
71      * neighbor is being added or removed.
72      *
73      */
74     enum Event : uint8_t
75     {
76         kChildAdded       = OT_NEIGHBOR_TABLE_EVENT_CHILD_ADDED,        ///< A child is being added.
77         kChildRemoved     = OT_NEIGHBOR_TABLE_EVENT_CHILD_REMOVED,      ///< A child is being removed.
78         kChildModeChanged = OT_NEIGHBOR_TABLE_EVENT_CHILD_MODE_CHANGED, ///< An existing child's mode changed.
79         kRouterAdded      = OT_NEIGHBOR_TABLE_EVENT_ROUTER_ADDED,       ///< A router is being added.
80         kRouterRemoved    = OT_NEIGHBOR_TABLE_EVENT_ROUTER_REMOVED,     ///< A router is being removed.
81     };
82 
83     /**
84      * This constructor initializes the `NeighborTable` instance.
85      *
86      * @param[in]  aInstance     A reference to the OpenThread instance.
87      *
88      */
89     explicit NeighborTable(Instance &aInstance);
90 
91     /**
92      * This method searches among parent and parent candidate to find a `Neighbor` corresponding to a given short
93      * address.
94      *
95      * @param[in]  aShortAddress  A short address.
96      * @param[in]  aFilter        A neighbor state filter
97      *
98      * @returns A pointer to the `Neighbor` corresponding to @p aShortAddress, nullptr otherwise.
99      *
100      */
101     Neighbor *FindParent(Mac::ShortAddress     aShortAddress,
102                          Neighbor::StateFilter aFilter = Neighbor::kInStateValidOrRestoring);
103 
104     /**
105      * This method searches in parent and parent candidate to find a `Neighbor` corresponding to a given MAC Extended
106      * Address.
107      *
108      * @param[in]  aExtAddress   A MAC Extended Address.
109      * @param[in]  aFilter       A neighbor state filter
110      *
111      * @returns A pointer to the `Neighbor` corresponding to @p aExtAddress, nullptr otherwise.
112      *
113      */
114     Neighbor *FindParent(const Mac::ExtAddress &aExtAddress,
115                          Neighbor::StateFilter  aFilter = Neighbor::kInStateValidOrRestoring);
116 
117     /**
118      * This method searches among parent and parent candidate to find a `Neighbor` object corresponding to a given MAC
119      * address.
120      *
121      * @param[in]  aMacAddress  A MAC address.
122      * @param[in]  aFilter      A neighbor state filter
123      *
124      * @returns A pointer to the `Neighbor` corresponding to @p aMacAddress, nullptr otherwise.
125      *
126      */
127     Neighbor *FindParent(const Mac::Address &  aMacAddress,
128                          Neighbor::StateFilter aFilter = Neighbor::kInStateValidOrRestoring);
129 
130     /**
131      * This method searches in the neighbor table to find a `Neighbor` corresponding to a given short address.
132      *
133      * @param[in]  aShortAddress  A short address.
134      * @param[in]  aFilter        A neighbor state filter.
135      *
136      * @returns A pointer to the `Neighbor` corresponding to @p aShortAddress, nullptr otherwise.
137      *
138      */
139     Neighbor *FindNeighbor(Mac::ShortAddress     aShortAddress,
140                            Neighbor::StateFilter aFilter = Neighbor::kInStateValidOrRestoring);
141 
142     /**
143      * This method searches in the neighbor table to find a `Neighbor` corresponding to a given MAC Extended Address.
144      *
145      * @param[in]  aExtAddress   A MAC Extended Address.
146      * @param[in]  aFilter       A neighbor state filter.
147      *
148      * @returns A pointer to the `Neighbor` corresponding to @p aExtAddress, nullptr otherwise.
149      *
150      */
151     Neighbor *FindNeighbor(const Mac::ExtAddress &aExtAddress,
152                            Neighbor::StateFilter  aFilter = Neighbor::kInStateValidOrRestoring);
153 
154     /**
155      * This method searches in the neighbor table to find a `Neighbor` object corresponding to a given MAC address.
156      *
157      * @param[in]  aMacAddress  A MAC address.
158      * @param[in]  aFilter      A neighbor state filter.
159      *
160      * @returns A pointer to the `Neighbor` corresponding to @p aMacAddress, nullptr otherwise.
161      *
162      */
163     Neighbor *FindNeighbor(const Mac::Address &  aMacAddress,
164                            Neighbor::StateFilter aFilter = Neighbor::kInStateValidOrRestoring);
165 
166 #if OPENTHREAD_FTD
167 
168     /**
169      * This method searches in the neighbor table to find a `Neighbor` object corresponding to a given IPv6 address.
170      *
171      * @param[in]  aIp6Address  An IPv6 address.
172      * @pram[in]   aFilter      A neighbor state filter.
173      *
174      * @returns A pointer to the `Neighbor` corresponding to @p aIp6Address, nullptr otherwise.
175      *
176      */
177     Neighbor *FindNeighbor(const Ip6::Address &  aIp6Address,
178                            Neighbor::StateFilter aFilter = Neighbor::kInStateValidOrRestoring);
179 
180     /**
181      * This method searches in the neighbor table to find a `Neighbor` for which a one-way link is maintained (as in the
182      * case of an FTD child with neighbor routers).
183      *
184      * @param[in]  aMacAddress  A MAC address.
185      *
186      * @returns A pointer to the Neighbor corresponding to @p aMacAddress, nullptr otherwise.
187      *
188      */
189     Neighbor *FindRxOnlyNeighborRouter(const Mac::Address &aMacAddress);
190 
191 #endif // OPENTHREAD_FTD
192 
193     /**
194      * This method gets the next neighbor information. It is used to iterate through the entries of
195      * the neighbor table.
196      *
197      * @param[inout]  aIterator  A reference to the iterator context. To get the first neighbor entry
198                                  it should be set to OT_NEIGHBOR_INFO_ITERATOR_INIT.
199      * @param[out]    aNeighInfo The neighbor information.
200      *
201      * @retval kErrorNone         Successfully found the next neighbor entry in table.
202      * @retval kErrorNotFound     No subsequent neighbor entry exists in the table.
203      *
204      */
205     Error GetNextNeighborInfo(otNeighborInfoIterator &aIterator, Neighbor::Info &aNeighInfo);
206 
207     /**
208      * This method registers the "neighbor table changed" callback function.
209      *
210      * The provided callback (if non-nullptr) will be invoked when a child/router entry is being added/remove to/from
211      * the neighbor table. Subsequent calls to this method will overwrite the previous callback.
212      *
213      * @param[in] aCallback    A pointer to callback handler function.
214      *
215      */
RegisterCallback(Callback aCallback)216     void RegisterCallback(Callback aCallback) { mCallback = aCallback; }
217 
218     /**
219      * This method signals a "neighbor table changed" event.
220      *
221      * This method invokes the `NeighborTable::Callback` and also signals the change through a related `Notifier` event.
222      *
223      * @param[in] aEvent     The event to emit (child/router added/removed, or child mode changed).
224      * @param[in] aNeighbor  The neighbor that is being added/removed.
225      *
226      */
227     void Signal(Event aEvent, const Neighbor &aNeighbor);
228 
229 private:
230     Neighbor *FindParent(const Neighbor::AddressMatcher &aMatcher);
231     Neighbor *FindNeighbor(const Neighbor::AddressMatcher &aMatcher);
232 #if OPENTHREAD_FTD
233     Neighbor *FindChildOrRouter(const Neighbor::AddressMatcher &aMatcher);
234 #endif
235 
236     Callback mCallback;
237 };
238 
239 } // namespace ot
240 
241 #endif // NEIGHBOR_TABLE_HPP_
242