Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers esfs.h Source File

esfs.h

00001 /*
00002  * Copyright (c) 2016 ARM Limited. All rights reserved.
00003  * SPDX-License-Identifier: Apache-2.0
00004  * Licensed under the Apache License, Version 2.0 (the License); you may
00005  * not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #ifndef __ESFS_H
00017 #define __ESFS_H
00018 
00019 #include <stdint.h>
00020 #include "pal_types.h"
00021 #include "pal_errors.h"
00022 #include "pal_macros.h"
00023 #include "pal_fileSystem.h"
00024 #include "pal_Crypto.h"
00025 
00026 
00027 
00028 #define ESFS_AES_NONCE_SIZE_BYTES   (8)
00029 
00030 // This value can be reduced to 0 to save stack space, if no metadata is required.
00031 // Beware that changing the values affects the format of the file.
00032 #define ESFS_MAX_TYPE_LENGTH_VALUES (3)
00033 
00034 #define ESFS_FILE_NAME_LENGTH       (9)
00035 
00036 // The maximum length of the name in bytes.
00037 #define ESFS_MAX_NAME_LENGTH            (1024)
00038 
00039 // ESFS_FILE_NAME_LENGTH + dot + extension (for example:  123456789.txt)
00040 #define ESFS_QUALIFIED_FILE_NAME_LENGTH       (ESFS_FILE_NAME_LENGTH + 4)
00041 
00042 #define ESFS_CMAC_SIZE_IN_BYTES         (16)
00043 
00044 typedef enum {
00045     ESFS_SUCCESS = 0,
00046     ESFS_INVALID_PARAMETER = 1,
00047     ESFS_INTERNAL_ERROR = 2,
00048     ESFS_BUFFER_TOO_SMALL = 3,
00049     ESFS_ERROR = 4 ,
00050     ESFS_EXISTS = 5,
00051     ESFS_NOT_EXISTS = 6,
00052     ESFS_HASH_CONFLICT = 7,
00053     ESFS_FILE_OPEN_FOR_READ = 8,
00054     ESFS_FILE_OPEN_FOR_WRITE = 9,
00055     ESFS_INVALID_FILE_VERSION = 10,
00056     ESFS_CMAC_DOES_NOT_MATCH = 11,
00057     ESFS_ERROR_MAXVAL = 0xFFFF
00058 }esfs_result_e;
00059 
00060 typedef enum {
00061     ESFS_USER_READ = 0x0001,
00062     ESFS_USER_WRITE = 0x0002,
00063     ESFS_USER_DELETE = 0x0004,
00064     ESFS_USER_EXECUTE = 0x0008,
00065     ESFS_OTHER_READ = 0x0010,
00066     ESFS_OTHER_WRITE = 0x0020,
00067     ESFS_OTHER_DELETE = 0x0040,
00068     ESFS_OTHER_EXECUTE = 0x0080,
00069     ESFS_ENCRYPTED = 0x0100,
00070     ESFS_FACTORY_VAL = 0x0200,
00071     ESFS_EXTENDED_ACL = 0x0400,
00072     ESFS_MAXVAL = 0xFFFF
00073 }esfs_mode_e;
00074 
00075 typedef enum {
00076     ESFS_READ = 1,    // This is the same as the standard "O_RDONLY"
00077     ESFS_WRITE = 2    // This is the same as the standard "O_WRONLY & O_APPEND"
00078 }esfs_file_flag_e;
00079 
00080 typedef struct {
00081     uint16_t type;
00082     uint16_t length_in_bytes;
00083     void *value;
00084 } esfs_tlv_item_t;
00085 
00086 typedef struct {
00087     uint16_t type;
00088     uint16_t length_in_bytes;
00089     // Position in bytes from the beginning of the of file.
00090     uint16_t position;
00091 } esfs_tlvItem_t;
00092 
00093 typedef struct {
00094     uint16_t number_of_items;
00095     esfs_tlvItem_t tlv_items[ESFS_MAX_TYPE_LENGTH_VALUES];
00096 }esfs_tlv_properties_t;
00097 
00098 
00099 typedef struct {
00100     palFileDescriptor_t file;
00101     esfs_file_flag_e file_flag;
00102     palAesHandle_t aes_ctx;
00103     palCMACHandle_t signature_ctx;  // NULL indicates no context.
00104     uint8_t nonce[ESFS_AES_NONCE_SIZE_BYTES];
00105     uint8_t cmac[ESFS_CMAC_SIZE_IN_BYTES]; // Saved on open/create; compared with on read
00106     uint16_t esfs_mode;
00107     uint16_t blob_name_length;
00108     char short_file_name[ESFS_QUALIFIED_FILE_NAME_LENGTH];
00109     esfs_tlv_properties_t tlv_properties;
00110     uint8_t file_invalid; // The file handle is invalid.
00111     // These are valid for files that are opened, not created.
00112     long current_read_pos;   // The byte position from the beginning of the data.
00113     size_t data_size;   // The size of the data only in bytes.
00114     int32_t file_size;  // Cache the physical file size on open.
00115 }esfs_file_t;
00116 
00117 // ESFS from which the enum values are in sync with those of PAL.
00118 typedef enum {
00119     ESFS_SEEK_SET = PAL_FS_OFFSET_SEEKSET,    // Offset will be relative to the beginning of the file.
00120     ESFS_SEEK_CUR = PAL_FS_OFFSET_SEEKCUR,    // Ofset will be relative to the last position read.
00121     ESFS_SEEK_END = PAL_FS_OFFSET_SEEKEND     // Offset will be relative to the end of the file and must be zero or a negative number.
00122 }esfs_seek_origin_e;
00123 
00124 #ifdef __cplusplus
00125 extern "C" {
00126 #endif
00127 
00128 /** 
00129 * @brief esfs_init Must be called once after boot.
00130 *  Initializes the file system so that it can be used.
00131 *  It creates the working and backup folders if they do not exist.
00132 *  If the factory_reset operation was not completed, esfs_init continues the operation.
00133 *
00134 * @returns ESFS_SUCCESS or an error code.
00135 *
00136 */
00137 esfs_result_e esfs_init(void);
00138 
00139 
00140 /** 
00141 * @brief esfs_finalize needs to be called before calling esfs_init again.
00142 * @returns ESFS_SUCCESS.
00143 *
00144 */
00145 esfs_result_e esfs_finalize(void);
00146 
00147 
00148 /**
00149 * @brief esfs_factory_reset removes the files from the working folder
00150 *  and creates a copy of the files that were created with ESFS_FACTORY_VAL set in the esfs_mode parameter in the working folder.
00151 *  If the device is rebooted during the factory reset operation, ESFS resumes the operation when calling esfs_init after the reboot.
00152 *
00153 * @returns ESFS_SUCCESS or ESFS_ERROR.
00154 *
00155 */
00156 esfs_result_e esfs_factory_reset(void);
00157 
00158 
00159 /** 
00160  * @brief esfs_reset resets ESFS to an empty state.
00161                 Initializes the file system and formats the SD card if required. Also initializes the internal structures.
00162  *
00163  * @returns ESFS_SUCCESS or an error code.
00164  *
00165  */
00166 esfs_result_e esfs_reset(void);
00167 
00168 /**
00169  * @brief Creates a new file and opens it for writing. Returns an error if a file exists.
00170  *
00171  *
00172  * @param [in] name
00173  *               A binary blob that uniquely identifies the file.
00174  *
00175  * @param [in] name_length
00176  *               The size of the name in bytes. The minimum is 1 and the maximum is ESFS_MAX_NAME_LENGTH.
00177  *
00178  * @param  [in] meta_data
00179  *                A pointer to an array of TLVs structures with meta_data_qty members.
00180  *
00181  * @param  [in] meta_data_qty
00182  *                The number of TLVs in the array pointed by the meta_data parameter. The minimum is 0 and the maximum is ESFS_MAX_TYPE_LENGTH_VALUES.
00183  *
00184  * @param  [in] esfs_mode
00185  *      A bitmap combination of values from the enum EsfsMode.
00186  *
00187  * @param [out] esfs_file_t file_handle A handle to the created file open for write.
00188  *
00189  * @returns ESFS_SUCCESS The file handle can be used in other ESFS functions. It must be closed to release it.
00190  *          ESFS_INVALID_PARAMETER if the name, name_length, file_handle or meta_data_qty is not valid.
00191  *          ESFS_EXISTS if a file with the same blob is found in the file system.
00192  *          ESFS_HASH_CONFLICT if two different blobs result in the same short name.
00193  *
00194  *
00195  */
00196 esfs_result_e esfs_create(const uint8_t * name, size_t name_length, const esfs_tlv_item_t *meta_data, size_t meta_data_qty, uint16_t esfs_mode, esfs_file_t *file_handle);
00197 
00198 /**
00199  * @brief Opens a file for read.
00200  *
00201  *
00202  * @param [in] name
00203  *               A binary blob that uniquely identifies the file.
00204  *
00205  * @param [in] name_length
00206  *               The size of the name in bytes.
00207  *
00208  * @param  [out] esfs_mode
00209  *                A pointer to get the actual mode bits passed on file creation (see EfsFlags for bit values).
00210  *
00211  *
00212  * @param [out] file_handle A handle to the file for future use.
00213  *
00214  * @returns ESFS_SUCCESS or an error code.
00215  * ESFS_INVALID_PARAMETER if the name, name_length or file_handle is not valid.
00216  * ESFS_HASH_CONFLICT - A file with the same file name but a different name is found.
00217  * ESFS_CMAC_DOES_NOT_MATCH - The CMAC does not match. The file has possibly been tampered with.
00218  * ESFS_INVALID_FILE_VERSION  - The format is invalid. This may indicate that the file is corrupt or the firmware supports
00219  * a different file version from the one opened.
00220  * ESFS_NOT_EXISTS if the file does not exist.
00221  * If successful, the file handle can be used in other ESFS functions. It must be closed to release it.
00222  *
00223  *
00224  */
00225 esfs_result_e esfs_open(const uint8_t * name, size_t name_length, uint16_t * esfs_mode, esfs_file_t *file_handle);
00226 
00227 /**
00228  * @brief Close the file and invalidate the file handle.
00229  *
00230  * @param [in] file_handle The handle.
00231  *
00232  * @returns ESFS_SUCCESS or an error code.
00233  * ESFS_INVALID_PARAMETER if the file_handle is not correct.
00234  * ESFS_HASH_CONFLICT - Trying to open a file with the same file name but a different name.
00235  */
00236 esfs_result_e esfs_close(esfs_file_t *file_handle);
00237 
00238 /**
00239  * @brief Reads data from a previously opened file with parameter esfs_mode=EfsRead. Decrypt if required.
00240  *
00241  *
00242  * @param [in] file_handle
00243  *               The handle obtained from a call to esfs_open.
00244  *
00245  *
00246  * @param  [in] buffer
00247  *                A pointer to the memory buffer where the data read from the file is stored.
00248  *
00249  * @param  [in] bytes_to_read
00250  *                The number of bytes to be read. The buffer must be big enough to contain this size.
00251  *
00252  *
00253  * @param [out] read_bytes
00254  *                The pointer to return the number of bytes actually read. Will be equal or smaller than bytes_to_read.
00255  *
00256  * @returns ESFS_SUCCESS 
00257  *          ESFS_INVALID_PARAMETER if the file_handle is not correct, buffer is null or read_bytes is null.
00258  *          ESFS_FILE_OPEN_FOR_WRITE if the file is after esfs_create and before esfs_close.
00259  *
00260  */
00261 esfs_result_e esfs_read(esfs_file_t *file_handle, void *buffer, size_t bytes_to_read, size_t *read_bytes);
00262 
00263 /**
00264  * @brief Returns the metadata properties (TLVs) associated with the file.
00265  *
00266  * @param [in] file_handle
00267  *               The handle obtained from a call to esfs_open.
00268  *
00269  * @param [out] meta_data_properties
00270  *              A pointer to return the metadata properties.
00271  *
00272  * @returns ESFS_SUCCESS 
00273  *         ESFS_INVALID_PARAMETER if file_handle is not valid or meta_data_properties is null.
00274  *         ESFS_FILE_OPEN_FOR_WRITE if the file is after esfs_create and before esfs_close.
00275  *
00276  */
00277 esfs_result_e esfs_get_meta_data_properties(esfs_file_t *file_handle, esfs_tlv_properties_t **meta_data_properties);
00278 /**
00279  * @brief Reads a single metadata entry into a TLV.
00280  *
00281  * @param [in] file_handle
00282  *               The handle obtained from a call to esfs_open.
00283  *
00284  * @param [in] index
00285  *                The index of the metadata if more than one meta data entry with the same type is present. 0 is the first one. 
00286  *                The index refers to an imaginary array that holds metadata entries of the same type only.
00287  *
00288  * @param [in,out] meta_data
00289  *                A pointer to an esfs_tlv_item_t structure with a valid *value pointing to a buffer aligned and big enough to hold the metadata.
00290  *                The type and length_in_bytes fields of the TLV should be filled before calling the function with the right values for the required metadata.
00291  *                The function will check the correctness of the fields.
00292  *                (See esfs_get_meta_data_buffer_size to calculate the required size.)
00293  *
00294  *
00295  *@returns ESFS_SUCCESS 
00296  *         ESFS_INVALID_PARAMETER if file_handle or meta_data is not valid or the index is out of bounds.
00297  *         ESFS_FILE_OPEN_FOR_WRITE if the file is after esfs_create and before esfs_close.
00298  *
00299  */
00300 esfs_result_e esfs_read_meta_data(esfs_file_t *file_handle, uint32_t index, esfs_tlv_item_t *meta_data);
00301 
00302 /**
00303  * @brief Change the current position for read. This function will return an error if used on a file open with EfsWrite mode
00304  * or the resulting position is out of the data range of the file.
00305  *
00306  *@param [in] file_handle
00307  *               The handle obtained from a call to esfs_open.
00308  *
00309  *
00310  * @param  [in] offset
00311  *                The number of bytes to move the read position. It can be negative but must be in range of the data.
00312  *
00313  * @param  [in] whence
00314  *                The position to relate the calculation of the new position for read. Use EfsSEEK_SET to seek the read position offset bytes from the beginning of the file and
00315  *                EfsSEEK_CUR to change the read position offset bytes from the last read. The last read is in the beginning of the file after open.
00316  *
00317  * @param  [out] position
00318  *                  A pointer to an integer that will hold the read position after the seek. The pointer may be NULL if the position is not the desired one.
00319  *
00320  *@returns ESFS_SUCCESS
00321  *         ESFS_INVALID_PARAMETER if file_handle is not valid or the offset is out of bounds.
00322  *         ESFS_FILE_OPEN_FOR_WRITE if the file is after esfs_create and before esfs_close.
00323  *
00324  *
00325  */
00326 esfs_result_e esfs_seek(esfs_file_t *file_handle, int32_t offset, esfs_seek_origin_e whence, uint32_t *position);
00327 
00328 /**
00329  * @brief Removes the file from the file system.
00330  *
00331  *
00332  *@param [in] name
00333  *               A binary blob that uniquely identifies the file.
00334  *
00335  * @param [in] name_length
00336  *               The size of the name in bytes.
00337  * @returns ESFS_SUCCESS
00338  *          ESFS_NOT_EXISTS if the file does not exist.
00339  *          ESFS_INVALID_PARAMETER if name, name_length or file_handle is not valid.
00340  */
00341 esfs_result_e esfs_delete(const uint8_t * name, size_t name_length);
00342 
00343 /**
00344  * @brief Write data to the file. Encrypt if required.
00345  * This may leave the file in an unpredictable state on failure. If that happens, the file
00346  * will be deleted by efs_close. The data is only guaranteed to be flushed to the media on efs_close.
00347  *
00348  *
00349  * @param    [in] file_handle
00350  *               The handle obtained from a call to esfs_open.
00351  *
00352  * @param    [in] buffer
00353  *               A pointer to memory buffer with the data to write.
00354  *
00355  * @param    [in] bytes_to_write
00356  *               The number of bytes to write from the buffer.
00357  *
00358  * @returns ESFS_SUCCESS
00359  *          ESFS_FILE_OPEN_FOR_READ if called after esfs_open (file opened for read).
00360  *          ESFS_INVALID_PARAMETER if file_handle is not correct, buffer is null or bytes_to_write == 0.
00361  *
00362  *
00363  */
00364 esfs_result_e esfs_write(esfs_file_t *file_handle, const void *buffer, size_t bytes_to_write);
00365 
00366 /**
00367  * @brief Returns the size of the data in the file.
00368  *
00369  * @param    [in] file_handle
00370  *               The handle obtained from a call to esfs_open.
00371  *
00372  * @param    [out] size_in_bytes
00373  *               A pointer to hold the size of the data in the file.
00374  *
00375  *
00376  * @returns ESFS_SUCCESS
00377  *          ESFS_INVALID_PARAMETER if file_handle is not valid.
00378  *
00379  *
00380  */
00381 esfs_result_e esfs_file_size(esfs_file_t *file_handle, size_t *size_in_bytes);
00382 
00383 #ifdef __cplusplus
00384 }
00385 #endif
00386 
00387 #endif
00388 
00389