/* 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_dlnafs.h 
 *  $RCSfile: $
 *  $Revision: #1 $
 *  $Date: 2015/05/29 $
 *  $Author: brianpc.huang $
 *  
 *  @par Description:
 *                      This file contains public API of dlnafs.
 */
/*----------------------------------------------------------------------------*/

#ifndef _C_FM_DLNAFS_H_
#define _C_FM_DLNAFS_H_

#include "u_fm_dlnafs.h"
#include "u_common.h"

/*!
 * @addtogroup    groupMW_FM_DLNAFS
 * @brief    Provide extentional API about DLNA FS.
 * %groupMW_FM_DLNAFS is a set of functions that makes the dlna as a file system.
 *                    So user can use stand i/o (fm api) to access dlna function.
 *                    dlnafs is the middle leve of them.
 *                    dlna fs normally needn't access directly but just from FM API.
 *                    But dlna has some special functions that can't be used from FM API,
 *                    those functions is supplied specially here.
 * 
 * @see groupMW_FM
 *
 * @{
 * */

/*------------------------------------------------------------------------------  */
/*! 
 *  @brief     Get media information of dlna media file. This function especially is for LPCM.
 *     because LPCM can't be parsed media information from its content but must be got from the server. 
 *  @param     [in] ps_filename - specify the media file. It must be a full path from the root.
 *  @param     [out] pt_info - the pointer to the structure of DLNA_MEDIA_INFO_T, which holds the media info.
 *
 *  @return  return the error code.
 *  @retval FMR_OK
 *  @retval FMR_INVAL
 *  @retval FMR_NO_ENTRY
 */
/*------------------------------------------------------------------------------  */
INT32 c_dlna_dmp_fm_get_media_info(CHAR *ps_filename, DLNA_MEDIA_INFO_T *pt_info);

/*------------------------------------------------------------------------------  */
/*! 
*
* @brief       Specify how the retrieved files will be sort.
*              Because different dms(s) have different sort capabilities,
*              that is maybe DMS A supports sorting by date, but DMS B is not.
*              User uses this api to set orderby of a DMS with a pt_filename argument which is any dir or file belongs to
*              the DMS, if the DMS supports, return 0 and BROWSE results will be sorted by the "orderby", or the DMS
*              cannot support. 
*
*
* @param    [in]  ps_filename - which is directory or file of a DMS, may be the root dir of a DMS or  another file of the DMS, it doesn't matter.
*                    NULL only valid when CLI_SUPPORT and is for CLI or test.
*                    Means the set is for next XENTRY passed in read_dir, AP or FM or shouldn't use this case
*                    because it knows very much about the DMS to be sorted..
*
* @param    [in]  e_orderby - order by what.
*
* @param    [in]  b_override - if true, override previous setting, otherwise append the orderby to the end of previous setting.
* @note    For example: Suppose previous setting is "+dc:title", the api called with an e_orderby eqauls "+dc:date".
*                       1. If b_override is true, current setting is "+dc:date".
*                       2. If b_override is false, current setting is "+dc:title, +dc:date". It means that order by title ascending the
*                           first, and then order by date ascending.
 *
*                       NOTE: if b_override is false and the api returns DLNAR_DMS_CANNOT_SUPPORT, previous setting is still keept.
*                       if b_override is true and the api returns DLNAR_DMS_CANNOT_SUPPORT, orderby setting is cancaled and DMS will
*                       sort the results by its default policy.
*
* @return return error code.
*
* @retval    DLNAR_DMS_CANNOT_SUPPORT  - dms doesn't support.
* @retval    DLNAR_SUCCESS - have succesfully set the orderby. If pt_xent is NULL, return is alwasy OK Because the XENTRY is pending until next get_dir_info is performed.
*/
/*----------------------------------------------------------------------------*/    
INT32 c_fm_dlna_orderby(CHAR * ps_filename, DLNA_ORDERBY_TYPE_T e_orderby, BOOL b_override);

/*----------------------------------------------------------------------------*/
/*! 
*
* @brief       Specify what will be retrieved in read dir. It can be used when user only
*              wants to get some type of files, or arrange files by some type in order.
*              For example, User arranges file list as: video files the first, audio files
*              the second, and images the last. User can at first set video type by this method,
*              and then perform read_dir, when it is up to EOF, means all video is returned.
*              As the same processes, set audio type and then read_dir ...
*
* @param    [in]  ps_filename - in which the read dir will take place.
*
* @param    [in]  e_browse_type - the file type of which the read dir returns files.
*                          If want to cancel the sort filter, set type DLNA_FILE_CONTENT_TYPE_CARELESS to ovverride.
* 
* @return    return error code.
*
* @retval    DLNAR_DMS_CANNOT_SUPPORT  - dms don't support search capability
* @retval    DLNAR_SUCCESS - have succesfully set the sort filter.
*/
/*----------------------------------------------------------------------------*/    
INT32  c_fm_dlna_set_content_filter(CHAR * ps_filename, DLNA_FILE_CONTENT_TYPE_T e_browse_type);

/*------------------------------------------------------------------------------  */
/*! 
 *
 *  @brief    Query if the server supports the special feature that folder retrived back before files.
 *
 *  @param    [in] ps_filename  - container to be queried if it supports the feature.
 *
 *  @return return TRUE of FALSE.
 *
 *  @retval TRUE - Support.
 *  @retval FALSE - can't
 */
/*------------------------------------------------------------------------------  */ 
BOOL c_fm_dlna_is_folder_sorting_supported(CHAR * ps_filename);

/*------------------------------------------------------------------------------  */
/*! 
 *
 *  @brief   Query if one dir has changed from last access.
 *
 *  @param    [in] ps_dir_name - specify the dir name. It must be the full path.
 *
 *  @return TRUE or FALSE. Return TRUE if changed, otherwise return FALSE.
 */
/*------------------------------------------------------------------------------  */
BOOL c_fm_dlna_is_folder_changed(CHAR * ps_dir_name);

/*------------------------------------------------------------------------------  */
/*! 
 *
 *  @brief  Query if the media file can be paused when playing.
 *
 *  @param    [in] ps_dir_name - specify the dir name. It must be the full path.
 *
 *  @return TRUE or FALSE. Return TRUE if changed, otherwise return FALSE.
 */
/*------------------------------------------------------------------------------  */
BOOL c_fm_dlna_is_pause_supported(CHAR * ps_media_name);

/*------------------------------------------------------------------------------  */
/*! 
 *
 *  @brief Whether there are any dlna device attached.
 *
 *  @return TRUE or FALSE. If any return TRUE, otherwise return FALSE.
 */
/*------------------------------------------------------------------------------  */
BOOL c_fm_dlna_is_device_alive(VOID);

/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief    provides the outside to decode the filename if it has been encoded.
 *           sometimes, the filename may include some character invalid for FM, e.g. '/'.
 *           So dlnafs should encoded it and replace the '/' to other something and later the user calls
 *           this function to recover the real name.
 *
 * @note     this feature isn't used at this moment, because:
 *           1. this case is so frew.
 *           2. replace '/' wich '-' for easy won't fail the CTT(CTT doesn't care) and no any series shortcoming.
 *
 * @param   [in] ps_encoding_name - the original name got from dlnafs.
 * @param   [out] ps_out_name - the true name which should be truly shown.
 * @param   [out] pui4_out_len - the length of the ps_out_name.
 *
 * @return  return the error code.
 * @retval  0: SUCCESS, otherwise failed.
 */
/*------------------------------------------------------------------------------  */
INT32 c_fm_dlna_parse_display_title(CHAR *ps_encoding_name, CHAR *ps_out_name, UINT32 *pui4_out_len);

/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief    get dlna_dms device mac address
 * @param   [in] ps_filename - the dms file path in file system, eg:/mnt/usb/dlnadms_0/,the last "/" must be included.
 * @param   [out] pps_ip - the DMS mac addr,eg: "00:00:00:00:fe:0d".
 *
 * @return  return the error code.
 * @retval  0: SUCCESS, otherwise failed.
 */
/*------------------------------------------------------------------------------  */


INT32 c_fm_dlna_dmp_get_device_mac(CHAR * ps_filename, CHAR **pps_mac);

/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief    get dlna_dms device  name from device doc

 *
 * @param   [in] ps_filename - the dms file path in file system, eg:/mnt/usb/dlnadms_0/,the last "/" must be included.
 * @param   [out] pps_name - the DMS name.may be DMS name is empty string
 *
 * @return  return the error code.
 * @retval  0: SUCCESS, otherwise failed.
 */
/*------------------------------------------------------------------------------  */

INT32 c_fm_dlna_dmp_get_device_name(CHAR * ps_filename, CHAR **pps_name);
/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief    get dlna_dms device ip address
 * @param   [in] ps_filename - the dms file path in file system, eg:/mnt/usb/dlnadms_0/,the last "/" must be included.
 * @param   [out] pps_ip - the DMS ip addr,ip and port,eg: "172.28.17.42:2869".
 *
 * @return  return the error code.
 * @retval  0: SUCCESS, otherwise failed.
 */
/*------------------------------------------------------------------------------  */


INT32 c_fm_dlna_dmp_get_device_ip(CHAR * ps_filename, CHAR **pps_ip);



/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief    function for ap to callback icon data
 * @param  [in]device_arg  - DLNA_DMP_DEVICE_T or NULL
 * @param  [in]iconmtype  -  icon mimetype ,eg: "image/png", "image/bmp"
 * @param  [in]icondata   - tempbuffer for store icon data,malloc and free by mw,free after callback
 * @param  [in]iconlen     - the length of icon raw data
 * @param   arg  - for future use is  possible
 */
/*------------------------------------------------------------------------------  */

typedef INT32 (*x_dlna_dmp_get_device_icon_callback) (VOID *device_arg, 
									CHAR * iconmtype,
									CHAR * icondata,
									INT32 datalen, VOID *arg);




/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief    get dlna_dms device icon

 * @param   [in] ps_filename - the dms file path in file system, eg:/mnt/usb/dlnadms_0/,the last "/" must be included.
 * @param   [in]pf_readicon - AP callback function.
 * @param   
 * @return  return the error code.if device has no icon or get icon failed,the api will return  failed.
 * @retval  0: SUCCESS, otherwise failed.
 */
/*------------------------------------------------------------------------------  */

INT32 c_fm_dlna_dmp_get_device_icon(CHAR * ps_filename, x_dlna_dmp_get_device_icon_callback pf_readicon, VOID *arg);


/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief    get dlna_dms device udn
 * @param   [in] ps_filename - the dms file path in file system, eg:/mnt/usb/dlnadms_0/,the last "/" must be included.
 * @param   [out] pps_udn - the DMS udn. a udn eg:" uuid:13b01394-1de0-11b2-82db-00000000fe0d"
 *
 * @return  return the error code.
 * @retval  0: SUCCESS, otherwise failed.
 */
/*------------------------------------------------------------------------------  */


INT32 c_fm_dlna_dmp_get_device_udn(CHAR * ps_filename, CHAR **pps_udn);

/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief    check if device has given sort capability
 * @param   [in] ps_filename - the dms file path in file system, eg:/mnt/usb/dlnadms_0/,the last "/" must be included.
 *@param   [in]sort_string -sort string such as "dc:title" "dc:date".
 *  *
 * @return  
 * @retval  0: SUCCESS, means the device support the given sort method
 *@retval  DLNAR_INVAL : the input argument is not proper
 *@retval DLNAR_DMS_CANNOT_SUPPORT : device not support the given sort method
 */
/*------------------------------------------------------------------------------  */

INT32 c_fm_dlna_has_given_sort_capability(CHAR * ps_filename, CHAR *sort_string );

/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief    cancel browse or search action
 * @param   [in] ps_filename - the dms file path in file system, eg:/mnt/usb/dlnadms_0/,the last "/" must be included.
 *  *
 * @return  
 * @retval  0: SUCCESS, break browse or search connection success
  *@retval  DLNAR_DMP_FAIL: break connection failed because of dlnalib
   *@retval  DLNAR_DMP_INVALID_ARGUMENT: there is no connection need to break.
 */
/*------------------------------------------------------------------------------  */


INT32 c_fm_dlna_break(CHAR * ps_filename);

/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief    check if dlna is in a reading or browing date status from server
 * @param   
 *  *
 * @return  
 * @retval  TRUE:dlna is in a reading or browing
  *@retval  FALSE:dlna is not in reading or browing,it means there are no connections need to break from MW DLNA
 */
/*------------------------------------------------------------------------------  */

BOOL c_fm_dlna_is_inread(VOID);

/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief   check device is DMR or not
 * @param   [in] ps_filename - the file path in file system, eg:/mnt/usb/dlnadms_0/,the last "/" must be included.
 *
 * @retval  TRUE: devie is DMR.
 */
/*------------------------------------------------------------------------------  */
BOOL c_fm_dlna_is_DMR_device(CHAR* ps_filename);

/* This API should not be used. It is only for compatiable.
 * Please use c_fm_dlna_get_seek_type instead
 */
BOOL c_fm_dlna_is_seek_supported(CHAR * ps_media_name);


/*------------------------------------------------------------------------------  */
/*! 
 *
 * @brief   check multi-connection is supported by DLNA server or not
 * @param   [in] ps_filename - the file path in file system
 *
 * @retval  TRUE: Multi-connection is supported
 *
 * Because DMS won't told us if multi-connection is supported, the only way to judge is trying to setup multiple connection at the same time,
 * then check the result. If seek is not supported, we will also return FALSE.
 */
/*------------------------------------------------------------------------------  */
BOOL c_fm_dlna_is_multiconnection_supported(CHAR * ps_media_name);

/**
 * Get DLNA file seek type
 * There are two seek method in DLNA: Byte-based and Time-based seek
 * Byte-based seek: Seek offset is measured by byte - x_fm_lseek
 * Time-based seek: Seek offset is measured by time (second) - x_fm_dlna_time_seek
 * DLNA file may support only one of them or both of them
 *
 * @param h_file, file handle
 * @param pt_seek, seek ablity
 *
 * @return INT32
 * FMR_OK, ok
 * FMR_HANDLE, Fail to get the handle object.
*/

INT32 c_fm_dlna_get_seek_type(CHAR *ps_filename, DLNAFS_SEEK_CAP_T * pt_seek);

/**
 * Check if Connection-Stalling is supported for this file
 * if result is true, that is good, no need to do anything
 * if result is false, we need to close file handle during pause and slow forward operation, then open a new handle when resume
 *
 * @param ps_filepath, file full path
 * @param pb_stalling, result
 *
 * @return INT32
 * FMR_OK, ok
 * 
*/

INT32 c_fm_dlna_is_stalling_supported(const CHAR *ps_filepath, BOOL *pb_stalling);

/*! @}  */
#endif /* _C_FM_DLNAFS_H_ */
