• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2017, 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 implements Filter IEEE 802.15.4 frame filtering based on MAC address.
32  */
33 
34 #include "mac_filter.hpp"
35 
36 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
37 
38 #include "common/array.hpp"
39 #include "common/as_core_type.hpp"
40 #include "common/code_utils.hpp"
41 
42 namespace ot {
43 namespace Mac {
44 
Filter(void)45 Filter::Filter(void)
46     : mMode(kModeRssInOnly)
47     , mDefaultRssIn(kFixedRssDisabled)
48 {
49     for (FilterEntry &entry : mFilterEntries)
50     {
51         entry.mFiltered = false;
52         entry.mRssIn    = kFixedRssDisabled;
53     }
54 }
55 
FindEntry(const ExtAddress & aExtAddress)56 Filter::FilterEntry *Filter::FindEntry(const ExtAddress &aExtAddress)
57 {
58     FilterEntry *rval = nullptr;
59 
60     for (FilterEntry &entry : mFilterEntries)
61     {
62         if (entry.IsInUse() && (aExtAddress == entry.mExtAddress))
63         {
64             ExitNow(rval = &entry);
65         }
66     }
67 
68 exit:
69     return rval;
70 }
71 
FindAvailableEntry(void)72 Filter::FilterEntry *Filter::FindAvailableEntry(void)
73 {
74     FilterEntry *rval = nullptr;
75 
76     for (FilterEntry &entry : mFilterEntries)
77     {
78         if (!entry.IsInUse())
79         {
80             ExitNow(rval = &entry);
81         }
82     }
83 
84 exit:
85     return rval;
86 }
87 
AddAddress(const ExtAddress & aExtAddress)88 Error Filter::AddAddress(const ExtAddress &aExtAddress)
89 {
90     Error        error = kErrorNone;
91     FilterEntry *entry = FindEntry(aExtAddress);
92 
93     if (entry == nullptr)
94     {
95         VerifyOrExit((entry = FindAvailableEntry()) != nullptr, error = kErrorNoBufs);
96         entry->mExtAddress = aExtAddress;
97     }
98 
99     entry->mFiltered = true;
100 
101 exit:
102     return error;
103 }
104 
RemoveAddress(const ExtAddress & aExtAddress)105 void Filter::RemoveAddress(const ExtAddress &aExtAddress)
106 {
107     FilterEntry *entry = FindEntry(aExtAddress);
108 
109     if (entry != nullptr)
110     {
111         entry->mFiltered = false;
112     }
113 }
114 
ClearAddresses(void)115 void Filter::ClearAddresses(void)
116 {
117     for (FilterEntry &entry : mFilterEntries)
118     {
119         entry.mFiltered = false;
120     }
121 }
122 
GetNextAddress(Iterator & aIterator,Entry & aEntry) const123 Error Filter::GetNextAddress(Iterator &aIterator, Entry &aEntry) const
124 {
125     Error error = kErrorNotFound;
126 
127     for (; aIterator < GetArrayLength(mFilterEntries); aIterator++)
128     {
129         const FilterEntry &entry = mFilterEntries[aIterator];
130 
131         if (entry.mFiltered)
132         {
133             aEntry.mExtAddress = entry.mExtAddress;
134             aEntry.mRssIn      = entry.mRssIn;
135             error              = kErrorNone;
136             aIterator++;
137             break;
138         }
139     }
140 
141     return error;
142 }
143 
AddRssIn(const ExtAddress & aExtAddress,int8_t aRss)144 Error Filter::AddRssIn(const ExtAddress &aExtAddress, int8_t aRss)
145 {
146     Error        error = kErrorNone;
147     FilterEntry *entry = FindEntry(aExtAddress);
148 
149     if (entry == nullptr)
150     {
151         entry = FindAvailableEntry();
152         VerifyOrExit(entry != nullptr, error = kErrorNoBufs);
153 
154         entry->mExtAddress = aExtAddress;
155     }
156 
157     entry->mRssIn = aRss;
158 
159 exit:
160     return error;
161 }
162 
RemoveRssIn(const ExtAddress & aExtAddress)163 void Filter::RemoveRssIn(const ExtAddress &aExtAddress)
164 {
165     FilterEntry *entry = FindEntry(aExtAddress);
166 
167     VerifyOrExit(entry != nullptr);
168 
169     entry->mRssIn = kFixedRssDisabled;
170 
171 exit:
172     return;
173 }
174 
ClearAllRssIn(void)175 void Filter::ClearAllRssIn(void)
176 {
177     for (FilterEntry &entry : mFilterEntries)
178     {
179         entry.mRssIn = kFixedRssDisabled;
180     }
181 
182     mDefaultRssIn = kFixedRssDisabled;
183 }
184 
GetNextRssIn(Iterator & aIterator,Entry & aEntry)185 Error Filter::GetNextRssIn(Iterator &aIterator, Entry &aEntry)
186 {
187     Error error = kErrorNotFound;
188 
189     for (; aIterator < GetArrayLength(mFilterEntries); aIterator++)
190     {
191         FilterEntry &entry = mFilterEntries[aIterator];
192 
193         if (entry.mRssIn != kFixedRssDisabled)
194         {
195             aEntry.mExtAddress = entry.mExtAddress;
196             aEntry.mRssIn      = entry.mRssIn;
197             error              = kErrorNone;
198             aIterator++;
199             ExitNow();
200         }
201     }
202 
203     // Return the default RssIn at the end of list
204     if ((aIterator == GetArrayLength(mFilterEntries)) && (mDefaultRssIn != kFixedRssDisabled))
205     {
206         AsCoreType(&aEntry.mExtAddress).Fill(0xff);
207         aEntry.mRssIn = mDefaultRssIn;
208         error         = kErrorNone;
209         aIterator++;
210     }
211 
212 exit:
213     return error;
214 }
215 
Apply(const ExtAddress & aExtAddress,int8_t & aRss)216 Error Filter::Apply(const ExtAddress &aExtAddress, int8_t &aRss)
217 {
218     Error        error = kErrorNone;
219     FilterEntry *entry = FindEntry(aExtAddress);
220     bool         isInFilterList;
221 
222     // Use the default RssIn setting for all receiving messages first.
223     aRss = mDefaultRssIn;
224 
225     // In allowlist mode, entry must be present in the list, in
226     // denylist mode it must not be present.
227 
228     isInFilterList = (entry != nullptr) && entry->mFiltered;
229 
230     switch (mMode)
231     {
232     case kModeRssInOnly:
233         break;
234 
235     case kModeAllowlist:
236         VerifyOrExit(isInFilterList, error = kErrorAddressFiltered);
237         break;
238 
239     case kModeDenylist:
240         VerifyOrExit(!isInFilterList, error = kErrorAddressFiltered);
241         break;
242     }
243 
244     if ((entry != nullptr) && (entry->mRssIn != kFixedRssDisabled))
245     {
246         aRss = entry->mRssIn;
247     }
248 
249 exit:
250     return error;
251 }
252 
253 } // namespace Mac
254 } // namespace ot
255 
256 #endif // OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
257