/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*----------------------------------------------------------------------------*/
/*! @file c_fm_mfw.h 
 *  $RCSfile: $
 *  $Revision: #2 $
 *  $Date: 2015/06/24 $
 *  $Author: songwen.liao $
 *  
 *  @par Description:
 *         This header file contains Multi-File-Wrapper exported functions.
 */
/*----------------------------------------------------------------------------*/

#ifndef _C_FM_MFW_H_
#define _C_FM_MFW_H_

/*-----------------------------------------------------------------------------
                    include files
-----------------------------------------------------------------------------*/
#include "u_fm.h"
#include "u_fm_mfw.h"
#include "u_common.h"
#include "u_handle.h"

/*!
 * @addtogroup    groupMW_FM_MFW
 * @ingroup     groupMW_FM
 * @brief    This header file contains Multi-File-Wrapper exported functions.
 * %MFW is a wrapper of multi files, user can access it as a visual file. 
 * 
 * @see groupMW_FM_MFW
 *
 * @{
 * */


/*-----------------------------------------------------------------------------
                    macros, defines, typedefs, enums
 ----------------------------------------------------------------------------*/
#define IN     /**<        */
#define OUT    /**<        */
/*-----------------------------------------------------------------------------
                    data declarations
 ----------------------------------------------------------------------------*/

/*-----------------------------------------------------------------------------
                    functions declarations
 ----------------------------------------------------------------------------*/
/*------------------------------------------------------------------*/
/*! @brief  Analyse the device to get the available space and the continuous
  *         space. This is a asynchronous a function, and wrapper will inform
  *         the caller of the analysing progress. When the analysing is done,
  *         inform caller of the result. After that, wrapper will free the handle
  *         itself.
 *  @param [in]  pt_param    -   Parameters for analysing.
 *  @param [out] h_req       -   Handle of the analysing request.
 *  @return Return the error code.
 *  @retval FMR_OK      -   Success!
 *  @retval FMR_ARG     -   pt_parm is NULL or ph_req is NULL or pt_parm has invalid member
 *                          varialbes.
 *  @retval FMR_CORE    -   Internal error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_analyse(
    IN  const FM_MFW_ANLS_PARAM_T* pt_param,
    OUT HANDLE_T*                  ph_req);


/*------------------------------------------------------------------*/
/*! @brief  Create a wrapper file according to the configs. This is a asynchronous
  *         a function, and it will analyse the device to get the available space 
  *         and the continuous space first, and then do the creating things. Wrapper
  *         will inform the caller of the analysing progress in phase1 and creating
  *         progress in phase2. When the creating is done, inform caller of the 
  *         result. After that, wrapper will free the handle itself.
 *  @param [in] pt_cfg  -   Configs for creating.
 *  @param [out]h_req   -   Handle of the creating request.
 *  @return Return the error code.
 *  @retval FMR_OK      -   Success!
 *  @retval FMR_ARG     -   pt_cfg is NULL or ph_req is NULL or pt_cfg has invalid member
 *                          varialbes.
 *  @retval FMR_CORE    -   Internal error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_create(
    IN  const FM_MFW_VF_CFG_T*     pt_cfg,
    OUT HANDLE_T*                  ph_req);


/*------------------------------------------------------------------*/
/*! @brief  Delete a wrapper/normal file.
 *  @param [in] h_dir    -   Handle of a directory label.
 *  @param [in] ps_path  -   Path name of the wrapper/normal file to be deleted.
 *  @param [out] None.
 *  @return Return the error code.
 *  @retval FMR_OK      -   Success!
 *  @retval FMR_ARG     -   ps_path is NULL.
 *  @retval FMR_CORE    -   Internal error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_delete(
    IN  HANDLE_T                   h_dir,
    OUT const CHAR*                ps_path);


/*------------------------------------------------------------------*/
/*! @brief  Check if the file is a wrapper file. If it is a wrapper file, 
  *         then check if all sub files in the wrapper are OK.
 *  @param [in] h_dir    -   Handle of a directory label.
 *  @param [in] ps_path  -   Path name of the wrapper file to be checked.
 *  @param [out] None.
 *  @return Return the error code.
 *  @retval FMR_OK      -   Success!
 *  @retval FMR_ARG     -   ps_path is NULL.
 *  @retval FMR_CORE    -   Internal error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_check(
    IN  HANDLE_T                   h_dir,
    IN  const CHAR*                ps_path,
    OUT BOOL*                      pb_mfw,
    OUT BOOL*                      pb_ok);

/*------------------------------------------------------------------*/
/*! @brief  Open a multi-file wrapper/normal file, and return a mfw/normal file handle. 
 *  @param [in]  h_dir      -   Handle of a directory label.
 *  @param [in]  ps_path    -   Path name of the file to be opened.
 *  @param [in]  ui4_flags  -   Flags for open. User can specify these flags by bitwise 'OR'
 *                              operation. The valid flags are as follows:
 *                              FM_READ_ONLY tells File Manager that the file is opened
 *                              for read only, and any write operation will get a FMR_PERM_DENY.
 *                              FM_WRITE_ONLY tells File Manager that the file is opend
 *                              for write only, and any read operation will get a FMR_PERM_DENY.
 *                              FM_READ_WRITE tells File Manager that the file is opened
 *                              for both read and write.
 *                              If none of above flags is selected, the default is read only.
 *                              If more than one is set, FM_READ_WRITE supersedes
 *                              FM_WRITE_ONLY and FM_WRITE_ONLY supersedes FM_READ_ONLY.
 *                              FM_OPEN_CREATE tells File Manager to create the specified
 *                              file if it does not exist.
 *                              FM_OPEN_TRUNC tells File Manager to truncate all contents of
 *                              the specified file. The starting offset will be zero
 *                              FM_OPEN_APPEND tells File Manager to set the starting offset
 *                              to the end of the file.
 *                              FM_OPEN_EXCLUDE tells File Manager to exclusively create a
 *                              file. It fails if the file already exists.
 *  @param [in]  ui4_mode   -   UNIX style access permission. The valid values are as follows:
 *                              FM_MODE_USR_READ
 *                              FM_MODE_USR_WRITE
 *                              FM_MODE_USR_EXEC
 *                              FM_MODE_GRP_READ
 *                              FM_MODE_GRP_WRITE
 *                              FM_MODE_GRP_EXEC
 *                              FM_MODE_OTH_READ
 *                              FM_MODE_OTH_WRITE
 *                              FM_MODE_OTH_EXEC
 *  @param [in]  b_ext_buf  -   Use the external buffer. If it is TRUE, File Manager will
 *                              NOT cache it. However, the buffer address must be aligned
 *                              to specific address due to the hardware's limitation.
 *  @param [out] ph_file    -   Handle of the opened wrapper/normal file.
 *  @return Return the error code.
 *  @retval FMR_OK              -   Success.
 *  @retval FMR_ARG             -   ps_path is NULL.
 *  @retval FMR_HANDLE          -   h_dir is an invalid handle.
 *  @retval FMR_INVAL           -   ps_path is an invalid path.
 *  @retval FMR_NO_ENTRY        -   The directory component in ps_path or ps_path itself does not exist.
 *  @retval FMR_NOT_DIR         -   The directory component in ps_path is not a directory.
 *  @retval FMR_NAME_TOO_LONG   -   Length of ps_path is too long.
 *  @retval FMR_CORE            -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_open (
    IN  HANDLE_T                   h_dir,
    IN  const CHAR*                ps_path,
    IN  UINT32                     ui4_flags,
    IN  UINT32                     ui4_mode,
    IN  BOOL                       b_ext_buf,
    OUT HANDLE_T*                  ph_file); 

/*------------------------------------------------------------------*/
/*! @brief  Close an opened wrapper/file.
 *  @param [in]  h_file  -   Handle of an opened wrapper/normal file.
 *  @param [out] None.
 *  @return Return the error code.
 *  @retval FMR_OK              -   Success.
 *  @retval FMR_HANDLE          -   h_file is an invalid handle.
 *  @retval FMR_INVAL           -   h_file is an file being closed.
 *  @retval FMR_CORE            -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_close(
    IN  HANDLE_T    h_file);

/*------------------------------------------------------------------*/
/*! @brief  set tshift reserve size .
 *  @param [in]  ui8_size  -   Handle of an opened wrapper/normal file.
 *  @param [out] None.
 *  @return Return the error code.
 *  @retval FMR_OK              -   Success.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_set_tshift_reserve_size(
    IN  UINT64    ui8_size);

/*------------------------------------------------------------------*/
/*! @brief Change the current postion of the opened multi-file wrapper/normal file.
 *  @param [in] h_file      -   Handle of an opened multi-file wrapper/normal file.
 *  @param [in] i8_offset   -   Offset from ui4_whence in bytes. Positive number means move
 *                              current position backward while negative number means move
 *                              forward.
 *  @param [in] ui1_whence  -   FM_SEEK_BGN tells File Manager to move current position to
 *                              i8_offset from the begging of the file. if i8_offset is
 *                              negative, current position is set to 0, that is the begging
 *                              of file.
 *                              FM_SEEK_CUR tells File Manager to move current position to
 *                              i8_offset from current position.
 *                              FM_SEEK_END tells File Manager to move current position to
 *                              i8_offset from the end of the file. If i8_offset is a
 *                              positive number, current position is set to the size of
 *                              the file, that is the end of file.
 *  @param [out] pui8_cur_pos    -   Current position.
 *  @return Return the error code
 *  @retval FMR_OK      -   Success.
 *  @retval FMR_ARG     -   pui8_cur_pos is NULL.
 *  @retval FMR_HANDLE  -   h_file is an invalid handle.
 *  @retval FMR_INVAL   -   h_file is being closed or ui1_whence is not defined.
 *  @retval FMR_CORE    -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_lseek(
    IN  HANDLE_T        h_file,
    IN  INT64           i8_offset,
    IN  UINT8           ui1_whence,
    OUT UINT64*         pui8_cur_pos);
    

/*------------------------------------------------------------------*/
/*! @brief  Read data from wrapper/file to buffer.
 *  @param [in] h_file      -   Handle of an opened wrapper/file.
 *  @param [in] pv_data     -   Buffer to hold read data.
 *  @param [in] ui4_count   -   Number of bytes to read.
 *  @param [out] pui4_read  -   Actual read bytes.
 *  @return Return the error code.
 *  @retval FMR_OK              -   Success.
 *  @retval FMR_ARG             -   pv_data is NULL or pui4_read is NULL.
 *  @retval FMR_HANDLE          -   Fail to get the handle object.
 *  @retval FMR_INVAL           -   h_file does not reference to a file descriptor or it is being
 *                                  closed.
 *  @retval FMR_EOF             -   Reaches EOF.
 *  @retval FMR_DEVICE_ERROR    -   Device read error.
 *  @retval FMR_CORE            -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_read(
    IN  HANDLE_T        h_file,
    IN  VOID*           pv_data,
    IN  UINT32          ui4_count,
    OUT UINT32*         pui4_read);

/*------------------------------------------------------------------*/
/*! @brief  Asynchronously read data from the opened wrapper/file.
 *  @param [in] h_file      -   Handle of an opened wrapper/file.
 *  @param [in] pv_data     -   Buffer to hold read data.
 *  @param [in] ui4_count   -   Number of bytes to read.
 *  @param [in] ui1_pri     -   I/O priority.
 *  @param [in] pf_nfy_fct  -   Callback function while read is done.
 *  @param [in] pv_tag      -   Tag value, which will be returned in the callback.
 *  @param [out] None
 *  @return Return the error code
 *  @retval FMR_OK              -   Success.
 *  @retval FMR_ARG             -   pv_data is NULL.
 *  @retval FMR_HANDLE          -   Fail to get the handle object.
 *  @retval FMR_INVAL           -   h_file does not reference to a file descriptor or it is being
 *                                  closed, driver not ready, etc.
 *  @retval FMR_PERM_DENY       -   Permission deny.
 *  @retval FMR_EOF             -   Reaches end of file.
 *  @retval FMR_ALIGNMENT       -   pv_data alignment error.
 *  @retval FMR_DEVICE_ERROR    -   Device read error.
 *  @retval FMR_CORE            -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_read_async(
    IN  HANDLE_T        h_file,
    IN  VOID            *pv_data,
    IN  UINT32          ui4_count,
    IN  UINT8           ui1_pri,
    IN  x_fm_async_fct  pf_nfy_fct,
    IN  VOID*           pv_tag,
    OUT HANDLE_T*       ph_req);

/*------------------------------------------------------------------*/
/*! @brief  Write data from buffer to wrapper/file.
 *  @param [in] h_file       -   Handle of an opened wrapper/file.
 *  @param [in] pv_data      -   Buffer of data to be written.
 *  @param [in] ui4_count    -   Number of bytes to write.
 *  @param [out] pui4_write  -   Actual written bytes.
 *  @return Return the error code.
 *  @retval FMR_OK              -   Success.
 *  @retval FMR_ARG             -   pv_data is NULL or pui4_write is NULL.
 *  @retval FMR_HANDLE          -   Fail to get the handle object.
 *  @retval FMR_INVAL           -   h_file does not reference to a file descriptor or it is being
 *                                  closed.
 *  @retval FMR_EOF             -   Reaches EOF.
 *  @retval FMR_DEVICE_ERROR    -   Device read error.
 *  @retval FMR_CORE            -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_write(
    IN  HANDLE_T        h_file,
    IN  const VOID*     pv_data,
    IN  UINT32          ui4_count,
    OUT UINT32*         pui4_written);

/*------------------------------------------------------------------*/
/*! @brief  Asynchronously read data from the opened wrapper/file.
 *  @param [in] h_file      -   Handle of an opened wrapper/file.
 *  @param [in] pv_data     -   Buffer to hold read data.
 *  @param [in] ui4_count   -   Number of bytes to read.
 *  @param [in] ui1_pri     -   I/O priority.
 *  @param [in] pf_nfy_fct  -   Callback function while read is done.
 *  @param [in] pv_tag      -   Tag value, which will be returned in the callback.
 *  @param [out] None
 *  @return Return the error code
 *  @retval FMR_OK              -   Success.
 *  @retval FMR_ARG             -   pv_data is NULL.
 *  @retval FMR_HANDLE          -   Fail to get the handle object.
 *  @retval FMR_INVAL           -   h_file does not reference to a file descriptor or it is being
 *                                  closed, driver not ready, etc.
 *  @retval FMR_PERM_DENY       -   Permission deny.
 *  @retval FMR_EOF             -   Reaches end of file.
 *  @retval FMR_ALIGNMENT       -   pv_data alignment error.
 *  @retval FMR_DEVICE_ERROR    -   Device read error.
 *  @retval FMR_CORE            -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_write_async(
    IN  HANDLE_T        h_file,
    IN  const VOID*     pv_data,
    IN  UINT32          ui4_count,
    IN  UINT8           ui1_pri,
    IN  x_fm_async_fct  pf_nfy_fct,
    IN  VOID*           pv_tag,
    OUT HANDLE_T*       ph_req);
    
/*------------------------------------------------------------------*/
/*! @brief  Tell if current position reaches the end of wrapper/file.
 *  @param [in]  h_file -   Handle of an opened wrapper/file.
 *  @param [out] pb_eof -   TRUE if it is at EOF, otherwise FALSE is returned.
 *  @return Return the error code.
 *  @retval FMR_OK      -   Success.
 *  @retval FMR_ARG     -   pb_eof is NULL.
 *  @retval FMR_HANDLE  -   h_file is an invalid handle.
 *  @retval FMR_INVAL   -   File is beging closed.
 *  @retval FMR_CORE    -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_feof(
    IN  HANDLE_T        h_file,
    OUT BOOL            *pb_eof);


/*------------------------------------------------------------------*/
/*! @brief  Abort async-ed request
 *  @param [in] h_req   -   Handle of the async-ed request.
 *  @param [out] None.
 *  @return Return the error code.
 *  @retval FMR_OK      -   Success.
 *  @retval FMR_HANDLE  -   h_req is an invalid handle.
 *  @retval FMR_CORE    -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_abort_async(
    IN  HANDLE_T h_req);


/*------------------------------------------------------------------*/
/*! @brief  Get information about a wrapper/file by name.
 *  @param [in]  h_dir   -   Handle of a directory label.
 *  @param [in]  ps_path -   Path name of the wrapper/file.
 *  @param [out] pt_info -   Reference to the returned information about the wrapper/file.
 *  @return Return the error code.
 *  @retval FMR_OK              -   Success.
 *  @retval FMR_ARG             -   ps_path or pt_info is NULL.
 *  @retval FMR_HANDLE          -   h_dir is an invalid handle.
 *  @retval FMR_NAME_TOO_LONG   -   Length of ps_path is too long.
 *  @retval FMR_CORE            -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_get_info_by_name(
	HANDLE_T        h_dir,
    const CHAR*     ps_path,
    FM_FILE_INFO_T* pt_info);


/*------------------------------------------------------------------*/
/*! @brief  Get information about a wrapper/file by handle.
 *  @param [in]  h_dir   -   Handle of an opened wrapper/file.
 *  @param [out] pt_info -   Reference to the returned information about the wrapper/file.
 *  @return Return the error code.
 *  @retval FMR_OK              -   Success.
 *  @retval FMR_ARG             -   pt_info is NULL.
 *  @retval FMR_HANDLE          -   h_file is an invalid handle.
 *  @retval FMR_CORE            -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_get_info_by_handle(
    HANDLE_T        h_file,
    FM_FILE_INFO_T* pt_info);


/*------------------------------------------------------------------*/
/*! @brief  Get a mounted file system information.
 *  @param [in] h_dir    -   Handle of the directory label relative to ps_path.
 *  @param [in] ps_path  -   A file/directory path name in the file system.
 *  @param [out] pt_fs_info -   Reference to file system information object.
 *  @return Return the error code.
 *  @retval FMR_OK              -   Success.
 *  @retval FMR_ARG             -   ps_path or pt_fs_info is NULL.
 *  @retval FMR_HANDLE          -   h_dir is an invalid handle.
 *  @retval FMR_INVAL           -   ps_path is an invalid path.
 *  @retval FMR_NO_ENTRY        -   The directory component in ps_path or ps_path does not exist.
 *  @retval FMR_NOT_DIR         -   The directory component in ps_path is not a directory.
 *  @retval FMR_NAME_TOO_LONG   -   Length of ps_path is too long.
 *  @retval FMR_CORE            -   OSAI error.
 */
/*------------------------------------------------------------------*/
extern INT32 c_fm_mfw_get_fs_info(
    HANDLE_T        h_dir,
    const CHAR      *ps_path,
    FM_FS_INFO_T    *pt_fs_info);

/*! @}  */

#endif /* _C_FM_MFW_H */

