• 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 source address match controller.
32  */
33 
34 #include "src_match_controller.hpp"
35 
36 #if OPENTHREAD_FTD
37 
38 #include "instance/instance.hpp"
39 
40 namespace ot {
41 
42 RegisterLogModule("SrcMatchCtrl");
43 
SourceMatchController(Instance & aInstance)44 SourceMatchController::SourceMatchController(Instance &aInstance)
45     : InstanceLocator(aInstance)
46     , mEnabled(false)
47 {
48     ClearTable();
49 }
50 
IncrementMessageCount(Child & aChild)51 void SourceMatchController::IncrementMessageCount(Child &aChild)
52 {
53     if (aChild.GetIndirectMessageCount() == 0)
54     {
55         AddEntry(aChild);
56     }
57 
58     aChild.IncrementIndirectMessageCount();
59 }
60 
DecrementMessageCount(Child & aChild)61 void SourceMatchController::DecrementMessageCount(Child &aChild)
62 {
63     if (aChild.GetIndirectMessageCount() == 0)
64     {
65         LogWarn("DecrementMessageCount(child 0x%04x) called when already at zero count.", aChild.GetRloc16());
66         ExitNow();
67     }
68 
69     aChild.DecrementIndirectMessageCount();
70 
71     if (aChild.GetIndirectMessageCount() == 0)
72     {
73         ClearEntry(aChild);
74     }
75 
76 exit:
77     return;
78 }
79 
ResetMessageCount(Child & aChild)80 void SourceMatchController::ResetMessageCount(Child &aChild)
81 {
82     aChild.ResetIndirectMessageCount();
83     ClearEntry(aChild);
84 }
85 
SetSrcMatchAsShort(Child & aChild,bool aUseShortAddress)86 void SourceMatchController::SetSrcMatchAsShort(Child &aChild, bool aUseShortAddress)
87 {
88     VerifyOrExit(aChild.IsIndirectSourceMatchShort() != aUseShortAddress);
89 
90     if (aChild.GetIndirectMessageCount() > 0)
91     {
92         ClearEntry(aChild);
93         aChild.SetIndirectSourceMatchShort(aUseShortAddress);
94         AddEntry(aChild);
95     }
96     else
97     {
98         aChild.SetIndirectSourceMatchShort(aUseShortAddress);
99     }
100 
101 exit:
102     return;
103 }
104 
ClearTable(void)105 void SourceMatchController::ClearTable(void)
106 {
107     Get<Radio>().ClearSrcMatchShortEntries();
108     Get<Radio>().ClearSrcMatchExtEntries();
109     LogDebg("Cleared all entries");
110 }
111 
Enable(bool aEnable)112 void SourceMatchController::Enable(bool aEnable)
113 {
114     mEnabled = aEnable;
115     Get<Radio>().EnableSrcMatch(mEnabled);
116     LogDebg("%sabling", mEnabled ? "En" : "Dis");
117 }
118 
AddEntry(Child & aChild)119 void SourceMatchController::AddEntry(Child &aChild)
120 {
121     aChild.SetIndirectSourceMatchPending(true);
122 
123     if (!IsEnabled())
124     {
125         SuccessOrExit(AddPendingEntries());
126         Enable(true);
127     }
128     else
129     {
130         VerifyOrExit(AddAddress(aChild) == kErrorNone, Enable(false));
131         aChild.SetIndirectSourceMatchPending(false);
132     }
133 
134 exit:
135     return;
136 }
137 
AddAddress(const Child & aChild)138 Error SourceMatchController::AddAddress(const Child &aChild)
139 {
140     Error error = kErrorNone;
141 
142     if (aChild.IsIndirectSourceMatchShort())
143     {
144         error = Get<Radio>().AddSrcMatchShortEntry(aChild.GetRloc16());
145 
146         LogDebg("Adding short addr: 0x%04x -- %s (%d)", aChild.GetRloc16(), ErrorToString(error), error);
147     }
148     else
149     {
150         error = Get<Radio>().AddSrcMatchExtEntry(aChild.GetExtAddress());
151 
152         LogDebg("Adding addr: %s -- %s (%d)", aChild.GetExtAddress().ToString().AsCString(), ErrorToString(error),
153                 error);
154     }
155 
156     return error;
157 }
158 
ClearEntry(Child & aChild)159 void SourceMatchController::ClearEntry(Child &aChild)
160 {
161     Error error = kErrorNone;
162 
163     if (aChild.IsIndirectSourceMatchPending())
164     {
165         LogDebg("Clearing pending flag for 0x%04x", aChild.GetRloc16());
166         aChild.SetIndirectSourceMatchPending(false);
167         ExitNow();
168     }
169 
170     if (aChild.IsIndirectSourceMatchShort())
171     {
172         error = Get<Radio>().ClearSrcMatchShortEntry(aChild.GetRloc16());
173 
174         LogDebg("Clearing short addr: 0x%04x -- %s (%d)", aChild.GetRloc16(), ErrorToString(error), error);
175     }
176     else
177     {
178         error = Get<Radio>().ClearSrcMatchExtEntry(aChild.GetExtAddress());
179 
180         LogDebg("Clearing addr: %s -- %s (%d)", aChild.GetExtAddress().ToString().AsCString(), ErrorToString(error),
181                 error);
182     }
183 
184     SuccessOrExit(error);
185 
186     if (!IsEnabled())
187     {
188         SuccessOrExit(AddPendingEntries());
189         Enable(true);
190     }
191 
192 exit:
193     return;
194 }
195 
AddPendingEntries(void)196 Error SourceMatchController::AddPendingEntries(void)
197 {
198     Error error = kErrorNone;
199 
200     for (Child &child : Get<ChildTable>().Iterate(Child::kInStateValidOrRestoring))
201     {
202         if (child.IsIndirectSourceMatchPending())
203         {
204             SuccessOrExit(error = AddAddress(child));
205             child.SetIndirectSourceMatchPending(false);
206         }
207     }
208 
209 exit:
210     return error;
211 }
212 
213 } // namespace ot
214 
215 #endif // OPENTHREAD_FTD
216