1 /*!
2 * \file NvmDataMgmt.c
3 *
4 * \brief NVM context management implementation
5 *
6 * \copyright Revised BSD License, see section \ref LICENSE.
7 *
8 * \code
9 * ______ _
10 * / _____) _ | |
11 * ( (____ _____ ____ _| |_ _____ ____| |__
12 * \____ \| ___ | (_ _) ___ |/ ___) _ \
13 * _____) ) ____| | | || |_| ____( (___| | | |
14 * (______/|_____)_|_|_| \__)_____)\____)_| |_|
15 * (C)2013-2017 Semtech
16 *
17 * ___ _____ _ ___ _ _____ ___ ___ ___ ___
18 * / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|
19 * \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|
20 * |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
21 * embedded.connectivity.solutions===============
22 *
23 * \endcode
24 *
25 * \author Miguel Luis ( Semtech )
26 *
27 * \author Gregory Cristian ( Semtech )
28 *
29 * \author Daniel Jaeckle ( STACKFORCE )
30 *
31 * \author Johannes Bruder ( STACKFORCE )
32 */
33
34 #include <stdio.h>
35 #include "utilities.h"
36 #include "nvmm.h"
37 #include "LoRaMac.h"
38 #include "NvmDataMgmt.h"
39
40 /*!
41 * Enables/Disables the context storage management storage.
42 * Must be enabled for LoRaWAN 1.0.4 or later.
43 */
44 #ifndef CONTEXT_MANAGEMENT_ENABLED
45 #define CONTEXT_MANAGEMENT_ENABLED 1
46 #endif
47
48
49 static uint16_t NvmNotifyFlags = 0;
50
NvmDataMgmtEvent(uint16_t notifyFlags)51 void NvmDataMgmtEvent( uint16_t notifyFlags )
52 {
53 NvmNotifyFlags = notifyFlags;
54 }
55
NvmDataMgmtStore(void)56 uint16_t NvmDataMgmtStore( void )
57 {
58 #if( CONTEXT_MANAGEMENT_ENABLED == 1 )
59 uint16_t offset = 0;
60 uint16_t dataSize = 0;
61 MibRequestConfirm_t mibReq;
62 mibReq.Type = MIB_NVM_CTXS;
63 LoRaMacMibGetRequestConfirm( &mibReq );
64 LoRaMacNvmData_t* nvm = mibReq.Param.Contexts;
65
66 // Input checks
67 if( NvmNotifyFlags == LORAMAC_NVM_NOTIFY_FLAG_NONE )
68 {
69 // There was no update.
70 return 0;
71 }
72 if( LoRaMacStop( ) != LORAMAC_STATUS_OK )
73 {
74 return 0;
75 }
76
77 // Crypto
78 if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_CRYPTO ) ==
79 LORAMAC_NVM_NOTIFY_FLAG_CRYPTO )
80 {
81 dataSize += NvmmWrite( ( uint8_t* ) &nvm->Crypto, sizeof( nvm->Crypto ),
82 offset );
83 }
84 offset += sizeof( nvm->Crypto );
85
86 // MacGroup1
87 if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1 ) ==
88 LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP1 )
89 {
90 dataSize += NvmmWrite( ( uint8_t* ) &nvm->MacGroup1,
91 sizeof( nvm->MacGroup1 ), offset );
92 }
93 offset += sizeof( nvm->MacGroup1 );
94
95 // MacGroup2
96 if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2 ) ==
97 LORAMAC_NVM_NOTIFY_FLAG_MAC_GROUP2 )
98 {
99 dataSize += NvmmWrite( ( uint8_t* ) &nvm->MacGroup2,
100 sizeof( nvm->MacGroup2 ), offset );
101 }
102 offset += sizeof( nvm->MacGroup2 );
103
104 // Secure element
105 if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT ) ==
106 LORAMAC_NVM_NOTIFY_FLAG_SECURE_ELEMENT )
107 {
108 dataSize += NvmmWrite( ( uint8_t* ) &nvm->SecureElement, sizeof( nvm->SecureElement ),
109 offset );
110 }
111 offset += sizeof( nvm->SecureElement );
112
113 // Region group 1
114 if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1 ) ==
115 LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP1 )
116 {
117 dataSize += NvmmWrite( ( uint8_t* ) &nvm->RegionGroup1,
118 sizeof( nvm->RegionGroup1 ), offset );
119 }
120 offset += sizeof( nvm->RegionGroup1 );
121
122 // Region group 2
123 if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2 ) ==
124 LORAMAC_NVM_NOTIFY_FLAG_REGION_GROUP2 )
125 {
126 dataSize += NvmmWrite( ( uint8_t* ) &nvm->RegionGroup2,
127 sizeof( nvm->RegionGroup2 ), offset );
128 }
129 offset += sizeof( nvm->RegionGroup2 );
130
131 // Class b
132 if( ( NvmNotifyFlags & LORAMAC_NVM_NOTIFY_FLAG_CLASS_B ) ==
133 LORAMAC_NVM_NOTIFY_FLAG_CLASS_B )
134 {
135 dataSize += NvmmWrite( ( uint8_t* ) &nvm->ClassB, sizeof( nvm->ClassB ),
136 offset );
137 }
138 offset += sizeof( nvm->ClassB );
139
140 // Reset notification flags
141 NvmNotifyFlags = LORAMAC_NVM_NOTIFY_FLAG_NONE;
142
143 // Resume LoRaMac
144 LoRaMacStart( );
145 return dataSize;
146 #else
147 return 0;
148 #endif
149 }
150
NvmDataMgmtRestore(void)151 uint16_t NvmDataMgmtRestore( void )
152 {
153 #if( CONTEXT_MANAGEMENT_ENABLED == 1 )
154 MibRequestConfirm_t mibReq;
155 mibReq.Type = MIB_NVM_CTXS;
156 LoRaMacMibGetRequestConfirm( &mibReq );
157 LoRaMacNvmData_t* nvm = mibReq.Param.Contexts;
158 uint16_t offset = 0;
159
160 // Crypto
161 if( NvmmCrc32Check( sizeof( LoRaMacCryptoNvmData_t ), offset ) == false )
162 {
163 return 0;
164 }
165 offset += sizeof( LoRaMacCryptoNvmData_t );
166
167 // Mac Group 1
168 if( NvmmCrc32Check( sizeof( LoRaMacNvmDataGroup1_t ), offset ) == false )
169 {
170 return 0;
171 }
172 offset += sizeof( LoRaMacNvmDataGroup1_t );
173
174 // Mac Group 2
175 if( NvmmCrc32Check( sizeof( LoRaMacNvmDataGroup2_t ), offset ) == false )
176 {
177 return 0;
178 }
179 offset += sizeof( LoRaMacNvmDataGroup2_t );
180
181 // Secure element
182 if( NvmmCrc32Check( sizeof( SecureElementNvmData_t ), offset ) == false )
183 {
184 return 0;
185 }
186 offset += sizeof( SecureElementNvmData_t );
187
188 // Region group 1
189 if( sizeof( RegionNvmDataGroup1_t ) > sizeof( uint32_t ) )
190 {
191 if( NvmmCrc32Check( sizeof( RegionNvmDataGroup1_t ), offset ) == false )
192 {
193 return 0;
194 }
195 }
196 offset += sizeof( RegionNvmDataGroup1_t );
197
198 // Region group 2
199 if( NvmmCrc32Check( sizeof( RegionNvmDataGroup2_t ), offset ) == false )
200 {
201 return 0;
202 }
203 offset += sizeof( RegionNvmDataGroup2_t );
204
205 // Class b
206 if( NvmmCrc32Check( sizeof( LoRaMacClassBNvmData_t ), offset ) == false )
207 {
208 return 0;
209 }
210 offset += sizeof( LoRaMacClassBNvmData_t );
211
212 if( NvmmRead( ( uint8_t* ) nvm, sizeof( LoRaMacNvmData_t ), 0 ) ==
213 sizeof( LoRaMacNvmData_t ) )
214 {
215 return sizeof( LoRaMacNvmData_t );
216 }
217 #endif
218 return 0;
219 }
220
NvmDataMgmtFactoryReset(void)221 bool NvmDataMgmtFactoryReset( void )
222 {
223 uint16_t offset = 0;
224 #if( CONTEXT_MANAGEMENT_ENABLED == 1 )
225 // Crypto
226 if( NvmmReset( sizeof( LoRaMacCryptoNvmData_t ), offset ) == false )
227 {
228 return false;
229 }
230 offset += sizeof( LoRaMacCryptoNvmData_t );
231
232 // Mac Group 1
233 if( NvmmReset( sizeof( LoRaMacNvmDataGroup1_t ), offset ) == false )
234 {
235 return false;
236 }
237 offset += sizeof( LoRaMacNvmDataGroup1_t );
238
239 // Mac Group 2
240 if( NvmmReset( sizeof( LoRaMacNvmDataGroup2_t ), offset ) == false )
241 {
242 return false;
243 }
244 offset += sizeof( LoRaMacNvmDataGroup2_t );
245
246 // Secure element
247 if( NvmmReset( sizeof( SecureElementNvmData_t ), offset ) == false )
248 {
249 return false;
250 }
251 offset += sizeof( SecureElementNvmData_t );
252
253 // Region group 1
254 if( NvmmReset( sizeof( RegionNvmDataGroup1_t ), offset ) == false )
255 {
256 return false;
257 }
258 offset += sizeof( RegionNvmDataGroup1_t );
259
260 // Region group 2
261 if( NvmmReset( sizeof( RegionNvmDataGroup2_t ), offset ) == false )
262 {
263 return false;
264 }
265 offset += sizeof( RegionNvmDataGroup2_t );
266
267 // Class b
268 if( NvmmReset( sizeof( LoRaMacClassBNvmData_t ), offset ) == false )
269 {
270 return false;
271 }
272 offset += sizeof( LoRaMacClassBNvmData_t );
273 #endif
274 return true;
275 }
276