• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2019, 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 a software Source Match table, for radios that don't have
32  *   such hardware acceleration. It supports only the single-instance build of
33  *   OpenThread.
34  */
35 
36 #include "utils/soft_source_match_table.h"
37 
38 #include <stdlib.h>
39 #include <string.h>
40 
41 #include <openthread/logging.h>
42 
43 #include "utils/code_utils.h"
44 
45 #if RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM || RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
46 static uint16_t sPanId = 0;
47 
utilsSoftSrcMatchSetPanId(uint16_t aPanId)48 void utilsSoftSrcMatchSetPanId(uint16_t aPanId) { sPanId = aPanId; }
49 #endif // RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM || RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
50 
51 #if RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM
52 typedef struct srcMatchShortEntry
53 {
54     uint16_t checksum;
55     bool     allocated;
56 } sSrcMatchShortEntry;
57 
58 static sSrcMatchShortEntry srcMatchShortEntry[RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM];
59 
utilsSoftSrcMatchShortFindEntry(uint16_t aShortAddress)60 int16_t utilsSoftSrcMatchShortFindEntry(uint16_t aShortAddress)
61 {
62     int16_t  entry    = -1;
63     uint16_t checksum = aShortAddress + sPanId;
64 
65     for (int16_t i = 0; i < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM; i++)
66     {
67         if (checksum == srcMatchShortEntry[i].checksum && srcMatchShortEntry[i].allocated)
68         {
69             entry = i;
70             break;
71         }
72     }
73 
74     return entry;
75 }
76 
findSrcMatchShortAvailEntry(void)77 static int16_t findSrcMatchShortAvailEntry(void)
78 {
79     int16_t entry = -1;
80 
81     for (int16_t i = 0; i < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM; i++)
82     {
83         if (!srcMatchShortEntry[i].allocated)
84         {
85             entry = i;
86             break;
87         }
88     }
89 
90     return entry;
91 }
92 
addToSrcMatchShortIndirect(uint16_t entry,uint16_t aShortAddress)93 static inline void addToSrcMatchShortIndirect(uint16_t entry, uint16_t aShortAddress)
94 {
95     uint16_t checksum = aShortAddress + sPanId;
96 
97     srcMatchShortEntry[entry].checksum  = checksum;
98     srcMatchShortEntry[entry].allocated = true;
99 }
100 
removeFromSrcMatchShortIndirect(uint16_t entry)101 static inline void removeFromSrcMatchShortIndirect(uint16_t entry)
102 {
103     srcMatchShortEntry[entry].allocated = false;
104     srcMatchShortEntry[entry].checksum  = 0;
105 }
106 
otPlatRadioAddSrcMatchShortEntry(otInstance * aInstance,uint16_t aShortAddress)107 otError otPlatRadioAddSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
108 {
109     OT_UNUSED_VARIABLE(aInstance);
110 
111     otError error = OT_ERROR_NONE;
112     int16_t entry = -1;
113 
114     entry = findSrcMatchShortAvailEntry();
115     otLogDebgPlat("Add ShortAddr entry: %d", entry);
116 
117     otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM, error = OT_ERROR_NO_BUFS);
118 
119     addToSrcMatchShortIndirect((uint16_t)entry, aShortAddress);
120 
121 exit:
122     return error;
123 }
124 
otPlatRadioClearSrcMatchShortEntry(otInstance * aInstance,uint16_t aShortAddress)125 otError otPlatRadioClearSrcMatchShortEntry(otInstance *aInstance, uint16_t aShortAddress)
126 {
127     OT_UNUSED_VARIABLE(aInstance);
128 
129     otError error = OT_ERROR_NONE;
130     int16_t entry = -1;
131 
132     entry = utilsSoftSrcMatchShortFindEntry(aShortAddress);
133     otLogDebgPlat("Clear ShortAddr entry: %d", entry);
134 
135     otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM, error = OT_ERROR_NO_ADDRESS);
136 
137     removeFromSrcMatchShortIndirect((uint16_t)entry);
138 
139 exit:
140     return error;
141 }
142 
otPlatRadioClearSrcMatchShortEntries(otInstance * aInstance)143 void otPlatRadioClearSrcMatchShortEntries(otInstance *aInstance)
144 {
145     OT_UNUSED_VARIABLE(aInstance);
146 
147     otLogDebgPlat("Clear ShortAddr entries");
148 
149     memset(srcMatchShortEntry, 0, sizeof(srcMatchShortEntry));
150 }
151 #endif // RADIO_CONFIG_SRC_MATCH_SHORT_ENTRY_NUM
152 
153 #if RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
154 typedef struct srcMatchExtEntry
155 {
156     uint16_t checksum;
157     bool     allocated;
158 } sSrcMatchExtEntry;
159 
160 static sSrcMatchExtEntry srcMatchExtEntry[RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM];
161 
utilsSoftSrcMatchExtFindEntry(const otExtAddress * aExtAddress)162 int16_t utilsSoftSrcMatchExtFindEntry(const otExtAddress *aExtAddress)
163 {
164     int16_t  entry    = -1;
165     uint16_t checksum = sPanId;
166 
167     checksum += (uint16_t)aExtAddress->m8[0] | (uint16_t)(aExtAddress->m8[1] << 8);
168     checksum += (uint16_t)aExtAddress->m8[2] | (uint16_t)(aExtAddress->m8[3] << 8);
169     checksum += (uint16_t)aExtAddress->m8[4] | (uint16_t)(aExtAddress->m8[5] << 8);
170     checksum += (uint16_t)aExtAddress->m8[6] | (uint16_t)(aExtAddress->m8[7] << 8);
171 
172     for (int16_t i = 0; i < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM; i++)
173     {
174         if (checksum == srcMatchExtEntry[i].checksum && srcMatchExtEntry[i].allocated)
175         {
176             entry = i;
177             break;
178         }
179     }
180 
181     return entry;
182 }
183 
findSrcMatchExtAvailEntry(void)184 static int16_t findSrcMatchExtAvailEntry(void)
185 {
186     int16_t entry = -1;
187 
188     for (int16_t i = 0; i < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM; i++)
189     {
190         if (!srcMatchExtEntry[i].allocated)
191         {
192             entry = i;
193             break;
194         }
195     }
196 
197     return entry;
198 }
199 
addToSrcMatchExtIndirect(uint16_t entry,const otExtAddress * aExtAddress)200 static inline void addToSrcMatchExtIndirect(uint16_t entry, const otExtAddress *aExtAddress)
201 {
202     uint16_t checksum = sPanId;
203 
204     checksum += (uint16_t)aExtAddress->m8[0] | (uint16_t)(aExtAddress->m8[1] << 8);
205     checksum += (uint16_t)aExtAddress->m8[2] | (uint16_t)(aExtAddress->m8[3] << 8);
206     checksum += (uint16_t)aExtAddress->m8[4] | (uint16_t)(aExtAddress->m8[5] << 8);
207     checksum += (uint16_t)aExtAddress->m8[6] | (uint16_t)(aExtAddress->m8[7] << 8);
208 
209     srcMatchExtEntry[entry].checksum  = checksum;
210     srcMatchExtEntry[entry].allocated = true;
211 }
212 
removeFromSrcMatchExtIndirect(uint16_t entry)213 static inline void removeFromSrcMatchExtIndirect(uint16_t entry)
214 {
215     srcMatchExtEntry[entry].allocated = false;
216     srcMatchExtEntry[entry].checksum  = 0;
217 }
218 
otPlatRadioAddSrcMatchExtEntry(otInstance * aInstance,const otExtAddress * aExtAddress)219 otError otPlatRadioAddSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
220 {
221     OT_UNUSED_VARIABLE(aInstance);
222 
223     otError error = OT_ERROR_NONE;
224     int16_t entry = -1;
225 
226     entry = findSrcMatchExtAvailEntry();
227     otLogDebgPlat("Add ExtAddr entry: %d", entry);
228 
229     otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM, error = OT_ERROR_NO_BUFS);
230 
231     addToSrcMatchExtIndirect((uint16_t)entry, aExtAddress);
232 
233 exit:
234     return error;
235 }
236 
otPlatRadioClearSrcMatchExtEntry(otInstance * aInstance,const otExtAddress * aExtAddress)237 otError otPlatRadioClearSrcMatchExtEntry(otInstance *aInstance, const otExtAddress *aExtAddress)
238 {
239     OT_UNUSED_VARIABLE(aInstance);
240 
241     otError error = OT_ERROR_NONE;
242     int16_t entry = -1;
243 
244     entry = utilsSoftSrcMatchExtFindEntry(aExtAddress);
245     otLogDebgPlat("Clear ExtAddr entry: %d", entry);
246 
247     otEXPECT_ACTION(entry >= 0 && entry < RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM, error = OT_ERROR_NO_ADDRESS);
248 
249     removeFromSrcMatchExtIndirect((uint16_t)entry);
250 
251 exit:
252     return error;
253 }
254 
otPlatRadioClearSrcMatchExtEntries(otInstance * aInstance)255 void otPlatRadioClearSrcMatchExtEntries(otInstance *aInstance)
256 {
257     OT_UNUSED_VARIABLE(aInstance);
258 
259     otLogDebgPlat("Clear ExtAddr entries");
260 
261     memset(srcMatchExtEntry, 0, sizeof(srcMatchExtEntry));
262 }
263 #endif // RADIO_CONFIG_SRC_MATCH_EXT_ENTRY_NUM
264