/ src / app / app_settings.cpp
app_settings.cpp
  1  #include "app_settings.h"
  2  
  3  #include "app_log_module.ii"
  4  
  5  namespace app::settings
  6  {
  7  	namespace
  8  	{
  9  		const char* settingsFilePath = "/sys/settings.bin";
 10  		constexpr size_t settingsBufferSize = 256;
 11  		bool Parse(const uint8_t* fileData, size_t dataLength);
 12  
 13  		static_assert (settingsBufferSize >= sizeof(app_settings_t) + 16);
 14  	}
 15  
 16  	bool Load(files::Littlefs& flash)
 17  	{
 18  		uint8_t buffer[settingsBufferSize] = { 0 };
 19  		if (flash.IsMounted())
 20  		{
 21  			NRF_LOG_VERBOSE("Loading config from flash `%s`", settingsFilePath);
 22  			files::FlashFile file;
 23  			if (flash.FileOpen(file, settingsFilePath, LFS_O_RDONLY))
 24  			{
 25  				size_t readAmount;
 26  				if (flash.FileRead(file, buffer, settingsBufferSize, &readAmount))
 27  				{
 28  					flash.FileClose(file);
 29  
 30  					if (readAmount == 0)
 31  					{
 32  						NRF_LOG_WARNING("Read settings file, but it was empty.");
 33  						return false;
 34  					}
 35  					else
 36  					{
 37  						if (Parse(buffer, readAmount) == false)
 38  						{
 39  							NRF_LOG_WARNING("Failed to parse settings file!");
 40  							return false;
 41  						}
 42  
 43  						return true;
 44  					}
 45  				}
 46  				else
 47  				{
 48  					NRF_LOG_WARNING("Failed to read settings file!");
 49  					return false;
 50  				}
 51  			}
 52  			else
 53  			{
 54  				NRF_LOG_WARNING("Failed to open settings file!");
 55  				return false;
 56  			}
 57  		}
 58  		else
 59  		{
 60  			NRF_LOG_WARNING("Cannot load settings with flash device unmounted.");
 61  			return false;
 62  		}
 63  	}
 64  
 65  	bool Save(files::Littlefs& flash)
 66  	{
 67  		if (flash.IsMounted())
 68  		{
 69  			NRF_LOG_VERBOSE("Saving config to flash `%s`", settingsFilePath);
 70  			files::FlashFile file;
 71  			if (flash.FileOpen(file, settingsFilePath, LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC))
 72  			{
 73  				size_t wroteAmount;
 74  				if (flash.FileWrite(file, &SETTINGS, sizeof(SETTINGS), &wroteAmount))
 75  				{
 76  					if (flash.FileClose(file))
 77  					{
 78  						NRF_LOG_VERBOSE("Settings saved.");
 79  						return true;
 80  					}
 81  					else
 82  					{
 83  						NRF_LOG_WARNING("Failed to close file after writing, save may have been successful...");
 84  						return false;
 85  					}
 86  				}
 87  				else
 88  				{
 89  					NRF_LOG_WARNING("Failed to write settings file!");
 90  					return false;
 91  				}
 92  			}
 93  			else
 94  			{
 95  				NRF_LOG_WARNING("Failed to open settings file!");
 96  				return false;
 97  			}
 98  		}
 99  		else
100  		{
101  			NRF_LOG_WARNING("Cannot save settings with flash device unmounted.");
102  			return false;
103  		}
104  
105  		return false;
106  	}
107  
108  	namespace
109  	{
110  		bool Parse(const uint8_t* fileData, size_t dataLength)
111  		{
112  			uint32_t version = 0xFFFFFFFF;
113  			// make sure we're working on the same size data here.
114  			static_assert(sizeof(version) == sizeof(SETTINGS.version));
115  
116  			memcpy(&version, fileData, sizeof(version));
117  
118  			size_t settingsSize = sizeof(SETTINGS);
119  
120  			if (version == CURRENT_SETTINGS_VERSION && dataLength == settingsSize)
121  			{
122  				// happy path, we can memcopy the data and we're done.
123  				memcpy(&SETTINGS, fileData, settingsSize);
124  				return true;
125  			}
126  			else if (version != CURRENT_SETTINGS_VERSION)
127  			{
128  				// #todo: handle version upgrading. As there's only one version now,
129  				// we don't have anything to do here, we just can't help if you get here.
130  				return false;
131  			}
132  			else if (dataLength != settingsSize)
133  			{
134  				// version matched, but size didn't match, we will handle this
135  				// by failing, and allowing default settings to get created.
136  				return false;
137  			}
138  
139  			return false;
140  		}
141  	}
142  }