11#include " CustomControlMap.h"
22#include " UI/UI.h"
33
4+ namespace {
5+ const string c_uad_storage_path = " /map.uad" ;
6+ }
7+
8+ size_t CustomControlMap::GetCurrentMaxUADSize () const {
9+ #if DEVICE_STORAGE == 1
10+ if (MatrixOS::FileSystem::Available ())
11+ {
12+ return MAX_UAD_SIZE_STORAGE;
13+ }
14+ #endif
15+ return MAX_UAD_SIZE_NVS;
16+ }
17+
418void CustomControlMap::Setup (const vector<string>& args) {
5- LoadUADfromNVS ();
19+ LoadSavedUAD ();
620}
721
822void CustomControlMap::Loop () {
@@ -13,39 +27,116 @@ void CustomControlMap::Loop() {
1327 HIDReportHandler ();
1428}
1529
30+ void CustomControlMap::LoadSavedUAD () {
31+ #if DEVICE_STORAGE == 1
32+ if (MatrixOS::FileSystem::Available () && LoadUADfromStorage ())
33+ {
34+ return ;
35+ }
36+ #endif
37+
38+ LoadUADfromNVS ();
39+ }
40+
41+ #if DEVICE_STORAGE == 1
42+ bool CustomControlMap::LoadUADfromStorage () {
43+ if (!MatrixOS::FileSystem::Available ())
44+ {
45+ return false ;
46+ }
47+
48+ if (!MatrixOS::FileSystem::Exists (c_uad_storage_path))
49+ {
50+ MLOGD (" CustomControlMap" , " No map found in storage" );
51+ return false ;
52+ }
53+
54+ uadRT.UnloadUAD ();
55+ vPortFree (uadData);
56+ uadData = nullptr ;
57+
58+ uadSize = 0 ;
59+
60+ File file = MatrixOS::FileSystem::Open (c_uad_storage_path, " rb" );
61+ size_t new_uad_size = file.Size ();
62+ MLOGD (" CustomControlMap" , " Storage map size: %d" , new_uad_size);
63+ if (new_uad_size == 0 || new_uad_size > MAX_UAD_SIZE_STORAGE)
64+ {
65+ MLOGE (" CustomControlMap" , " Invalid map size in storage (%d bytes)" , new_uad_size);
66+ file.Close ();
67+ return false ;
68+ }
69+
70+ uadData = (uint8_t *)pvPortMalloc (new_uad_size);
71+ if (uadData == nullptr )
72+ {
73+ MLOGE (" CustomControlMap" , " Failed to allocate memory for map from storage (%d bytes requested, %d bytes free)" , new_uad_size, xPortGetFreeHeapSize ());
74+ file.Close ();
75+ return false ;
76+ }
77+
78+ if (file.Read (uadData, new_uad_size) != new_uad_size)
79+ {
80+ MLOGE (" CustomControlMap" , " Failed to read map from storage" );
81+ file.Close ();
82+ vPortFree (uadData);
83+ uadData = nullptr ;
84+ return false ;
85+ }
86+ file.Close ();
87+
88+ if (!uadRT.LoadUAD (uadData, new_uad_size))
89+ {
90+ MLOGE (" CustomControlMap" , " Failed to load map from storage" );
91+ vPortFree (uadData);
92+ uadData = nullptr ;
93+ return false ;
94+ }
95+
96+ uadSize = new_uad_size;
97+ return true ;
98+ }
99+ #endif
100+
16101void CustomControlMap::LoadUADfromNVS () {
17102 uadRT.UnloadUAD ();
18103 vPortFree (uadData);
104+ uadData = nullptr ;
19105
20106 uadSize = 0 ;
21107
22108 size_t new_uad_size = MatrixOS::NVS::GetSize (UAD_NVS_HASH);
23109
24- MLOGD (" CustomControlMap" , " NVS UAD Size : %d" , new_uad_size);
110+ MLOGD (" CustomControlMap" , " NVS map size : %d" , new_uad_size);
25111 if (new_uad_size == -1 || new_uad_size == 0 )
26112 {
27- MLOGD (" CustomControlMap" , " No UAD found in NVS" );
113+ MLOGD (" CustomControlMap" , " No map found in NVS" );
114+ return ;
115+ }
116+ if (new_uad_size > MAX_UAD_SIZE_NVS)
117+ {
118+ MLOGE (" CustomControlMap" , " Map in NVS exceeds NVS limit (%d > %d)" , new_uad_size, MAX_UAD_SIZE_NVS);
28119 return ;
29120 }
30121
31122 uadData = (uint8_t *)pvPortMalloc (new_uad_size);
32123 if (uadData == nullptr )
33124 {
34- MLOGE (" CustomControlMap" , " Failed to allocate memory for UAD (%d bytes requested, %d bytes free)" , new_uad_size, xPortGetFreeHeapSize ());
125+ MLOGE (" CustomControlMap" , " Failed to allocate memory for map from NVS (%d bytes requested, %d bytes free)" , new_uad_size, xPortGetFreeHeapSize ());
35126 return ;
36127 }
37128
38129 if (MatrixOS::NVS::GetVariable (UAD_NVS_HASH, uadData, new_uad_size) != 0 )
39130 {
40- MLOGE (" CustomControlMap" , " Failed to read UAD from NVS" );
131+ MLOGE (" CustomControlMap" , " Failed to read map from NVS" );
41132 vPortFree (uadData);
42133 uadData = nullptr ;
43134 return ;
44135 }
45136
46137 if (!uadRT.LoadUAD (uadData, new_uad_size))
47138 {
48- MLOGE (" CustomControlMap" , " Failed to load UAD " );
139+ MLOGE (" CustomControlMap" , " Failed to load map from NVS " );
49140 vPortFree (uadData);
50141 uadData = nullptr ;
51142 return ;
@@ -54,6 +145,26 @@ void CustomControlMap::LoadUADfromNVS() {
54145 uadSize = new_uad_size;
55146}
56147
148+ #if DEVICE_STORAGE == 1
149+ bool CustomControlMap::SaveUADtoStorage () {
150+ if (!MatrixOS::FileSystem::Available ())
151+ {
152+ return false ;
153+ }
154+
155+ File file = MatrixOS::FileSystem::Open (c_uad_storage_path, " wb" );
156+ if (file.Write (uadData, uadSize) != uadSize)
157+ {
158+ file.Close ();
159+ return false ;
160+ }
161+
162+ bool flush_ok = file.Flush ();
163+ file.Close ();
164+ return flush_ok;
165+ }
166+ #endif
167+
57168bool CustomControlMap::SaveUADtoNVS () {
58169 return MatrixOS::NVS::SetVariable (UAD_NVS_HASH, uadData, uadSize);
59170}
@@ -124,11 +235,12 @@ void CustomControlMap::HIDReportHandler() {
124235
125236void CustomControlMap::PrepNewUAD (const uint8_t * report) {
126237 uint32_t new_uad_size = (report[2 ] << 24 ) | (report[3 ] << 16 ) | (report[4 ] << 8 ) | report[5 ];
238+ size_t max_uad_size = GetCurrentMaxUADSize ();
127239 MLOGD (" CustomControlMap" , " Prep New UAD with Size: %d" , new_uad_size);
128240
129- if (new_uad_size > MAX_UAD_SIZE )
241+ if (new_uad_size > max_uad_size )
130242 {
131- MLOGE (" CustomControlMap" , " UAD size exceeds limit (%d > %d)" , new_uad_size, MAX_UAD_SIZE );
243+ MLOGE (" CustomControlMap" , " UAD size exceeds limit (%d > %d)" , new_uad_size, max_uad_size );
132244 SendError (report[0 ], 3 ); // UAD Size too large
133245 return ;
134246 }
@@ -196,18 +308,57 @@ void CustomControlMap::SaveUAD() {
196308 return ;
197309 }
198310
199- if (!SaveUADtoNVS ())
311+ bool save_ok = false ;
312+ if (uadSize <= MAX_UAD_SIZE_NVS)
200313 {
201- MLOGE (" CustomControlMap" , " Failed to save UAD to NVS (%d bytes)" , uadSize);
202- SendError (UAD_SAVE, 3 ); // Failed to save UAD to NVS
314+ save_ok = SaveUADtoNVS ();
315+ if (!save_ok)
316+ {
317+ MLOGE (" CustomControlMap" , " Failed to save map to NVS (%d bytes)" , uadSize);
318+ }
319+ #if DEVICE_STORAGE == 1
320+ else if (MatrixOS::FileSystem::Available () && MatrixOS::FileSystem::Exists (c_uad_storage_path))
321+ {
322+ if (!MatrixOS::FileSystem::Remove (c_uad_storage_path))
323+ {
324+ MLOGE (" CustomControlMap" , " Failed to remove stale map from storage" );
325+ }
326+ }
327+ #endif
328+ }
329+ else
330+ {
331+ #if DEVICE_STORAGE == 1
332+ if (MatrixOS::FileSystem::Available ())
333+ {
334+ save_ok = SaveUADtoStorage ();
335+ if (!save_ok)
336+ {
337+ MLOGE (" CustomControlMap" , " Failed to save map to storage (%d bytes)" , uadSize);
338+ }
339+ else if (MatrixOS::NVS::GetSize (UAD_NVS_HASH) > 0 && !MatrixOS::NVS::DeleteVariable (UAD_NVS_HASH))
340+ {
341+ MLOGE (" CustomControlMap" , " Failed to remove stale map from NVS" );
342+ }
343+ }
344+ #endif
345+ if (!save_ok)
346+ {
347+ MLOGE (" CustomControlMap" , " Map exceeds NVS limit and no storage is available (%d bytes)" , uadSize);
348+ }
349+ }
350+
351+ if (!save_ok)
352+ {
353+ SendError (UAD_SAVE, 3 ); // Failed to save map
203354 return ;
204355 }
205356
206357 SendAck (UAD_SAVE | HID_RESPONSE);
207358}
208359
209360void CustomControlMap::LoadUAD () {
210- LoadUADfromNVS ();
361+ LoadSavedUAD ();
211362 SendAck (UAD_LOAD | HID_RESPONSE);
212363}
213364
@@ -234,6 +385,7 @@ void CustomControlMap::BeginUAD() {
234385}
235386
236387void CustomControlMap::SendDeviceDescriptor () {
388+ size_t max_uad_size = GetCurrentMaxUADSize ();
237389 MLOGD (" CustomControlMap" , " Send Device Descriptor" );
238390 vector<uint8_t > payload = {
239391 DEVICE_DESCRIPTOR | HID_RESPONSE, // Response to DEVICE_DESCRIPTOR
@@ -248,10 +400,10 @@ void CustomControlMap::SendDeviceDescriptor() {
248400 Device::x_size, // Device X 8
249401 Device::y_size, // Device Y 8
250402 MAX_UAD_LAYER, // Max Layers
251- (uint8_t )((MAX_UAD_SIZE >> 24 ) & 0xFF ), // UAD Size MSB1
252- (uint8_t )((MAX_UAD_SIZE >> 16 ) & 0xFF ), // UAD Size MSB2
253- (uint8_t )((MAX_UAD_SIZE >> 8 ) & 0xFF ), // UAD Size MSB3
254- (uint8_t )((MAX_UAD_SIZE ) & 0xFF ), // UAD Size MSB4
403+ (uint8_t )((max_uad_size >> 24 ) & 0xFF ), // UAD Size MSB1
404+ (uint8_t )((max_uad_size >> 16 ) & 0xFF ), // UAD Size MSB2
405+ (uint8_t )((max_uad_size >> 8 ) & 0xFF ), // UAD Size MSB3
406+ (uint8_t )((max_uad_size ) & 0xFF ), // UAD Size MSB4
255407 (uint8_t )MAX_HID_TRANSFER_SIZE, // Max HID Transfer Size
256408 };
257409
0 commit comments