/* * FileSystem.c * * Created on: Oct 23, 2018 * Author: shlomo */ #include "include.h" #include "Communication/CommunicationTask.h" #include "Communication/connection.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "drivers/Flash_Memory/fatfs/ff.h" #include "drivers/FPGA/FPGA_GPIO/FPGA_GPIO.h" #include "Modules/Control/Control.h" #include "StateMachines/Printing/PrintingSTM.h" ErrorCode FileError_to_ErrorCode[FR_INVALID_PARAMETER+1] = {ERROR_CODE__NONE,ERROR_CODE__FILE_REQUEST_DISK_ERR,ERROR_CODE__FILE_REQUEST_INT_ERR,ERROR_CODE__FILE_REQUEST_NOT_READY,ERROR_CODE__FILE_REQUEST_NO_FILE, ERROR_CODE__FILE_REQUEST_NO_PATH,ERROR_CODE__FILE_REQUEST_INVALID_NAME,ERROR_CODE__FILE_REQUEST_DENIED,ERROR_CODE__FILE_REQUEST_EXIST,ERROR_CODE__FILE_REQUEST_INVALID_OBJECT, ERROR_CODE__FILE_REQUEST_WRITE_PROTECTED,ERROR_CODE__FILE_REQUEST_INVALID_DRIVE,ERROR_CODE__FILE_REQUEST_NOT_ENABLED,ERROR_CODE__FILE_REQUEST_NO_FILESYSTEM, ERROR_CODE__FILE_REQUEST_MKFS_ABORTED,ERROR_CODE__FILE_REQUEST_TIMEOUT,ERROR_CODE__FILE_REQUEST_LOCKED,ERROR_CODE__FILE_REQUEST_NOT_ENOUGH_CORE,ERROR_CODE__FILE_REQUEST_TOO_MANY_OPEN_FILES, ERROR_CODE__FILE_REQUEST_INVALID_PARAMETER}; FIL *UploadFileHandle = 0; //the system supports a single active file FIL *DownloadFileHandle = 0; //the system supports a single active file char FileHandleChar[5]; char ErrorMsg[100]; #define MAX_CHUNK_LENGTH 5500 int32_t FileLength = 0; int32_t FileReceivedLength = 0; int32_t FileSentLength = 0; static char g_cCwdBuf[50] = "/"; uint32_t WrittenBytes = 0; uint32_t ReadBytes = 0; Task_Handle CommRxTaskHandle; extern Semaphore_Handle FFS_Sem; extern Semaphore_Handle FileUpload_sem_param; ErrorCode getErrorCode(FRESULT Fresult) { return FileError_to_ErrorCode[Fresult]; } bool isDirectory(FileAttribute FileAtt) { if (FileAtt&&FILE_ATTRIBUTE__Directory) return true; return false; } bool FileDone = true; bool FileUploadGetState(void) { return FileDone; } int CommRxpri; uint32_t FileUploadRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; FRESULT Fresult = FR_OK; bool sem_ok = false; MessageContainer responseContainer; FileUploadRequest* request = file_upload_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); FileUploadResponse response = FILE_UPLOAD_RESPONSE__INIT; WrittenBytes=0; if (JobIsActive()) { Fresult = FR_DENIED; Report("file uplad rejected - job is running", __FILE__, __LINE__, 4, RpWarning, (int)0, 0); } else { UploadFileHandle = my_malloc(sizeof(FIL)); if (UploadFileHandle == 0) Fresult = FR_DENIED; else { if (1)//(Semaphore_pend(FileUpload_sem_param, BIOS_NO_WAIT)) { sem_ok = true; } else { Semaphore_post(FileUpload_sem_param); Report("semaphore was not free", __FILE__, __LINE__, request->length, RpWarning, (int)MAX_CHUNK_LENGTH, 0); sem_ok = true; } if (sem_ok == true) { CommRxTaskHandle = Task_self(); CommRxpri = Task_getPri(CommRxTaskHandle); Task_setPri(CommRxTaskHandle, 11); Report("Task_setPri", __FILE__, __LINE__, 4, RpWarning, (int)CommRxTaskHandle, 0); //Report("FileUploadRequestFunc 2", __FILE__, __LINE__, msec_millisecondCounter, RpWarning, (int)0, 0); Fresult = f_open(UploadFileHandle,request->path,FA_READ | FA_WRITE | FA_OPEN_ALWAYS | FA_CREATE_ALWAYS); if (Fresult == FR_OK) { usnprintf(ErrorMsg, 100, "file upload request %s %d",request->path,request->length); Report(ErrorMsg, __FILE__, __LINE__, request->length, RpWarning, (int)MAX_CHUNK_LENGTH, 0); FileLength = request->length; FileReceivedLength = 0; response.has_maxchunklength = true; response.maxchunklength = MAX_CHUNK_LENGTH; strcpy(FileHandleChar, "1234"); response.uploadid = FileHandleChar; //supporting only single file at each time. FileDone = false; } else { my_free (UploadFileHandle); UploadFileHandle = 0; Semaphore_post(FileUpload_sem_param); } } else { Fresult = FR_DENIED; Report("Semaphore_pend failed", __FILE__, __LINE__, 4, RpWarning, (int)0, 0); } } } responseContainer = createContainer(MESSAGE_TYPE__FileUploadResponse, requestContainer->token, true, &response, &file_upload_response__pack, &file_upload_response__get_packed_size); if (Fresult!= FR_OK) { responseContainer.has_error = true; responseContainer.error = getErrorCode(Fresult); responseContainer.errormessage = "File operation upload request error"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); file_upload_request__free_unpacked(request,NULL); SendChars(container_buffer, container_size); return OK; } FRESULT lFresult = FR_OK; uint32_t Chunk_ControlId = 0xFF; uint32_t FileChunkUploadCallBackFunction(uint32_t IfIndex, uint32_t BusyFlag) { Report("chunk timeout error",__FILE__,IfIndex,FileReceivedLength,RpWarning,BusyFlag,0); f_close(UploadFileHandle); my_free (UploadFileHandle); UploadFileHandle = 0; FileReceivedLength = 0; FileDone = true; Task_setPri(CommRxTaskHandle, CommRxpri); Semaphore_post(FileUpload_sem_param); Report("Task_setPri", __FILE__, __LINE__, CommRxpri, RpWarning, (int)CommRxTaskHandle, 0); if (SafeRemoveControlCallback(Chunk_ControlId, FileChunkUploadCallBackFunction )==OK) Chunk_ControlId = 0xFF; return OK; } uint32_t FileChunkUploadRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; FRESULT Fresult = FR_OK; MessageContainer responseContainer; FileChunkUploadRequest* request = file_chunk_upload_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); FileChunkUploadResponse response = FILE_CHUNK_UPLOAD_RESPONSE__INIT; FIL *ReceivedFileHandle; //the system supports a single active file uint32_t save_milisec = 0; // if (request->uploadid == 1) ReceivedFileHandle = UploadFileHandle; // memcpy (&ReceivedFileHandle,request->uploadid,sizeof(ReceivedFileHandle)); //if (ReceivedFileHandle == FileHandle) //{ //Control_WD(ENABLE,55); //activate heaters/dispenser watchdog, 0.5 seconds //GeneralHwReady = false; if (ReceivedFileHandle==NULL) { Fresult = FR_DENIED; Report("file chunk upload rejected - file not created", __FILE__, __LINE__, 4, RpWarning, (int)0, 0); FileDone = true; } else { KeepAliveOneSecondCounter = 0; save_milisec = msec_millisecondCounter; Chunk_ControlId = AddControlCallback("chunk", FileChunkUploadCallBackFunction, eOneSecond, TemplateDataReadCBFunction,0,request->buffer.len, WrittenBytes ); Fresult = f_write(ReceivedFileHandle,request->buffer.data,request->buffer.len,&WrittenBytes ); lFresult = Fresult; if(Fresult != FR_OK) { Report("f_write error",__FILE__,Fresult,FileReceivedLength,RpWarning,request->buffer.len,0); FileDone = true; } else { FileReceivedLength += WrittenBytes; ReportWithPackageFilter(CommFilter,"Chunk received", __FILE__,FileLength,FileReceivedLength, RpMessage,msec_millisecondCounter-save_milisec, 0); RemoveControlCallback(Chunk_ControlId, FileChunkUploadCallBackFunction ); Chunk_ControlId = 0xFF; //REPORT_MSG (FileReceivedLength,"file upload chunk"); if (FileReceivedLength == FileLength) { REPORT_MSG (FileReceivedLength,"file upload ended successfully"); f_close(ReceivedFileHandle); my_free (UploadFileHandle); UploadFileHandle = 0; FileReceivedLength = 0; FileDone = true; } else { if (FileReceivedLength > FileLength) { REPORT_MSG (FileReceivedLength,"file upload too much data!"); f_close(ReceivedFileHandle); my_free (UploadFileHandle); UploadFileHandle = 0; FileReceivedLength = 0; FileDone = true; } } } } responseContainer = createContainer(MESSAGE_TYPE__FileChunkUploadResponse, requestContainer->token, FileDone, &response, &file_chunk_upload_response__pack, &file_chunk_upload_response__get_packed_size); if (Fresult!= OK) { responseContainer.has_error = true; responseContainer.error = getErrorCode(Fresult); responseContainer.errormessage = "File operation chunk upload error"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); //my_free(request->buffer.data); file_chunk_upload_request__free_unpacked(request,NULL); my_free(responseContainer.data.data); SendCharsWithType(container_buffer, container_size,MESSAGE_TYPE__FileChunkUploadResponse); if (FileDone == true) { Task_setPri(CommRxTaskHandle, CommRxpri); Semaphore_post(FileUpload_sem_param); Report("Task_setPri", __FILE__, __LINE__, CommRxpri, RpWarning, (int)CommRxTaskHandle, 0); } return OK; } void FileChunkUploadError(void) { if (FileDone == false) { REPORT_MSG (FileReceivedLength,"file upload too much data!"); f_close(UploadFileHandle); //my_free (UploadFileHandle); CAN NOT CALL FREE() FROM INTERRUPT UploadFileHandle = 0; FileReceivedLength = 0; FileDone = true; Task_setPri(CommRxTaskHandle, CommRxpri); Semaphore_post(FileUpload_sem_param); } } uint32_t FileDownloadRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; FRESULT Fresult = FR_OK; FILINFO* fno; MessageContainer responseContainer; FileDownloadRequest* request = file_download_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); FileDownloadResponse response = FILE_DOWNLOAD_RESPONSE__INIT; ReadBytes=0; FileSentLength = 0; fno = my_malloc(sizeof(FILINFO)); if (fno == 0) Fresult = FR_DENIED; else { memset (fno,0,sizeof(FILINFO)); Fresult = f_stat(request->filename,fno); FileLength = fno->fsize; DownloadFileHandle = my_malloc(sizeof(FIL)); if (DownloadFileHandle == 0) Fresult = FR_DENIED; else { if (1)//(Semaphore_pend(FFS_Sem, BIOS_NO_WAIT)) { Fresult = f_open(DownloadFileHandle,request->filename,FA_READ ); if (Fresult == FR_OK) { response.has_maxchunklength = true; response.maxchunklength = MAX_CHUNK_LENGTH; strcpy(FileHandleChar, "1234"); response.downloadid = FileHandleChar; //supporting only single file at each time. Report("data request", __FILE__, 1234, MAX_CHUNK_LENGTH, RpWarning, (int)fno->fsize, 0); } else { Semaphore_post(FFS_Sem); } } else { Fresult = FR_DENIED; Report("Semaphore_pend failed", __FILE__, __LINE__, 4, RpWarning, (int)0, 0); } } } responseContainer = createContainer(MESSAGE_TYPE__FileDownloadResponse, requestContainer->token, false, &response, &file_download_response__pack, &file_download_response__get_packed_size); if (Fresult!= FR_OK) { responseContainer.has_error = true; responseContainer.error = getErrorCode(Fresult); responseContainer.errormessage = "File operation download request error"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); file_download_request__free_unpacked(request,NULL); SendChars(container_buffer, container_size); my_free(fno); return OK; } uint32_t FileChunkDownloadRequestFunc(MessageContainer* requestContainer) { MessageContainer responseContainer; FileChunkDownloadRequest* request = file_chunk_download_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); FileChunkDownloadResponse response = FILE_CHUNK_DOWNLOAD_RESPONSE__INIT; FRESULT Fresult = FR_OK; FIL *SentFileHandle; //the system supports a single active file SentFileHandle = DownloadFileHandle; uint8_t *Buffer = 0; Buffer = my_malloc (MAX_CHUNK_LENGTH); if (Buffer != NULL) { Fresult = f_read(SentFileHandle,Buffer,MAX_CHUNK_LENGTH,&ReadBytes ); if(Fresult != FR_OK) { LOG_ERROR (Fresult,"f_read error"); Semaphore_post(FFS_Sem); } else { response.has_buffer = true; response.buffer.len = ReadBytes; response.buffer.data = Buffer; FileSentLength += ReadBytes; Report("sending data to MS", __FILE__, ReadBytes, FileSentLength, RpWarning, (int)FileLength, 0); if (FileSentLength == FileLength) { REPORT_MSG (FileSentLength,"file download ended successfully"); f_close(SentFileHandle); Semaphore_post(FFS_Sem); my_free (DownloadFileHandle); FileSentLength = 0; } else { if (FileSentLength > FileLength) { REPORT_MSG (FileSentLength,"file download too much data!"); f_close(SentFileHandle); Semaphore_post(FFS_Sem); my_free (DownloadFileHandle); FileSentLength = 0; } } } } responseContainer = createContainer(MESSAGE_TYPE__FileChunkDownloadResponse, requestContainer->token, false, &response, &file_chunk_download_response__pack, &file_chunk_download_response__get_packed_size); if (Fresult!= OK) { responseContainer.has_error = true; responseContainer.error = getErrorCode(Fresult); responseContainer.errormessage = "File operation chunk download error"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); file_chunk_download_request__free_unpacked(request,NULL); my_free(responseContainer.data.data); my_free(Buffer); SendChars(container_buffer, container_size); return OK; } uint32_t ExecuteProcessRequestFunc(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; ExecuteProcessRequest* request = execute_process_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); ExecuteProcessResponse response = EXECUTE_PROCESS_RESPONSE__INIT; responseContainer = createContainer(MESSAGE_TYPE__ExecuteProcessResponse, requestContainer->token, false, &response, &execute_process_response__pack, &execute_process_response__get_packed_size); if (status!= OK) { responseContainer.has_error = true; responseContainer.error = ERROR_CODE__GENERAL_ERROR;//getErrorCode(Fresult); responseContainer.errormessage = "File operation execute error"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); execute_process_request__free_unpacked(request,NULL); my_free(responseContainer.data.data); SendChars(container_buffer, container_size); return OK; } uint32_t KillProcessRequestFunc(MessageContainer* requestContainer) { uint32_t status = OK; MessageContainer responseContainer; KillProcessRequest* request = kill_process_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); KillProcessResponse response = KILL_PROCESS_RESPONSE__INIT; responseContainer = createContainer(MESSAGE_TYPE__KillProcessResponse, requestContainer->token, false, &response, &kill_process_response__pack, &kill_process_response__get_packed_size); if (status!= OK) { responseContainer.has_error = true; responseContainer.error = ERROR_CODE__GENERAL_ERROR;//getErrorCode(Fresult); responseContainer.errormessage = "File operation kill error"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); kill_process_request__free_unpacked(request,NULL); SendChars(container_buffer, container_size); return OK; } uint32_t CreateRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; FRESULT Fresult = FR_OK; MessageContainer responseContainer; CreateRequest* request = create_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); CreateResponse response = CREATE_RESPONSE__INIT; if (isDirectory(request->attribute)) { Fresult = f_mkdir(request->path); if (Fresult == FR_EXIST) Fresult = FR_OK; //ingnore f_exist in directory create } else { UploadFileHandle = my_malloc(sizeof(FIL)); if (UploadFileHandle == 0) Fresult = FR_DENIED; else { if (1)//(Semaphore_pend(FFS_Sem, BIOS_NO_WAIT)) { Fresult = f_open(UploadFileHandle,request->path,FA_READ | FA_WRITE | FA_OPEN_ALWAYS | FA_CREATE_ALWAYS); if (Fresult == FR_OK) { if (f_close (UploadFileHandle)!= FR_OK) { Fresult = FR_LOCKED; } } Semaphore_post(FFS_Sem); } else { Fresult = FR_DENIED; Report("Semaphore_pend failed", __FILE__, __LINE__, 4, RpWarning, (int)0, 0); } } } if (Fresult != FR_OK) { //status = ERROR_CODE__FILE_NOT_FOUND; //usnprintf(ErrorMsg, 100, "File Operation failed error code %d",Fresult); Report("File Operation failed error code", __FILE__, __LINE__, Fresult, RpWarning, (int)0, 0); } free (UploadFileHandle); responseContainer = createContainer(MESSAGE_TYPE__CreateResponse, requestContainer->token, false, &response, &create_response__pack, &create_response__get_packed_size); if (Fresult!= OK) { responseContainer.has_error = true; responseContainer.error = getErrorCode(Fresult); responseContainer.errormessage = "File operation create error"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); create_request__free_unpacked(request,NULL); SendChars(container_buffer, container_size); return OK; } uint32_t DeleteRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; MessageContainer responseContainer; DeleteRequest* request = delete_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); DeleteResponse response = DELETE_RESPONSE__INIT; FILINFO* fno = 0; //int NumOfFiles = 0; FRESULT Fresult = FR_OK; if (1)//(Semaphore_pend(FFS_Sem, BIOS_NO_WAIT)) { Fresult = f_unlink(request->path); Semaphore_post(FFS_Sem); } else { Fresult = FR_DENIED; Report("Semaphore_pend failed", __FILE__, __LINE__, 4, RpWarning, (int)0, 0); } REPORT_MSG(Fresult, "File Delete"); responseContainer = createContainer(MESSAGE_TYPE__DeleteResponse, requestContainer->token, false, &response, &delete_response__pack, &delete_response__get_packed_size); if (Fresult!= OK) { //usnprintf(ErrorMsg, 100, "File Operation failed error code %d",Fresult); responseContainer.has_error = true; responseContainer.error = getErrorCode(Fresult); responseContainer.errormessage = "File operation delete error"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); my_free(fno); delete_request__free_unpacked(request,NULL); SendChars(container_buffer, container_size); return OK; } uint32_t GetStorageInfoRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; MessageContainer responseContainer; GetStorageInfoRequest* request = get_storage_info_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); GetStorageInfoResponse response = GET_STORAGE_INFO_RESPONSE__INIT; FATFS *fs; DWORD fre_clust, fre_sect, tot_sect; FRESULT Fresult = FR_OK; /* Get volume information and free clusters of drive 1 */ Fresult = f_getfree("0:", &fre_clust, &fs); if (Fresult == FR_OK) { /* Get total sectors and free sectors */ tot_sect = (fs->n_fatent - 2) * fs->csize; fre_sect = fre_clust * fs->csize; response.has_capacity = true; response.capacity = tot_sect/2*1024; response.has_freespace = true; response.freespace = fre_sect/2*1024; response.root = "/"; } responseContainer = createContainer(MESSAGE_TYPE__GetStorageInfoResponse, requestContainer->token, false, &response, &get_storage_info_response__pack, &get_storage_info_response__get_packed_size); if (Fresult!= OK) { responseContainer.has_error = true; responseContainer.error = getErrorCode(Fresult); responseContainer.errormessage = "File operation get storage info error"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); size_t container_size = message_container__pack(&responseContainer, container_buffer); my_free(responseContainer.data.data); get_storage_info_request__free_unpacked(request,NULL); SendChars(container_buffer, container_size); return OK; } //char Datestr[100]; uint32_t GetFilesRequestFunc(MessageContainer* requestContainer) { //uint32_t status = OK; MessageContainer responseContainer; GetFilesRequest* request = get_files_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data); GetFilesResponse response = GET_FILES_RESPONSE__INIT; #define MAX_NUM_OF_FILES 20 DIR dir; FILINFO* fno[MAX_NUM_OF_FILES]; char FullPath[MAX_NUM_OF_FILES][60]; int i,NumOfFiles = 0; FRESULT Fresult = FR_OK; FileInfo **FilesInfo = (FileInfo**)my_malloc(sizeof(FileInfo *)*(MAX_NUM_OF_FILES)); FileInfo Data[MAX_NUM_OF_FILES]; if (1)//(Semaphore_pend(FFS_Sem, BIOS_NO_WAIT)) { Fresult |= f_opendir(&dir, g_cCwdBuf); if(Fresult != FR_OK) { Semaphore_post(FFS_Sem); return(Fresult); } memset (fno,0,sizeof(fno)); memset(fno,0,sizeof(fno)); fno[0] = my_malloc(sizeof(FILINFO)); memset (fno[0],0,sizeof(FILINFO)); //============================ Fresult = f_opendir(&dir, request->path); /* Open the directory */ if (Fresult == FR_OK) { for (NumOfFiles = 1;NumOfFiles < MAX_NUM_OF_FILES;NumOfFiles++) { fno[NumOfFiles] = my_malloc(sizeof(FILINFO)); memset (fno[NumOfFiles],0,sizeof(FILINFO)); Fresult = f_readdir(&dir, fno[NumOfFiles]); /* Read a directory item */ if (Fresult == FR_OK) { if(fno[NumOfFiles]->fname[0] ==0) { break; } } } } Semaphore_post(FFS_Sem); } else { Fresult = FR_DENIED; Report("Semaphore_pend failed", __FILE__, __LINE__, 4, RpWarning, (int)0, 0); } if ((Fresult == FR_OK)&&(NumOfFiles)) { for (i = 0;i < NumOfFiles;i++) { file_info__init(&Data[i]); FilesInfo[i] = &Data[i]; Data[i].has_attribute = true; Data[i].attribute = fno[i]->fattrib; Data[i].name = fno[i]->fname; Data[i].has_length = true; Data[i].length = fno[i]->fsize; Data[i].has_lastmodifieddate = true; Data[i].lastmodifieddate = fno[i]->fdate; Data[i].has_lastmodifiedtime = true; Data[i].lastmodifiedtime = fno[i]->ftime; if (i==0) usnprintf(&FullPath[i], 50, "%s", request->path); else if (strlen(request->path)==1) //info under the root usnprintf(&FullPath[i], 50, "%s%s", request->path, fno[i]->fname); else usnprintf(&FullPath[i], 50, "%s%s%s", request->path,"/", fno[i]->fname); Data[i].fullpath = &FullPath[i]; } response.n_items = NumOfFiles; response.items = FilesInfo; } else { response.n_items = 0; response.items = NULL; } responseContainer = createContainer(MESSAGE_TYPE__GetFilesResponse, requestContainer->token, false, &response, &get_files_response__pack, &get_files_response__get_packed_size); if (Fresult!= OK) { responseContainer.has_error = true; responseContainer.error = getErrorCode(Fresult); responseContainer.errormessage = "File operation get files error"; } responseContainer.continuous = false; uint8_t* container_buffer = my_malloc(message_container__get_packed_size(&responseContainer)); if (container_buffer) { size_t container_size = message_container__pack(&responseContainer, container_buffer); SendChars(container_buffer, container_size); } if (responseContainer.data.data) my_free(responseContainer.data.data); if (FilesInfo) my_free(FilesInfo); get_files_request__free_unpacked(request,NULL); for (i = 0;i < NumOfFiles;i++) { if (fno[i]) my_free (fno[i]); } return Fresult; } FRESULT FileWrite(void * buffer, uint16_t size,char *path, uint32_t timeout) { FRESULT Fresult = FR_OK; FIL *FileHandle = 0; //the system supports a single active file uint32_t Bytes = 0; if (buffer) { FileHandle = my_malloc(sizeof(FIL)); if (FileHandle == 0) Fresult = FR_DENIED; else { if (1)//(Semaphore_pend(FFS_Sem, BIOS_NO_WAIT)) { Fresult = f_open(FileHandle,path,FA_WRITE | FA_OPEN_ALWAYS|FA_CREATE_ALWAYS); if (Fresult == FR_OK) { Fresult = f_write(FileHandle,buffer,size,&Bytes ); if(Fresult != FR_OK) { LOG_ERROR (Fresult,"fwrite error"); } //LOG_ERROR (Bytes,"f_write ok no of bytes"); Report("f_write ok no of bytes", __FILE__, __LINE__, Bytes, RpWarning, (int)size, 0); f_close(FileHandle); } else { LOG_ERROR (Fresult,"fopen error"); } Semaphore_post(FFS_Sem); } else { Fresult = FR_DENIED; Report("Semaphore_pend failed", __FILE__, __LINE__, 4, RpWarning, (int)0, 0); } my_free(FileHandle); } } return Fresult; } FRESULT FileRead(char *path, uint32_t *Size, void **Buffer) { FRESULT Fresult = FR_OK; FIL *FileHandle = 0; //the system supports a single active file FILINFO* fno = 0; void* buffer = NULL; uint32_t Bytes = 0; //uint32_t status = 0; fno = my_malloc(sizeof(FILINFO)); if (fno == 0) return ERROR; memset (fno,0,sizeof(FILINFO)); Fresult = f_stat(path,fno); if (Fresult == FR_OK) { buffer = my_malloc (fno->fsize); if (buffer) { FileHandle = my_malloc(sizeof(FIL)); if (FileHandle == 0) Fresult = FR_DENIED; else { if (1)//(Semaphore_pend(FFS_Sem, BIOS_NO_WAIT)) { Fresult = f_open(FileHandle,path,FA_READ); if (Fresult == FR_OK) { Fresult = f_read(FileHandle,buffer,fno->fsize,&Bytes ); if(Fresult == FR_OK) { *Buffer = buffer; *Size = (uint32_t)fno->fsize; Report("f_read ok no of bytes", __FILE__, __LINE__, Bytes, RpWarning, (int)fno->fsize, 0); } else { LOG_ERROR (Fresult,"fread error"); my_free (buffer); } f_close(FileHandle); } else { LOG_ERROR (Fresult,"fopen error"); my_free (buffer); } Semaphore_post(FFS_Sem); } else { Fresult = FR_DENIED; Report("Semaphore_pend failed", __FILE__, __LINE__, 4, RpWarning, (int)0, 0); } my_free(FileHandle); } } else { LOG_ERROR (Fresult,"malloc error"); } } else { LOG_ERROR (Fresult,"f_stat error"); } my_free(fno); return Fresult; } FRESULT FileOpen(char *path, uint32_t *Size, FIL *FileHandle) { FRESULT Fresult = FR_OK; FILINFO* fno = 0; fno = my_malloc(sizeof(FILINFO)); if (fno == 0) return ERROR; memset (fno,0,sizeof(FILINFO)); Fresult = f_stat(path,fno); *Size = (uint32_t)fno->fsize; if (Fresult == FR_OK) { //FileHandle = my_malloc(sizeof(FIL)); if (FileHandle == 0) Fresult = FR_DENIED; else if (1)//(Semaphore_pend(FFS_Sem, BIOS_NO_WAIT)) { Fresult = f_open(FileHandle,path,FA_READ); Semaphore_post(FFS_Sem); //will be closed with the f_close, in the job } else { Fresult = FR_DENIED; Report("Semaphore_pend failed", __FILE__, __LINE__, 4, RpWarning, (int)0, 0); } } else { Report("f_stat error", __FILE__, __LINE__,Fresult, RpWarning, (int)0, 0); } my_free(fno); return Fresult; }