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( NvmmCrc32Check( sizeof( RegionNvmDataGroup1_t ), offset ) == false )
190 {
191 return 0;
192 }
193 offset += sizeof( RegionNvmDataGroup1_t );
194
195 // Region group 2
196 if( NvmmCrc32Check( sizeof( RegionNvmDataGroup2_t ), offset ) == false )
197 {
198 return 0;
199 }
200 offset += sizeof( RegionNvmDataGroup2_t );
201
202 // Class b
203 if( NvmmCrc32Check( sizeof( LoRaMacClassBNvmData_t ), offset ) == false )
204 {
205 return 0;
206 }
207 offset += sizeof( LoRaMacClassBNvmData_t );
208
209 if( NvmmRead( ( uint8_t* ) nvm, sizeof( LoRaMacNvmData_t ), 0 ) ==
210 sizeof( LoRaMacNvmData_t ) )
211 {
212 return sizeof( LoRaMacNvmData_t );
213 }
214 #endif
215 return 0;
216 }
217
NvmDataMgmtFactoryReset(void)218 bool NvmDataMgmtFactoryReset( void )
219 {
220 uint16_t offset = 0;
221 #if( CONTEXT_MANAGEMENT_ENABLED == 1 )
222 // Crypto
223 if( NvmmReset( sizeof( LoRaMacCryptoNvmData_t ), offset ) == false )
224 {
225 return false;
226 }
227 offset += sizeof( LoRaMacCryptoNvmData_t );
228
229 // Mac Group 1
230 if( NvmmReset( sizeof( LoRaMacNvmDataGroup1_t ), offset ) == false )
231 {
232 return false;
233 }
234 offset += sizeof( LoRaMacNvmDataGroup1_t );
235
236 // Mac Group 2
237 if( NvmmReset( sizeof( LoRaMacNvmDataGroup2_t ), offset ) == false )
238 {
239 return false;
240 }
241 offset += sizeof( LoRaMacNvmDataGroup2_t );
242
243 // Secure element
244 if( NvmmReset( sizeof( SecureElementNvmData_t ), offset ) == false )
245 {
246 return false;
247 }
248 offset += sizeof( SecureElementNvmData_t );
249
250 // Region group 1
251 if( NvmmReset( sizeof( RegionNvmDataGroup1_t ), offset ) == false )
252 {
253 return false;
254 }
255 offset += sizeof( RegionNvmDataGroup1_t );
256
257 // Region group 2
258 if( NvmmReset( sizeof( RegionNvmDataGroup2_t ), offset ) == false )
259 {
260 return false;
261 }
262 offset += sizeof( RegionNvmDataGroup2_t );
263
264 // Class b
265 if( NvmmReset( sizeof( LoRaMacClassBNvmData_t ), offset ) == false )
266 {
267 return false;
268 }
269 offset += sizeof( LoRaMacClassBNvmData_t );
270 #endif
271 return true;
272 }
273