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