aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c
blob: 84d8fa725dfb7d2bb67b97bbcdcbbe988c3df2d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
generated by cgit v1.3.1 (git 2.54.0) at 2026-07-03 09:32:02 +0000
 


566' href='#n566'>566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
/*
 * FileSystem.c
 *
 *  Created on: Oct 23, 2018
 *      Author: shlomo
 */
#include "include.h"
#include "Communication/CommunicationTask.h"
#include "Communication/connection.h"
#include <DataDef.h>

#include  <Communication/PMR/IO/FileUploadRequest.pb-c.h>
#include  <Communication/PMR/IO/FileUploadResponse.pb-c.h>
#include  <Communication/PMR/IO/FileChunkUploadRequest.pb-c.h>
#include  <Communication/PMR/IO/FileChunkUploadResponse.pb-c.h>
#include  <Communication/PMR/IO/FileDownloadRequest.pb-c.h>
#include  <Communication/PMR/IO/FileDownloadResponse.pb-c.h>
#include  <Communication/PMR/IO/FileChunkDownloadRequest.pb-c.h>
#include  <Communication/PMR/IO/FileChunkDownloadResponse.pb-c.h>
#include  <Communication/PMR/IO/ExecuteProcessRequest.pb-c.h>
#include  <Communication/PMR/IO/ExecuteProcessResponse.pb-c.h>
#include  <Communication/PMR/IO/KillProcessRequest.pb-c.h>
#include  <Communication/PMR/IO/KillProcessResponse.pb-c.h>
#include  <Communication/PMR/IO/CreateRequest.pb-c.h>
#include  <Communication/PMR/IO/CreateResponse.pb-c.h>
#include  <Communication/PMR/IO/DeleteRequest.pb-c.h>
#include  <Communication/PMR/IO/DeleteResponse.pb-c.h>
#include  <Communication/PMR/IO/GetStorageInfoRequest.pb-c.h>
#include  <Communication/PMR/IO/GetStorageInfoResponse.pb-c.h>
#include  <Communication/PMR/IO/GetFilesRequest.pb-c.h>
#include  <Communication/PMR/IO/GetFilesResponse.pb-c.h>
#include  <Communication/PMR/IO/FileAttribute.pb-c.h>

#include "drivers/Flash_Memory/Flash_Memory.h"
#include "drivers/Flash_Memory/fatfs/ff.h"
#include "drivers/FPGA/FPGA_GPIO/FPGA_GPIO.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;

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;
}
uint32_t    FileUploadRequestFunc(MessageContainer* requestContainer)
{
    //uint32_t status = OK;

    FRESULT Fresult = FR_OK;

    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 (Semaphore_pend(FFS_Sem, BIOS_NO_WAIT))
            {
                CommRxTaskHandle = Task_self();
                Task_setPri(CommRxTaskHandle, 2);
               // 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(FFS_Sem);
                }
            }
            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    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 uplad rejected - file not created", __FILE__, __LINE__, 4, RpWarning,   (int)0, 0);
        FileDone = true;
    }
    else
    {
        KeepAliveOneSecondCounter = 0;
        save_milisec = msec_millisecondCounter;
        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);

            //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, 9);
        Semaphore_post(FFS_Sem);
        //Report("Task_setPri", __FILE__, __LINE__, 9, 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);
        UploadFileHandle = 0;
        FileReceivedLength = 0;
        FileDone = true;
        Task_setPri(CommRxTaskHandle, 9);
        Semaphore_post(FFS_Sem);
    }
}
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 (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 (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 (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];
    /*
    time_t t;
    struct tm *ltm;
    char *curTime;
    t = time(NULL);
    ltm = localtime(&t);
    curTime = asctime(ltm);
    Report(curTime, __FILE__, ltm->tm_hour,ltm->tm_min , RpWarning,  ltm->tm_sec, 0);
     */

    if (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;
           /*
           t = (fno[i]->fdate<<16)+fno[i]->ftime;
           ltm = localtime(&t);
           curTime = asctime(ltm);
           usnprintf(&Datestr, 100, "File info %s %s",fno[i]->fname, curTime);
           Report(Datestr, __FILE__, __LINE__, t, RpWarning,   (int)Data[i].lastmodifiedtime, 0);
           Task_sleep(50);
            */

           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 (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 (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 (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
    {
        LOG_ERROR (Fresult,"f_stat error");
    }
    my_free(fno);
    return Fresult;
}