47 #define FILESIZE_MAX 100 48 #define MAX_PATH_LEN 64 52 #define TPS_DIRECTORY "tps/" 53 #define MAX_WRITES_IN_PERIOD 64 54 #define WRITE_PERIOD_DAYS 28 59 #define DBG_PRINT(x) DBG_PRINTF x 60 #define DBG_TPS(x) do { DBG_PRINTF("%s: ", __func__); DBG_PRINTF x; } while (0) 72 typedef struct s_TruePersistentFile
83 struct s_TruePersistentFile *next;
84 struct s_TruePersistentFile *previous;
85 } t_TruePersistentFile;
90 static t_TruePersistentFile *file_list_head = NULL;
91 static t_TruePersistentFile *file_list_tail = NULL;
92 static U16BIT file_count = 0;
106 static void TPS_StorageClose(
void);
107 static BOOLEAN TPS_StorageGetEnabled();
109 static void FreeFile(t_TruePersistentFile *file);
110 static void DeleteFile(t_TruePersistentFile *file);
111 static void ClearCache();
112 static BOOLEAN AddFileToList(t_TruePersistentFile *file);
113 static BOOLEAN LoadFile(
char *filename);
114 static t_TruePersistentFile* FindFileByName(
S_STRING filename);
116 static BOOLEAN DeleteOldFile();
119 static MHEG5Bool WriteFileToStore( t_TruePersistentFile *out_file);
123 static t_TruePersistentFile* OverwriteFileEntry(
void *
data,
MHEG5Int len,
125 t_TruePersistentFile *replaced_file);
127 static t_TruePersistentFile* UpdateFileEntry(t_TruePersistentFile *file,
void *
data,
MHEG5Int len,
131 static void Store32Bits(
U8BIT *bytes,
U32BIT value);
133 static void Store16Bits(
U8BIT *bytes,
U16BIT value);
146 current_service = *pDvbLoc;
164 DBG_TPS((
"reading:%.*s\n", (
int)fn.
len, fn.
data));
165 if (filename.
zlen && filename.
zlen < 9)
167 rc = TPS_StorageRead(filename, data, (
U32BIT *)len);
173 DBG_TPS((
"read:\n"));
174 for (i = 0; i < *
len; i++)
176 DBG_PRINT((
"0x%x ", ((
U8BIT *)*data)[i]));
206 DBG_TPS((
"writing:%.*s\n", (
int)fn.
len, fn.
data));
207 DBG_TPS((
"writing:\n"));
208 for (i = 0; i <
len; i++)
210 DBG_PRINT((
"0x%x ", ((
U8BIT *)data)[i]));
216 if (filename.
zlen && filename.
zlen < 9)
218 rc = TPS_StorageWrite(filename, data, len);
237 if (TPS_StorageGetEnabled())
265 static void MHEG5NotifyTpsFilesChanged(
void *dummy)
278 E_MhegErr MHEG5_NotifyNvmFilesChanged(
void)
296 t_TruePersistentFile *file_entry;
304 file_entry = FindFileByName(filename);
307 *
data = file_entry->file_data;
308 *data_len = file_entry->file_len;
327 t_TruePersistentFile *replaced_file;
328 t_TruePersistentFile *updated_file;
342 DBG_TPS((
"current service_id 0x%x\n", current_service.
service_id));
344 replaced_file = FindFileByName(filename);
348 DBG_TPS((
"File exists\n"));
349 if (replaced_file->write_date >= day - WRITE_PERIOD_DAYS)
351 replaced_file->num_writes = 0;
354 if (replaced_file->num_writes >= MAX_WRITES_IN_PERIOD)
357 DBG_TPS((
"Warning: File has been written too many times\n"));
362 else if (ServicesEqual(¤t_service, &replaced_file->service_info))
364 check_service =
FALSE;
368 if (write && check_service)
371 DeleteFileByService(¤t_service);
374 if (write && file_count == MAX_FILES)
376 DBG_TPS((
"Store full, deleting old files\n"));
378 if (file_count == MAX_FILES)
388 updated_file = OverwriteFileEntry(
data, data_len, ¤t_service, day, replaced_file);
392 updated_file = NewFile(filename,
data, data_len, ¤t_service, day);
394 if (WriteFileToStore( updated_file ))
408 static void FreeFile(t_TruePersistentFile *file)
428 static void DeleteFile(t_TruePersistentFile *file)
434 file->next->previous = file->previous;
438 file_list_tail = file->previous;
444 file->previous->next = file->next;
448 file_list_head = file->next;
459 static void ClearCache(
void)
461 t_TruePersistentFile *current;
462 t_TruePersistentFile *next;
464 current = file_list_head;
468 next = current->next;
472 file_list_head = NULL;
473 file_list_tail = NULL;
494 static BOOLEAN AddFileToList(t_TruePersistentFile *file)
496 t_TruePersistentFile *current;
498 if (file_list_tail == NULL)
500 file_list_tail = file;
501 file_list_head = file;
505 current = file_list_tail;
508 if (file->write_date >= current->write_date)
510 file->previous = current;
511 file->next = current->next;
514 current->next->previous = file;
515 current->next = file;
519 file_list_tail = file;
520 current->next = file;
526 current = current->previous;
531 file_list_head->previous = file;
532 file->next = file_list_head;
533 file_list_head = file;
543 static BOOLEAN LoadFile(
char *filename)
546 t_TruePersistentFile *new_file;
555 full_path =
MHEG5getMem(strlen(TPS_DIRECTORY) + strlen(filename) + 1);
557 memcpy(full_path, (
char *)TPS_DIRECTORY, strlen(TPS_DIRECTORY) + 1);
558 strncat(full_path, filename, strlen(filename) + 1);
560 DBG_TPS((
"Loading File %s\n", filename));
562 new_file =
MHEG5getMem(
sizeof(t_TruePersistentFile));
564 new_file->previous = NULL;
565 new_file->next = NULL;
566 new_file->num_writes = 0;
567 new_file->write_date = 0;
568 new_file->file_path = full_path;
569 new_file->filename = (
U8BIT *)full_path + strlen(TPS_DIRECTORY);
570 new_file->filename_len = strlen(filename);
575 if (file_size >= HEADER_SIZE)
587 service_info = &new_file->service_info;
591 service_info->
service_id = Read16Bits(data + offset);
596 new_file->num_writes = *(data + offset);
598 new_file->write_date = Read32Bits(data + offset);
601 new_file->file_len = file_size - offset;
602 new_file->file_data =
MHEG5getMem(new_file->file_len);
603 if (new_file->file_data)
605 memcpy(new_file->file_data, data + offset, new_file->file_len);
606 success = AddFileToList(new_file);
637 static void Store32Bits(
U8BIT *bytes,
U32BIT value)
639 bytes[0] = value & 0xFF;
640 bytes[1] = (value >> 8) & 0xFF;
641 bytes[2] = (value >> 16) & 0xFF;
642 bytes[3] = (value >> 24) & 0xFF;
656 static void Store16Bits(
U8BIT *bytes,
U16BIT value)
658 bytes[0] = value & 0xFF;
659 bytes[1] = (value >> 8) & 0xFF;
672 if (!init && TPS_enabled)
684 if (!LoadFile(filename_buffer))
700 static void TPS_StorageClose(
void)
714 static t_TruePersistentFile* FindFileByName(
S_STRING filename)
716 t_TruePersistentFile *file_entry;
717 file_entry = file_list_tail;
721 if (filename.
zlen == file_entry->filename_len)
723 if (!memcmp(filename.
zptr, file_entry->filename, filename.
zlen))
728 file_entry = file_entry->previous;
739 static BOOLEAN DeleteOldFile(
void)
741 t_TruePersistentFile *current;
744 current = file_list_head;
754 current = current->next;
787 t_TruePersistentFile *file_entry;
789 file_entry = file_list_head;
790 DBG_TPS((
"deleting files on service 0x%x\n", service_info->
service_id));
793 if (ServicesEqual(service_info, &file_entry->service_info))
795 DeleteFile(file_entry);
799 file_entry = file_entry->next;
808 static MHEG5Bool WriteFileToStore( t_TruePersistentFile *out_file)
817 len += out_file->file_len;
822 Store16Bits(file_data + offset, out_file->service_info.original_network_id);
824 Store16Bits(file_data + offset, out_file->service_info.service_id);
826 memcpy(file_data + offset, &out_file->num_writes, 1);
828 Store32Bits(file_data + offset, out_file->write_date);
831 memcpy(file_data + offset, out_file->file_data, out_file->file_len);
862 t_TruePersistentFile *new_file;
866 new_file =
MHEG5getMem(
sizeof(t_TruePersistentFile));
879 strncat(full_path, TPS_DIRECTORY, strlen(TPS_DIRECTORY));
880 strncat(full_path, (
char *)filename.
zptr, filename.
zlen);
882 new_file->file_path = full_path;
883 new_file->filename = (
U8BIT *)full_path + strlen(TPS_DIRECTORY);
884 new_file->filename_len = filename.
zlen;
885 new_file->num_writes = 1;
886 new_file->write_date = today;
888 UpdateFileEntry(new_file,
data,
len, service);
898 static t_TruePersistentFile* OverwriteFileEntry(
void *
data,
MHEG5Int len,
900 t_TruePersistentFile *replaced_file)
904 assert(replaced_file);
907 if (today <= replaced_file->write_date + WRITE_PERIOD_DAYS)
909 if (replaced_file->num_writes == MAX_WRITES_IN_PERIOD)
915 replaced_file->num_writes++;
920 replaced_file->write_date = today;
921 replaced_file->num_writes = 1;
927 if (replaced_file->previous && replaced_file->next)
930 replaced_file->previous->next = replaced_file->next;
931 replaced_file->next->previous = replaced_file->previous;
933 else if (replaced_file->next)
936 replaced_file->next->previous = NULL;
938 else if (replaced_file->previous)
940 replaced_file->previous->next = NULL;
943 if (file_list_head == replaced_file)
945 file_list_head = replaced_file->next;
947 if (file_list_tail == replaced_file)
949 file_list_tail = replaced_file->previous;
954 replaced_file->file_data = NULL;
955 replaced_file->file_len = 0;
956 replaced_file->next = NULL;
957 replaced_file->previous = NULL;
958 return UpdateFileEntry(replaced_file,
data,
len, service);
970 static t_TruePersistentFile* UpdateFileEntry(t_TruePersistentFile *file,
void *
data,
MHEG5Int len,
975 file_list_tail->next = file;
979 file_list_head = file;
983 file->previous = file_list_tail;
985 file_list_tail = file;
989 file->service_info.service_id = service->
service_id;
993 memcpy(file->file_data,
data,
len);
994 file->file_len =
len;
1011 *enabled = (TPS_enabled) ?
TRUE :
FALSE;
1023 if (TPS_enabled && !enabled)
1028 TPS_enabled = enabled;
1040 t_TruePersistentFile *cursor;
1042 if (current_file_list)
1050 if (current_file_list)
1052 for (cursor = file_list_head, file_count = 0; cursor; file_count++, cursor = cursor->next)
1054 current_file_list[file_count].
original_network_id = cursor->service_info.original_network_id;
1055 current_file_list[file_count].
transport_stream_id = cursor->service_info.transport_stream_id;
1056 current_file_list[file_count].
service_id = cursor->service_info.service_id;
1058 *pfile_count = file_count;
1059 *first_file = current_file_list;
1083 if (current_file_list)
1086 current_file_list = NULL;
1099 if (DeleteFileByService(service))
1112 BOOLEAN TPS_StorageGetEnabled(
void)
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.
MHEG5Bool MHEG5TpsWrite(MHEG5String fn, void *data, MHEG5Int len)
Write data passed from the application into the TPS stroe.
F_MSG_PROCESS proc_msg_func
void STB_NVMCloseDirectory(void *dir)
Closes the directory for reading.
MHEG5Bool MHEG5GetTpsStatus(void)
Get the status of the TPS store for the PST resident program. none.
void MHEG5TpsClose(void)
Close the clear the store and delete the cache none.
True Persistent Storage functions.
void MHEG5getDate(S32BIT *day, S32BIT *sec)
Modified Julian Date - see Davic 9.2.12.1.
MHEG5Bool MHEG5TpsRead(MHEG5String fn, void **data, MHEG5Int *len)
Read a file from the TPS store and pass it back to the application.
void STB_NVMCloseFile(void *file)
Flushes and closes an open file.
U16BIT transport_stream_id
S_DvbLocator * pS_DvbLocator
BOOLEAN STB_NVMFileSize(U8BIT *filename, U32BIT *filesize)
Returns the size in KB of the given file.
MHEG5 engine interface error codes.
U16BIT original_network_id
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-...
U32BIT STB_NVMReadFile(void *file, U8BIT *data, U32BIT size)
Reads data from an open file.
void MHEG5TpsSetCurrentService(S_DvbLocator *pDvbLoc)
Set current service for application none.
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.
Non-Volatile Memory functions and file access for caching files during power cycles. All file/path names are relative to some implementation dependent root path for MHEG's NVM storage area. So a path of "" (i.e. zero length name), is the root directory of storage area.
#define USE_UNWANTED_PARAM(param)
E_MhegErr DVB_MhegDvbLocatorToIndex(S_DvbLocator *pDvbLocator, S32BIT *pServiceIndex)
Get a DVB implementation dependant service index - an integer greater or equal to 0...
BOOLEAN STB_NVMDeleteFile(U8BIT *filename)
Deletes the file.