/**
*@file    sr_ota.h
*@brief   ota组件接口
*@details 提供ota组件枚举、结构体
*@copyright Copyright (c) 2024 lierda. All rights reserved.
*@author  Lierda-RDC
*@date    2024-05-07
*@example ZhaoyangSDK\example\component\ota_example.c
*/

#ifndef _SR_OTA_H
#define _SR_OTA_H

#include "sr_stddef.h"
#include "sr_config.h"

#include "sr_net.h"

#include "sr_bsp_ota.h"


#if  0
typedef struct otaMng otaMng_t;

typedef void (*OtaResultCallback_t)(otaMng_t *otaMng,int result);


typedef struct otaOps
{
  int (*http_download)(otaMng_t *otaMng);
  int (*verify)(otaMng_t *otaMng);

}otaOps_t;


struct otaMng
{
	otaOps_t *ops;   
	char* uri;           //下载固件的URI地址
	char* falPartName;   //固件分区名称。OS_NUL表示使用内部默认分区
	uint32_t codeSize;   //待下载固件大小
	char* verifyCode;    //校验码
	
    OtaResultCallback_t resultCallback;

 
};



void OtaOpsRegister(otaOps_t *optOps);

int OtaFwDownloadHttp(otaMng_t *otaMng);

#endif








#define SR_OTA_VERIFY_MAX_LEN   32
#define SR_OTA_URL_MAX_LEN      128
#define SR_OTA_NAME_MAX_LEN     32

#define SR_OTA_FW_FILE_NAME_DEF   "ota_fw.bin"   /*!<默认固件保存的分区名*/ 
#define SR_OTA_FW_FLASH_NAME_DEF  "ota_save"     /*!<默认固件保存的文件名*/

typedef struct SR_OTA_MNG SR_OTA_MNG_T;


/**  
* @brief OTA固件存储接口类型
*/
typedef enum
{
  SR_OTA_STORE_FOTA = 1,    /*!<OpenCPU模组的FOTA接口*/
  SR_OTA_STORE_FLASH,       /*!<MCU的flash接口*/ 
  SR_OTA_STORE_FILESYS,     /*!<文件系统接口*/ 
  
}SR_OTA_STORE_E;


/**  
* @brief 升级协议类型
*/
typedef enum
{
  SR_OTA_PROTO_NULL = 0,  /*!<不支持*/ 
  SR_OTA_PROTO_HTTP = 1, /*!<http协议*/ 
  SR_OTA_PROTO_FTP,      /*!<ftp协议，预留*/ 
  SR_OTA_PROTO_YMODEM,   /*!<ymodem协议，预留*/ 

}SR_OTA_PROTO_E;  



#if  0
//OTA固件存储FLASH操作函数集
typedef struct SR_OTA_STORAGE_FLASH_OPS
{
  int (*before)(void);
  int (*write)(uint32_t offset,uint8_t buf, uint32_t bufSize);
  int (*read)(uint32_t offset,uint8_t buf, uint32_t bufSize);
  int (*after)(void);

}SR_OTA_FLASH_OPS_T;

//OTA固件存储文件系统操作函数集
typedef struct SR_OTA_STORAGE_FILE_OPS
{
  int (*before)(void);
  int (*write)(void *fd,uint8_t buf, uint32_t bufSize);
  int (*read)(void *fd,uint8_t buf, uint32_t bufSize);
  int (*after)(void);

}SR_OTA_FILE_OPS_T;

#endif

/**  
* @brief OTA事件类型枚举
*/
typedef enum
{
  SR_OTA_EVT_OK=0,   /*!<OTA下载并校验成功，可复位重启*/
  SR_OTA_EVT_FAIL,   /*!<OTA失败，原因为SR_OTA_STA_T*/
}SR_OTA_EVT_T;

/**  
* @brief OTA状态
*/
typedef enum
{
  SR_OTA_STA_NULL = 0,	   /*!<OTA初始状态*/
  SR_OTA_STA_INIT_FAIL,    /*!<OTA初始化失败*/
  SR_OTA_STA_DLDING,	   /*!<OTA下载中*/
  SR_OTA_STA_DLD_OK,       /*!<下载成功*/
  SR_OTA_STA_DLD_FAIL,     /*!<下载失败*/
  SR_OTA_STA_VRF_OK,	   /*!<校验成功*/
  SR_OTA_STA_VRF_FAIL,     /*!<校验失败*/
  SR_OTA_STA_STORE_FAIL,   /*!<存储接口错误*/
}SR_OTA_STA_T;


/**  
 * @brief OTA事件通知回调函数类型  
 *    
 * @param[in] event   OTA事件类型
 * @param[in] status  OTA当前状态
 *
 * @return  无
 * @note    回调函数的具体实现由调用者提供，用于响应OTA过程中的各种事件。  
 */
typedef void (*OtaEventCb)(SR_OTA_EVT_T event,SR_OTA_STA_T status);

/**  
 * @brief OTA校验函数类型定义 
 * 若升级包在文件系统且有效，函数将文件从文件系统写入到ota分区，并完成校验
 * 若升级包已在文ota分区，直接校验
 *
 * @param[in] otaMng OTA管理器的指针，包含OTA相关的信息。   
 *         
 * @return 校验成功返回0，若无效或者校验失败，则返回负值错误码。  
 */
typedef int (*OtaVerify)(SR_OTA_MNG_T *otaMng);

/**  
* @brief OTA初始初始化参数结构体
*/
typedef struct SR_OTA_INIT_PARAMS
{
	SR_OTA_PROTO_E  proteType;			/*!<下载协议类型*/
	SR_OTA_STORE_E  storeType;          /*!<固件存储接口类型*/
	uint32_t fwSize;                    /*!<待下载固件大小 */
	char *url;                          /*!<下载固件的URI地址*/
	char *storeName;                    /*!<固件存储时使用的分区或文件名称*/
	char *verifyCode;                   /*!<固件校验码*/ 
	char *netAdpName;                   /*!<网络适配器名称*/ 
}SR_OTA_INIT_PARAMS_T;


/**  
* @brief OTA管理器结构体
*/
struct SR_OTA_MNG
{
  ///SR_OTA_FILE_OPS_T  *fileOps;     /*!<固件存储接口:文件系统*/
  ///SR_OTA_FLASH_OPS_T *flashOps;    /*!<固件存储接口：flash*/
  ///SR_OTA_FLASH_OPS_T *fotaOps;     /*!<固件存储接口：模组fota*/
  OtaVerify verify;                        /*!<校验接口*/
  OtaEventCb evtCb;                        /*!<OTA事件通知回调*/
  void *evtCbArgs;                         /*!<OTA事件通知回调的参数*/
  SR_NET_ADP_T *netAdp;                    /*!<网络适配器*/
  uint32_t fwSize;                         /*!<待下载固件大小*/
  SR_OTA_STORE_E   storeType;    		   /*!<固件存储接口类型*/ 
  SR_OTA_PROTO_E   protoType;              /*!<升级协议类型*/ 
  SR_OTA_STA_T     status;                 /*!<OTA状态*/ 
  char url[SR_OTA_URL_MAX_LEN];            /*!<下载固件的URI地址*/
  char storeName[SR_OTA_NAME_MAX_LEN];     /*!<固件存储时使用的分区或文件名称。空表示使用内部默认分区和文件名*/
  char verifyCode[SR_OTA_VERIFY_MAX_LEN];  /*!<固件校验码*/ 
 
};


#define _FotaBefore()   BspFotaBefore()
#define _Fotawrite(offset,buf,bufSize) BspFotawrite(offset,buf,bufSize)
#define _FotaAfter()    BspFotaAfter()




/****************************抽象接口*******************************************/
/**  
* @brief OTA固件下载初始化
*   
* @param[in] params 初始化参数结构体指针
*   
* @return 成功返回0，失败返回负值错误码  
*/  
int SR_OtaFwDownloadInit(SR_OTA_INIT_PARAMS_T *params);


/**  
* @brief 启动OTA固件异步下载
*   
* @return 成功返回0，失败返回负值错误码  
*/ 
int SR_OtaFwDownloadAsync(void);



/**  
* @brief 设置OTA事件回调函数
*   
* @param[in] cb 事件回调函数指针
* @param[in] args 回调函数参数指针
*   
* @return 成功返回0，失败返回负值错误码  
*/ 
int SR_OtaSetEventCb(OtaEventCb cb,void *args);



#endif

