43 #ifdef INCLUDE_FREESAT 46 #ifndef NVM_STORAGE_MAX 47 #define NVM_STORAGE_MAX (256 * 1024) 51 #ifndef NVM_STORAGE_DIRECTORY 52 #define NVM_STORAGE_DIRECTORY "nvm/" 54 #define NVM_STORAGE_DIRECTORY_LEN strlen(NVM_STORAGE_DIRECTORY) 56 #define MAX_PATH_LEN 64 61 typedef struct s_nvm_file
71 struct s_nvm_allocation *allocation;
72 struct s_nvm_file *next;
73 struct s_nvm_file *previous;
76 typedef struct s_nvm_allocation
81 S_NVM_FILE *first_file;
82 struct s_nvm_allocation *next;
83 struct s_nvm_allocation *previous;
89 static S_NVM_ALLOCATION *allocation_list = NULL;
90 static S_NVM_ALLOCATION scratchpad;
95 static MHEG5Bool WriteToFile(S_NVM_FILE *file);
96 static MHEG5Bool CheckFreeSpace(S_NVM_FILE *file);
97 static MHEG5Bool CheckAllocationSize(S_NVM_FILE *file);
99 static void InitStore(
void);
100 static void OpenNvmStore(
void);
102 static MHEG5Bool RemoveFileFromCache(S_NVM_FILE *file_entry);
103 static MHEG5Bool DeleteFile(S_NVM_FILE *file_entry);
104 static MHEG5Bool MoveFileToScratch(S_NVM_FILE *file);
108 static void CalculateFileScore(S_NVM_FILE *file);
109 static S_NVM_ALLOCATION* GetAllocationFromId(
U16BIT allocation_id);
110 static void CheckUpdatedAllocation(S_NVM_ALLOCATION *allocation);
111 static void CacheFile(
char *file_name);
112 static void UpdateHeader( S_NVM_FILE *file);
113 static void ParseFileHeader(
U8BIT *header_data, S_NVM_FILE *file);
115 static void ClearFileDataCache(
void);
145 allocation_id = ConvertPathToId(fn);
147 new_filename = CreateStorageFilename(fn, allocation_id);
150 file = FindFile(*new_filename, allocation_id);
153 *priority = file->priority;
154 *expires = file->expires;
155 success = ReadFromFile(data, len, file);
192 allocation_id = ConvertPathToId(fn);
193 if (allocation_id == 0xffff)
199 new_filename = CreateStorageFilename(fn, allocation_id);
204 file = CreateFile(data, len, new_filename, allocation_id, file_priority);
207 file->expires = expires;
208 file->last_accessed = today;
209 if (CheckAllocationSize(file))
211 if (CheckFreeSpace(file))
213 success = WriteToFile(file);
218 RemoveFileFromCache(file);
224 file = FindFile(*new_filename, allocation_id);
227 success = DeleteFile(file);
232 ClearFileDataCache();
242 static MHEG5Bool WriteToFile(S_NVM_FILE *file)
257 bytes_written =
STB_NVMWriteFile(nvm_file, file->data, HEADER_SIZE + file->data_len);
262 if (bytes_written == HEADER_SIZE + file->data_len)
281 U16BIT current_identifier;
286 if (DVB_MhegGetCurrentFSI(¤t_identifier) ==
MHERR_OK)
288 return current_identifier;
293 current_identifier = 0;
295 for (i = 0; i < 4; i++)
297 if (fn.
data[i] >=
'a' && fn.
data[i] <=
'f')
299 current_identifier += (fn.
data[i] + 0xa -
'a') << shift;
301 else if (fn.
data[i] >=
'0' && fn.
data[i] <=
'9')
303 current_identifier += (fn.
data[i] -
'0') << shift;
312 if (current_identifier > 0x8000)
318 DVB_MhegCurrentServiceIsInGroup(current_identifier, &ok);
322 current_identifier |= 0x8000;
326 current_identifier = 0xffff;
330 return current_identifier;
338 static MHEG5Bool CheckFreeSpace(S_NVM_FILE *file)
340 S_NVM_FILE *file_cursor;
341 S_NVM_FILE *lowest_scored_file = NULL;
344 while (total_stored > NVM_STORAGE_MAX && scratchpad.first_file)
346 file_cursor = scratchpad.first_file;
349 if (file_cursor == file)
351 file_cursor = file_cursor->next;
355 CalculateFileScore(file_cursor);
356 if (!lowest_scored_file)
358 lowest_scored_file = file_cursor;
360 else if (lowest_scored_file->score > file_cursor->score)
362 lowest_scored_file = file_cursor;
365 file_cursor = file_cursor->next;
368 if (lowest_scored_file)
370 DeleteFile(lowest_scored_file);
373 if (total_stored <= NVM_STORAGE_MAX)
388 static MHEG5Bool CheckAllocationSize(S_NVM_FILE *file)
390 S_NVM_ALLOCATION *allocation;
391 S_NVM_FILE *file_cursor;
392 S_NVM_FILE *next_file;
397 allocation = file->allocation;
400 CalculateFileScore(file);
401 if (file->allocation == &scratchpad)
403 return MoveFileToScratch(file);
407 if (allocation->size >= allocation->used)
412 else if (file->data_len <= allocation->size)
415 file_cursor = allocation->first_file;
416 while (file_cursor && allocation->size < allocation->used)
418 CalculateFileScore(file_cursor);
419 next_file = file_cursor->next;
420 if (file_cursor != file && !file_cursor->score)
422 DeleteFile(file_cursor);
424 file_cursor = next_file;
427 file_cursor = allocation->first_file;
428 while (file_cursor && allocation->size < allocation->used)
430 next_file = file_cursor->next;
431 if (file_cursor != file && file_cursor->score < file->score)
433 MoveFileToScratch(file_cursor);
435 file_cursor = next_file;
438 if (allocation->size < allocation->used)
441 CalculateFileScore(file);
442 return MoveFileToScratch(file);
448 RemoveFileFromCache(file);
468 for (name_start = 0; name_start < fn.
len; name_start++)
470 if (fn.
data[name_start] ==
'/')
477 if (fn.
len > name_start && fn.
len <= name_start + 7)
483 new_fn->
len = fn.
len + 5 - name_start;
484 new_fn->
len += NVM_STORAGE_DIRECTORY_LEN;
494 memcpy(new_fn->
data, NVM_STORAGE_DIRECTORY, NVM_STORAGE_DIRECTORY_LEN);
496 for (i = NVM_STORAGE_DIRECTORY_LEN; i != NVM_STORAGE_DIRECTORY_LEN + 4; i++)
498 new_fn->
data[i] = (allocation_id >> shift) & 0xf;
499 if (new_fn->
data[i] > 9)
501 new_fn->
data[i] +=
'a' - 0xa;
505 new_fn->
data[i] +=
'0';
509 new_fn->
data[i++] =
'_';
510 memcpy( &new_fn->
data[i], &fn.
data[name_start], fn.
len - name_start);
511 new_fn->
data[new_fn->
len] =
'\0';
523 static void InitStore(
void)
527 assert(!allocation_list);
529 scratchpad.id = 0xffff;
530 scratchpad.size = NVM_STORAGE_MAX;
532 scratchpad.first_file = NULL;
533 scratchpad.next = NULL;
534 scratchpad.previous = NULL;
544 static void OpenNvmStore(
void)
547 void *directory_handle;
557 if (directory_handle)
560 memcpy(file_name, NVM_STORAGE_DIRECTORY, NVM_STORAGE_DIRECTORY_LEN);
562 (
U8BIT *)file_name + NVM_STORAGE_DIRECTORY_LEN,
MAX_PATH_LEN - NVM_STORAGE_DIRECTORY_LEN, &file_type))
566 CacheFile(file_name);
568 memcpy(file_name, NVM_STORAGE_DIRECTORY, NVM_STORAGE_DIRECTORY_LEN);
583 S_NVM_ALLOCATION *allocation;
584 S_NVM_ALLOCATION *next_allocation;
586 S_NVM_FILE *next_file;
591 allocation = allocation_list;
594 next_allocation = allocation->next;
595 file = allocation->first_file;
598 next_file = file->next;
600 RemoveFileFromCache(file);
605 allocation = next_allocation;
607 file = scratchpad.first_file;
610 next_file = file->next;
612 RemoveFileFromCache(file);
616 scratchpad.first_file = NULL;
617 allocation_list = NULL;
628 S_NVM_ALLOCATION *allocation;
629 S_NVM_FILE *file_cursor = NULL;
633 allocation = GetAllocationFromId(allocation_id);
638 file_cursor = allocation->first_file;
641 file_cursor = file_cursor->next;
647 allocation = &scratchpad;
648 file_cursor = scratchpad.first_file;
651 file_cursor = file_cursor->next;
664 static MHEG5Bool RemoveFileFromCache(S_NVM_FILE *file_entry)
666 file_entry->allocation->used -= file_entry->data_len;
667 total_stored -= file_entry->data_len;
668 if (file_entry->data)
674 if (!file_entry->previous)
676 file_entry->allocation->first_file = file_entry->next;
680 file_entry->previous->next = file_entry->next;
682 if (file_entry->next)
684 file_entry->next->previous = file_entry->previous;
696 static MHEG5Bool DeleteFile(S_NVM_FILE *file_entry)
704 success = RemoveFileFromCache(file_entry);
719 static MHEG5Bool MoveFileToScratch(S_NVM_FILE *file)
721 S_NVM_ALLOCATION *allocation;
722 S_NVM_FILE *file_cursor;
723 S_NVM_FILE *lowest_file;
725 void *temp_file = NULL;
730 allocation = file->allocation;
735 if (allocation != &scratchpad)
744 file->data =
MHEG5getMem(file->data_len + HEADER_SIZE);
751 bytes_read =
STB_NVMReadFile( temp_file, file->data, file->data_len + HEADER_SIZE);
754 if (file->data && bytes_read != file->data_len + HEADER_SIZE)
770 file->previous->next = file->next;
774 allocation->first_file = file->next;
778 file->next->previous = file->previous;
780 allocation->used -= file->data_len;
781 total_stored -= file->data_len;
782 file->allocation = &scratchpad;
783 file->previous = NULL;
784 file->next = scratchpad.first_file;
785 if (scratchpad.first_file)
787 scratchpad.first_file->previous = file;
789 scratchpad.first_file = file;
790 scratchpad.used += file->data_len;
791 total_stored += file->data_len;
795 while (scratchpad.size < scratchpad.used)
798 file_cursor = scratchpad.first_file;
803 if (file_cursor->stored && file_cursor->score < lowest_score)
805 lowest_score = file_cursor->score;
806 lowest_file = file_cursor;
808 file_cursor = file_cursor->next;
812 DeleteFile(lowest_file);
816 RemoveFileFromCache(file);
839 S_NVM_FILE *file_entry = NULL;
840 S_NVM_ALLOCATION *allocation;
841 S_NVM_ALLOCATION *old_allocation;
843 allocation = GetAllocationFromId(allocation_id);
844 if (!allocation || allocation->size < len + HEADER_SIZE)
849 file_entry = FindFile(*filename, allocation_id);
854 allocation = &scratchpad;
863 if (file_entry->data)
865 memcpy((
U8BIT *)file_entry->data + HEADER_SIZE, data, len);
867 file_entry->fn.data = filename->
data;
868 file_entry->fn.len = filename->
len;
869 file_entry->allocation = allocation;
870 file_entry->data_len =
len;
871 file_entry->priority = priority;
872 file_entry->previous = NULL;
874 if (allocation->first_file)
876 allocation->first_file->previous = file_entry;
878 file_entry->next = allocation->first_file;
880 allocation->first_file = file_entry;
881 allocation->used +=
len;
888 if (!file_entry->priority)
890 old_allocation = &scratchpad;
894 old_allocation = allocation;
896 old_allocation->used -= file_entry->data_len;
897 total_stored -= file_entry->data_len;
898 file_entry->data_len =
len;
899 file_entry->priority = priority;
904 allocation = &scratchpad;
907 if (old_allocation != allocation)
909 if (file_entry->next)
911 file_entry->next->previous = file_entry->previous;
914 if (file_entry->previous)
916 file_entry->previous->next = file_entry->next;
918 if (old_allocation->first_file == file_entry)
920 old_allocation->first_file = file_entry->next;
923 file_entry->previous = NULL;
924 file_entry->next = allocation->first_file;
925 allocation->first_file = file_entry;
926 file_entry->allocation = allocation;
928 allocation->used +=
len;
931 if (file_entry->data)
933 memcpy((
U8BIT *)file_entry->data + HEADER_SIZE, data, len);
951 *len = file->data_len;
952 *data = (
U8BIT *)file->data + HEADER_SIZE;
957 file->data =
MHEG5getMem(file->data_len + HEADER_SIZE);
962 *len = file->data_len;
963 *data = (
U8BIT *)file->data + HEADER_SIZE;
976 static void CalculateFileScore(S_NVM_FILE *file)
981 if (file->expires <= today)
987 file->score = file->priority * 30;
988 file->score += file->last_accessed;
996 static void NotifyUpdateServiceAllocation(
U16BIT identifier,
BOOLEAN groupNotService,
999 S_NVM_ALLOCATION *allocation;
1011 for (i = 0; i < blockSize; i++)
1017 allocation_id = identifier;
1018 if (groupNotService)
1020 allocation_id |= 0x8000;
1022 allocation = GetAllocationFromId(allocation_id);
1025 allocation->size = size;
1029 if (size <= NVM_STORAGE_MAX)
1031 allocation =
MHEG5getMem(
sizeof(S_NVM_ALLOCATION));
1036 allocation->size = size;
1037 allocation->used = 0;
1038 allocation->id = allocation_id;
1039 allocation->first_file = NULL;
1040 allocation->next = allocation_list;
1041 allocation->previous = NULL;
1042 allocation_list = allocation;
1052 CheckUpdatedAllocation(allocation);
1082 event_msg.
data.fsStorage.blockSize = blockSize;
1083 event_msg.
data.fsStorage.blocks = blocks;
1084 event_msg.
data.fsStorage.group = groupNotService;
1085 event_msg.
data.fsStorage.identifier = identifier;
1095 static void CheckUpdatedAllocation(S_NVM_ALLOCATION *allocation)
1097 S_NVM_FILE *file_cursor;
1098 S_NVM_FILE *lowest_file;
1101 file_cursor = allocation->first_file;
1104 if (file_cursor->data_len > allocation->size)
1106 S_NVM_FILE *temp_next = file_cursor->next;
1107 DeleteFile(file_cursor);
1108 file_cursor = temp_next;
1112 file_cursor = file_cursor->next;
1117 while (allocation->used > allocation->size)
1120 file_cursor = allocation->first_file;
1124 if (!lowest_file || file_cursor->score < lowest_file->score)
1126 lowest_file = file_cursor;
1128 file_cursor = file_cursor->next;
1132 MoveFileToScratch(lowest_file);
1143 if (scratchpad.used > scratchpad.size)
1146 MoveFileToScratch(scratchpad.first_file);
1156 static S_NVM_ALLOCATION* GetAllocationFromId(
U16BIT allocation_id)
1158 S_NVM_ALLOCATION *allocation;
1160 allocation = allocation_list;
1161 while (allocation && allocation->id != allocation_id)
1163 allocation = allocation->next;
1173 static void CacheFile(
char *file_name)
1175 void *nvm_file = NULL;
1177 U8BIT *header_data = NULL;
1178 S_NVM_ALLOCATION *allocation;
1179 S_NVM_FILE *new_file = NULL;
1190 new_file->fn.data =
MHEG5getMem(strlen(file_name) + 1);
1191 if (new_file->fn.data)
1193 new_file->fn.len = strlen(file_name);
1194 memcpy(new_file->fn.data, file_name, new_file->fn.len + 1);
1208 if (bytes_read == HEADER_SIZE)
1211 ParseFileHeader(header_data, new_file);
1213 new_file->data = NULL;
1215 new_file->previous = NULL;
1216 allocation_id = FilenameToId(new_file->fn);
1219 allocation = GetAllocationFromId(allocation_id);
1222 allocation = &scratchpad;
1223 new_file->priority = 0;
1226 new_file->next = allocation->first_file;
1227 allocation->first_file = new_file;
1230 new_file->next->previous = new_file;
1232 new_file->allocation = allocation;
1233 allocation->used += new_file->data_len;
1234 total_stored += new_file->data_len;
1236 CalculateFileScore(new_file);
1250 static void UpdateHeader( S_NVM_FILE *file)
1254 header_data = file->data;
1257 header_data[0] = (file->expires) & 0xff;
1258 header_data[1] = (file->expires >> 8) & 0xff;
1259 header_data[2] = (file->expires >> 16) & 0x01;
1260 header_data[2] |= (file->last_accessed << 1) & 0xfe;
1261 header_data[3] = (file->last_accessed >> 7) & 0xff;
1262 header_data[4] = (file->last_accessed >> 15) & 0x3;
1263 header_data[4] |= (file->priority << 2) & 0xc;
1264 header_data[5] = (file->data_len) & 0xff;
1265 header_data[6] = (file->data_len >> 8) & 0xff;
1275 static void ParseFileHeader(
U8BIT *header_data, S_NVM_FILE *file)
1280 buffer = header_data[0];
1281 buffer |= header_data[1] << 8;
1282 buffer |= (header_data[2] << 16) & 0x10000;
1283 file->expires = buffer;
1285 buffer = header_data[2] >> 1;
1286 buffer |= (header_data[3] << 7) & 0x7f00;
1287 buffer |= (header_data[4] << 15) & 0x18000;
1288 file->last_accessed = buffer;
1290 buffer = (header_data[4] >> 2) & 0x3;
1291 file->priority = buffer;
1293 buffer = header_data[5];
1294 buffer |= (header_data[6] << 8) & 0xff00;
1295 file->data_len = buffer;
1312 for (i = 0; i < 4; i++)
1313 if ((
string.data[i] >=
'0') && (
string.data[i] <=
'9'))
1314 rc = rc * 16 + ((int)
string.data[i] - (
int)
'0');
1315 else if ((
string.data[i] >=
'a') && (
string.data[i] <=
'z'))
1316 rc = rc * 16 + ((int)
string.data[i] - (
int)
'a') + 10;
1317 else if ((
string.data[i] >=
'A') && (
string.data[i] <=
'Z'))
1318 rc = rc * 16 + ((int)
string.data[i] - (
int)
'A') + 10;
1329 static void ClearFileDataCache(
void)
1331 S_NVM_ALLOCATION *allocation_cursor;
1332 S_NVM_FILE *file_cursor;
1334 allocation_cursor = allocation_list;
1336 while (allocation_cursor)
1338 file_cursor = allocation_cursor->first_file;
1341 if (file_cursor->data && file_cursor->stored)
1344 file_cursor->data = NULL;
1346 file_cursor = file_cursor->next;
1348 allocation_cursor = allocation_cursor->next;
1351 if (scratchpad.first_file)
1353 file_cursor = scratchpad.first_file;
1356 if (file_cursor->data && file_cursor->stored)
1359 file_cursor->data = NULL;
1361 file_cursor = file_cursor->next;
void * STB_NVMOpenFile(U8BIT *name, E_STB_DSK_FILE_MODE mode)
Opens an existing file or creates a new one.
E_MhegErr VQ_PutMsg(S_MhegMessage *pMsg, E_PRIORITY priority)
Post event or section message on queue. Copies data into queue.
F_MSG_PROCESS proc_msg_func
MHEG5Bool MHEG5stringEqual(MHEG5String *s1, MHEG5String *s2)
Compare two Strings (case sensitive!)
void MHEG5getDate(S32BIT *day, S32BIT *sec)
Modified Julian Date - see Davic 9.2.12.1.
MHEG5Bool MHEG5FSnvmWrite(MHEG5String fn, void *data, MHEG5Int len, MHEG5Int expires, MHEG5Int priority)
void STB_NVMCloseFile(void *file)
Flushes and closes an open file.
MHEG5 engine interface error codes.
void(* F_MSG_PROCESS)(void *data)
Function to Process voyager message.
void * STB_NVMOpenDirectory(U8BIT *dir_name)
Opens a directory in order to read the entries.
DVB Service information functions are required by MHEG5 engine. All required functions should be non-...
void MHEG5FSnvmStoreClose(void)
void MHEG5FSnvmStoreOpen(void)
U32BIT STB_NVMReadFile(void *file, U8BIT *data, U32BIT size)
Reads data from an open file.
#define MHEG5strncmp(a, b, n)
System Wide Global Technical Data Type Definitions.
BOOLEAN STB_NVMReadDirectory(void *dir, U8BIT *filename, U16BIT filename_len, E_STB_DIR_ENTRY_TYPE *entry_type)
Reads the next entry from the directory, returning the name of the entry and the type of the entry...
U32BIT STB_NVMWriteFile(void *file, U8BIT *data, U32BIT size)
Writes data to an open file.
MHEG5Bool MHEG5FSnvmRead(MHEG5String fn, void **data, MHEG5Int *len, MHEG5Int *expires, MHEG5Int *priority)
union s_mhg_message::@13 data
BOOLEAN STB_NVMDeleteFile(U8BIT *filename)
Deletes the file.