A board support package for the LPC4088 Display Module.

Dependencies:   DM_HttpServer DM_USBHost

Dependents:   lpc4088_displaymodule_emwin lpc4088_displaymodule_demo_sphere sampleGUI sampleEmptyGUI ... more

Fork of DMSupport by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Registry.cpp Source File

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     _data = (uint8_t*)malloc(eeprom.memorySize());
00160     if (_data == NULL) {
00161       err = MemoryError;
00162       break;
00163     }
00164 
00165     uint32_t read = eeprom.read(0,_data,eeprom.memorySize());
00166     if (read != eeprom.memorySize()) {
00167       err = EEPROMReadError;
00168       break;
00169     }
00170     eeprom.powerDown();
00171     // decode the data
00172     err = fromEEPROM();
00173     if (err != Ok) {
00174       free(_data);
00175       _data = NULL;
00176     }
00177   } while(0);
00178   _mutex.unlock();
00179   return err;
00180 }
00181 
00182 Registry::RegistryError Registry::setValue(const char* key, const char* val)
00183 {
00184   RegistryError err = Ok;
00185   _mutex.lock();
00186   int existingIdx = find(key);
00187   if (existingIdx == -1) {
00188     // new value
00189     if (_numEntries < (NumEntries-1)) {
00190       // room for more
00191      if (strlen(key) < EntryLen) {
00192        if (strlen(val) < EntryLen) {
00193          _numEntries++;
00194          strncpy(_entries[_numEntries].key, key, EntryLen-1);
00195          strncpy(_entries[_numEntries].val, val, EntryLen-1);
00196          _modified[_numEntries] = true;
00197        } else {
00198          err = ValueLenError;
00199        }
00200      } else {
00201        err = KeyLenError;
00202      }
00203     } else {
00204       err = RegistryFullError;
00205     }
00206   } else {
00207     // already have value, modify it
00208     if (strlen(val) < EntryLen) {
00209       strncpy(_entries[existingIdx].val, val, EntryLen-1);
00210       _modified[existingIdx] = true;
00211     } else {
00212       err = ValueLenError;
00213     }
00214   }
00215   _mutex.unlock();
00216   return err;
00217 }
00218 
00219 Registry::RegistryError Registry::getValue(const char* key, char** pVal)
00220 {
00221   RegistryError err = Ok;
00222   _mutex.lock();
00223   int existingIdx = find(key);
00224   if (existingIdx == -1) {
00225     *pVal = NULL;
00226     err = NoSuchKeyError;
00227   } else {
00228     *pVal = (char*)malloc(EntryLen);
00229     if (*pVal == NULL) {
00230       err = MemoryError;
00231     } else {
00232       strncpy(*pVal, _entries[existingIdx].val, EntryLen);
00233     }
00234   }
00235   _mutex.unlock();
00236   return err;
00237 }
00238 
00239 Registry::RegistryError Registry::entryAt(int pos, char** pKey, char** pVal)
00240 {
00241   RegistryError err = Ok;
00242   _mutex.lock();
00243   if (pos < 0 || pos >= NumEntries) {
00244     err = InvalidPositionError;
00245   } else {
00246     *pKey = (char*)malloc(EntryLen);
00247     if (*pKey == NULL) {
00248       err = MemoryError;
00249     } else {
00250       strncpy(*pKey, _entries[pos+1].key, EntryLen);
00251       *pVal = (char*)malloc(EntryLen);
00252       if (*pVal == NULL) {
00253         err = MemoryError;
00254         free(*pKey);
00255         *pKey = NULL;
00256       } else {
00257         strncpy(*pVal, _entries[pos+1].val, EntryLen);
00258       }
00259     }
00260   }
00261   _mutex.unlock();
00262   return err;
00263 }
00264 
00265 
00266 Registry::RegistryError Registry::registerListener()
00267 {
00268     return Ok;
00269 }
00270 
00271 Registry::RegistryError Registry::store()
00272 {
00273   InternalEEPROM eeprom;
00274   RegistryError err = Ok;
00275 
00276   _mutex.lock();
00277     
00278   do {
00279     err = toEEPROM();
00280     if (err != Ok) {
00281       break;
00282     }
00283     
00284     eeprom.init();  
00285 
00286     for (int i = 0; i <= _numEntries; i++) {
00287       if (_modified[i]) {
00288         if (eeprom.write(i*EntrySize, (uint8_t*)&_entries[i], EntrySize) != EntrySize) {
00289           err = EEPROMWriteError;
00290           break;
00291         }
00292         _modified[i] = false;
00293       }
00294     }
00295     
00296     eeprom.powerDown();
00297     
00298   } while(0);
00299   
00300   _mutex.unlock();  
00301   
00302   return err;
00303 }