Subdirectory provided by Embedded Artists
Dependencies: DM_FATFileSystem DM_HttpServer DM_USBHost EthernetInterface USBDevice mbed-rpc mbed-rtos mbed-src
Dependents: lpc4088_displaymodule_hello_world_Sept_2018
Fork of DMSupport by
Registry.cpp
00001 /* 00002 * Copyright 2014 Embedded Artists AB 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed.h" 00018 #include "DMBoard.h" 00019 #include "InternalEEPROM.h" 00020 #include "Registry.h" 00021 00022 00023 /****************************************************************************** 00024 * Defines and typedefs 00025 *****************************************************************************/ 00026 00027 //Registry::Entry::Entry(const char* key, const char* value, bool free) : 00028 // _key(key),_value(value),_freeKey(free),_freeValue(free) 00029 //{ 00030 //} 00031 // 00032 //Registry::Entry::~Entry() 00033 //{ 00034 // if (_freeKey && _key != NULL) { 00035 // free((void*)_key); 00036 // _key = NULL; 00037 // } 00038 //} 00039 // 00040 //void Registry::Entry::modify(const char* newValue) 00041 //{ 00042 // if (_freeValue && _value != NULL) { 00043 // free((void*)_value); 00044 // _value = NULL; 00045 // } 00046 // _freeValue = true; 00047 // _value = newValue; 00048 //} 00049 00050 /****************************************************************************** 00051 * Local variables 00052 *****************************************************************************/ 00053 00054 /****************************************************************************** 00055 * Private Class 00056 *****************************************************************************/ 00057 00058 /****************************************************************************** 00059 * Private Functions 00060 *****************************************************************************/ 00061 00062 Registry::Registry() : _numEntries(0), _entries(NULL) 00063 { 00064 } 00065 00066 Registry::~Registry() 00067 { 00068 if (_data != NULL) { 00069 free(_data); 00070 _data = NULL; 00071 } 00072 _numEntries = 0; 00073 _entries = NULL; 00074 } 00075 00076 Registry::RegistryError Registry::fromEEPROM() 00077 { 00078 // Registry is stored as a header followed by a nuber of key-value 00079 // pairs. Each key and value is a maximum of 31 characters + null 00080 // termination. The header looks like this: 00081 // 00082 // key = 'e','a','r','e','g','\0' 00083 // val = X 00084 // 00085 // where X is the number of key-value pairs used (one byte). 00086 // The list is compacted so that there are no unused entries in 00087 // the list. 00088 // 00089 _entries = (reg_entry_t*)_data; 00090 _numEntries = _entries[0].val[0]; 00091 for (int i = 0; i < NumEntries; i++) { 00092 _modified[i] = false; 00093 } 00094 00095 // Check header entry 00096 if (strcmp(_entries[0].key, "eareg") == 0) { 00097 00098 // Check num entries 00099 if (_numEntries < NumEntries) { 00100 00101 // list is valid, but make sure null termination is ok 00102 // just in case 00103 for (int i = 1; i <= _numEntries; i++) { 00104 _entries[i].key[EntryLen-1] = '\0'; 00105 _entries[i].val[EntryLen-1] = '\0'; 00106 } 00107 00108 return Ok; 00109 } 00110 } 00111 00112 // The list is either corrupt or doesn't exist, create one 00113 memset(_data, 0, NumEntries*sizeof(reg_entry_t)); 00114 sprintf(_entries[0].key, "eareg"); 00115 _entries[0].val[0] = _numEntries = 0; 00116 _modified[0] = true; 00117 00118 return Ok; 00119 } 00120 00121 Registry::RegistryError Registry::toEEPROM() 00122 { 00123 if (_entries[0].val[0] != _numEntries) { 00124 _entries[0].val[0] = _numEntries; 00125 _modified[0] = true; 00126 } 00127 return Ok; 00128 } 00129 00130 int Registry::find(const char* key) 00131 { 00132 for (int i = 1; i <= _numEntries; i++) { 00133 if (strcmp(key, _entries[i].key) == 0) { 00134 return i; 00135 } 00136 } 00137 return -1; 00138 } 00139 00140 /****************************************************************************** 00141 * Public Functions 00142 *****************************************************************************/ 00143 00144 Registry::RegistryError Registry::load() 00145 { 00146 InternalEEPROM eeprom; 00147 RegistryError err = Ok; 00148 00149 _mutex.lock(); 00150 if (_data != NULL) { 00151 free(_data); 00152 _data = NULL; 00153 } 00154 _numEntries = 0; 00155 _entries = NULL; 00156 00157 do { 00158 eeprom.init(); 00159 00160 _data = (uint8_t*)malloc(eeprom.memorySize()); 00161 if (_data == NULL) { 00162 err = MemoryError; 00163 break; 00164 } 00165 00166 uint32_t read = eeprom.read(0,_data,eeprom.memorySize()); 00167 if (read != eeprom.memorySize()) { 00168 err = EEPROMReadError; 00169 break; 00170 } 00171 00172 eeprom.powerDown(); 00173 00174 // decode the data 00175 err = fromEEPROM(); 00176 if (err != Ok) { 00177 free(_data); 00178 _data = NULL; 00179 } 00180 00181 } while(0); 00182 00183 _mutex.unlock(); 00184 return err; 00185 } 00186 00187 Registry::RegistryError Registry::setValue(const char* key, const char* val) 00188 { 00189 RegistryError err = Ok; 00190 _mutex.lock(); 00191 int existingIdx = find(key); 00192 if (existingIdx == -1) { 00193 // new value 00194 if (_numEntries < (NumEntries-1)) { 00195 // room for more 00196 if (strlen(key) < EntryLen) { 00197 if (strlen(val) < EntryLen) { 00198 _numEntries++; 00199 strncpy(_entries[_numEntries].key, key, EntryLen-1); 00200 strncpy(_entries[_numEntries].val, val, EntryLen-1); 00201 _modified[_numEntries] = true; 00202 } else { 00203 err = ValueLenError; 00204 } 00205 } else { 00206 err = KeyLenError; 00207 } 00208 } else { 00209 err = RegistryFullError; 00210 } 00211 } else { 00212 // already have value, modify it 00213 if (strlen(val) < EntryLen) { 00214 strncpy(_entries[existingIdx].val, val, EntryLen-1); 00215 _modified[existingIdx] = true; 00216 } else { 00217 err = ValueLenError; 00218 } 00219 } 00220 _mutex.unlock(); 00221 return err; 00222 } 00223 00224 Registry::RegistryError Registry::getValue(const char* key, char** pVal) 00225 { 00226 RegistryError err = Ok; 00227 _mutex.lock(); 00228 int existingIdx = find(key); 00229 if (existingIdx == -1) { 00230 *pVal = NULL; 00231 err = NoSuchKeyError; 00232 } else { 00233 *pVal = (char*)malloc(EntryLen); 00234 if (*pVal == NULL) { 00235 err = MemoryError; 00236 } else { 00237 strncpy(*pVal, _entries[existingIdx].val, EntryLen); 00238 } 00239 } 00240 _mutex.unlock(); 00241 return err; 00242 } 00243 00244 Registry::RegistryError Registry::entryAt(int pos, char** pKey, char** pVal) 00245 { 00246 RegistryError err = Ok; 00247 _mutex.lock(); 00248 if (pos < 0 || pos >= NumEntries) { 00249 err = InvalidPositionError; 00250 } else { 00251 *pKey = (char*)malloc(EntryLen); 00252 if (*pKey == NULL) { 00253 err = MemoryError; 00254 } else { 00255 strncpy(*pKey, _entries[pos+1].key, EntryLen); 00256 *pVal = (char*)malloc(EntryLen); 00257 if (*pVal == NULL) { 00258 err = MemoryError; 00259 free(*pKey); 00260 *pKey = NULL; 00261 } else { 00262 strncpy(*pVal, _entries[pos+1].val, EntryLen); 00263 } 00264 } 00265 } 00266 _mutex.unlock(); 00267 return err; 00268 } 00269 00270 00271 Registry::RegistryError Registry::registerListener() 00272 { 00273 return Ok; 00274 } 00275 00276 Registry::RegistryError Registry::store() 00277 { 00278 InternalEEPROM eeprom; 00279 RegistryError err = Ok; 00280 00281 _mutex.lock(); 00282 00283 do { 00284 err = toEEPROM(); 00285 if (err != Ok) { 00286 break; 00287 } 00288 00289 eeprom.init(); 00290 00291 for (int i = 0; i <= _numEntries; i++) { 00292 if (_modified[i]) { 00293 if (eeprom.write(i*EntrySize, (uint8_t*)&_entries[i], EntrySize) != EntrySize) { 00294 err = EEPROMWriteError; 00295 break; 00296 } 00297 _modified[i] = false; 00298 } 00299 } 00300 00301 eeprom.powerDown(); 00302 00303 } while(0); 00304 00305 _mutex.unlock(); 00306 00307 return err; 00308 }
Generated on Wed Jul 13 2022 02:57:23 by 1.7.2