/**
 *****************************************************************************************
 *	@file etn_mesh_fota_blb.h
 *
 *	@brief eaton ble mesh fota blob transfer model header file
 *
 *	@details this custom model from eaton, used to transfer binary large object from client to server. 
 *
 *	@version C Style Guide Version 1.0
 *
 *	@copyright 2022 Eaton Corporation. All Rights Reserved.
 *
 *****************************************************************************************
 */
#ifndef ETN_MESH_FOTA_BLB_H
#define ETN_MESH_FOTA_BLB_H

/*
 *****************************************************************************************
 *		Headers
 *****************************************************************************************
 */
#include <bluetooth/mesh/model_types.h>
#include <etn_mesh_fota.h>
#include <etn_mesh_fota_blb.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 *****************************************************************************************
 *		Opcodes for eaton mesh fota blob transfer
 *****************************************************************************************
 */

#define BT_MESH_ETN_FOTA_BLB_TRANS_GET_OP        BT_MESH_MODEL_OP_3( 0x11, BT_MESH_COMPANY_ID_EATON )
#define BT_MESH_ETN_FOTA_BLB_TRANS_START_OP      BT_MESH_MODEL_OP_3( 0x12, BT_MESH_COMPANY_ID_EATON )
#define BT_MESH_ETN_FOTA_BLB_TRANS_CANCEL_OP     BT_MESH_MODEL_OP_3( 0x13, BT_MESH_COMPANY_ID_EATON )
#define BT_MESH_ETN_FOTA_BLB_TRANS_STATUS_OP     BT_MESH_MODEL_OP_3( 0x14, BT_MESH_COMPANY_ID_EATON )
#define BT_MESH_ETN_FOTA_BLB_BLOCK_GET_OP        BT_MESH_MODEL_OP_3( 0x15, BT_MESH_COMPANY_ID_EATON )
#define BT_MESH_ETN_FOTA_BLB_BLOCK_START_OP      BT_MESH_MODEL_OP_3( 0x16, BT_MESH_COMPANY_ID_EATON )
#define BT_MESH_ETN_FOTA_BLB_BLOCK_STATUS_OP     BT_MESH_MODEL_OP_3( 0x17, BT_MESH_COMPANY_ID_EATON )
#define BT_MESH_ETN_FOTA_BLB_BLOCK_PRL_RPT_OP    BT_MESH_MODEL_OP_3( 0x18, BT_MESH_COMPANY_ID_EATON )
#define BT_MESH_ETN_FOTA_BLB_CHUNK_TRANS_OP      BT_MESH_MODEL_OP_3( 0x19, BT_MESH_COMPANY_ID_EATON )
#define BT_MESH_ETN_FOTA_BLB_INFO_GET_OP         BT_MESH_MODEL_OP_3( 0x1A, BT_MESH_COMPANY_ID_EATON )
#define BT_MESH_ETN_FOTA_BLB_INFO_STATUS_OP      BT_MESH_MODEL_OP_3( 0x1B, BT_MESH_COMPANY_ID_EATON )

#define BT_MESH_ETN_FOTA_BLB_REBOOT_REQ_OP       BT_MESH_MODEL_OP_3( 0x1C, BT_MESH_COMPANY_ID_EATON )

#define BT_MESH_ETN_FOTA_BLB_TRANS_GET_MSG_MINLEN       1
#define BT_MESH_ETN_FOTA_BLB_TRANS_START_MSG_MINLEN     sizeof( struct fota_blb_trans_start )
#define BT_MESH_ETN_FOTA_BLB_TRANS_CANCEL_MSG_MINLEN    1
#define BT_MESH_ETN_FOTA_BLB_TRANS_STATUS_MSG_MINLEN    sizeof( struct fota_blb_trans_status )

#define BT_MESH_ETN_FOTA_BLB_BLOCK_GET_MSG_MINLEN       1
#define BT_MESH_ETN_FOTA_BLB_BLOCK_START_MSG_MINLEN     sizeof( struct fota_blb_block_start )
#define BT_MESH_ETN_FOTA_BLB_BLOCK_STATUS_MSG_MINLEN    sizeof( struct fota_blb_block_status )
#define BT_MESH_ETN_FOTA_BLB_BLOCK_PRL_RPT_MSG_MINLEN   sizeof( struct fota_blb_block_prtl_rpt )   
#define BT_MESH_ETN_FOTA_BLB_CHUNK_TRANS_MSG_MINLEN     sizeof( struct fota_blb_chunk_transfer )

#define BT_MESH_ETN_FOTA_BLB_INFO_GET_MSG_MINLEN        1
#define BT_MESH_ETN_FOTA_BLB_INFO_STATUS_MSG_MINLEN     sizeof( struct fota_blb_info_status )

#define BT_MESH_ETN_FOTA_BLB_REBOOT_REQ_MSG_MINLEN          1

#define BT_MESH_ETN_FOTA_BLB_FLASH_MAX_DATA_SIZE        128

/*
#define MAX_BLOB_SIZE_IN_BYTES     2048
#define MAX_BLOCK_SIZE_IN_BYTES    512
 
#define MAX_BLOCKS_IN_BLOB      4
#define MAX_CHUNK_IN_BLOCK      4
*/


#define MAX_BLOB_SIZE_IN_BYTES     32768
#define MAX_BLOCK_SIZE_IN_BYTES    2048
 
#define MAX_BLOCKS_IN_BLOB      16
#define MAX_CHUNK_IN_BLOCK      16


/*
 *****************************************************************************************
 *		Constants
 *****************************************************************************************
 */


/*
 *****************************************************************************************
 *		Variables
 *****************************************************************************************PLAT
 */

/*
 *****************************************************************************************
 *		Structures
 *****************************************************************************************
 */

enum fota_blb_trans_curr_state{
    BLB_SRV_CURR_STATE_BLB_NONE,
    BLB_SRV_CURR_STATE_BLB_TRANS_START,
    BLB_SRV_CURR_STATE_BLB_TRANS_PROGRESS,
    BLB_SRV_CURR_STATE_BLB_TRANS_COMPLETED,
    BLB_SRV_CURR_STATE_BLB_TRANS_CANCELLED
};

enum fota_blb_block_curr_state{
    BLB_SRV_CURR_STATE_BLOCK_NONE,
    BLB_SRV_CURR_STATE_BLOCK_START,
    BLB_SRV_CURR_STATE_BLOCK_PROGRESS,
    BLB_SRV_CURR_STATE_BLOCK_COMPLETED,
    BLB_SRV_CURR_STATE_BLOCK_CANCELLED
};

struct fota_blb_current_values{
    enum fota_blb_trans_curr_state blb_trans_state ;
    enum fota_blb_block_curr_state block_state ;
    uint64_t blob_id;
    uint16_t block_number;
    uint16_t block_chunk_start;
    uint16_t chunk_number;
    uint8_t  block_chunk_counter;
    uint16_t missing_chunks;
    uint16_t expected_blocks;
    uint64_t expected_fw_size;
    uint64_t received_fw_size;
    uint16_t user_id;
}__packed;

struct fota_blb_data_flash {
    uint16_t chunk_number;
    uint32_t address;
    uint32_t length;
    uint8_t  data[BT_MESH_ETN_FOTA_BLB_FLASH_MAX_DATA_SIZE];
} __packed;

struct fota_blb_trans_start {
	uint8_t rfu;
    uint8_t trans_mode;
    uint64_t blob_id;
    uint32_t blob_size;
    uint8_t  block_size_log;
    uint16_t cli_mtu_size;
} __packed;

struct fota_blb_trans_status {
	uint8_t status;
    uint8_t rfu;
    uint8_t trans_mode;
    uint8_t trans_phase;
    uint64_t blob_id;
    uint32_t blob_size;
    uint8_t  block_size_log;
    uint16_t trans_mtu_size;
    uint16_t block_not_recvd;
} __packed;

enum fota_blb_trans_status_code {
    TRANS_ALL_CHUNKS_MISSING=0,
    TRANS_NO_MISSING_CHUNKS,
    TRANS_SOME_CHUNKS_MISSING,
    TRANS_ENCODE_CHUNKS_MISSING
};

struct fota_blb_block_start {
	uint16_t block_number;
    uint16_t chunk_size;
} __packed;

struct fota_blb_block_status {
	uint8_t status;
    uint8_t rfu;
    uint8_t format;
    uint16_t block_number;
    uint16_t chunk_size;
    uint16_t missing_chunks;
    uint16_t encoded_missing_chunks;
} __packed;

enum fota_blb_block_status_code {
    BLOCK_ALL_CHUNKS_MISSING=0,
    BLOCK_NO_MISSING_CHUNKS,
    BLOCK_SOME_CHUNKS_MISSING,
    BLOCK_ENCODE_CHUNKS_MISSING
};

struct fota_blb_block_prtl_rpt {
    uint16_t encoded_missing_chunks;
} __packed;

struct fota_blb_chunk_transfer {
    uint16_t chunk_number;
    uint8_t  chunk_data[BT_MESH_FOTA_MAX_BYTE_TRANSFER - 2];
} __packed;

struct fota_blb_info_status {
    uint8_t min_block_size_log;
    uint8_t max_block_size_log;
    uint16_t max_total_chunks;
    uint16_t max_chunk_size;
    uint32_t max_blob_size;
    uint16_t server_mtu_size;
    uint8_t  supported_trans_mode;
} __packed;

enum fota_blb_blob_state {
    BLOB_STATE_BLOB_ID=0,
    BLOB_STATE_BLOB_SIZE,
    BLOB_STATE_BLOCK_SIZE_LOG,
    BLOB_STATE_BLOB_DATA,
    BLOB_STATE_TOTAL_BLOCKS
};

enum fota_blb_block_state {
    BLOCK_STATE_NUMBER=0,
    BLOCK_STATE_CURRENT_BLOCK_SIZE,
    BLOCK_STATE_CHUNK_SIZE,
    BLOCK_STATE_TOTAL_CHUNK,
    BLOCK_STATE_BLOCK_DATA
};

enum fota_blb_transfer_state {
    TRANSFER_STATE_PHASE=0,
    TRANSFER_STATE_EXPECTED_BLOB_ID,
    TRANSFER_STATE_BLOCKS_NOT_RECVD,
    TRANSFER_STATE_MISSING_CHUNKS,
    TRANSFER_STATE_CLI_MTU_SIZE,
    TRANSFER_STATE_SERVER_TIMEOUT_BASE,
    TRANSFER_STATE_CAPABILITIES
};

enum fota_blb_capability_state {
    CAPABILITY_STATE_MIN_BLOCK_SIZE_LOG=0,
    CAPABILITY_STATE_MAX_BLOCK_SIZE_LOG,
    CAPABILITY_STATE_MAX_TOTAL_CHUNK,
    CAPABILITY_STATE_MAX_CHUNK_SIZE,
    CAPABILITY_STATE_MAX_BLOB_SIZE,
    CAPABILITY_STATE_SRV_MTU_SIZE,
    CAPABILITY_STATE_TRANS_MODE
};

enum fota_blb_transfer_phase_code {
    INACTIVE=0,
    WAITING_FOR_START,
    WAITING_FOR_NEXT_BLOCK,
    WAITING_FOR_NEXT_CHUNK,
    COMPLETE,
    SUSPENDED,
    /* new added */
    CANCELLED
};

enum fota_blb_transfer_status_code {
    SUCCESS=0,
    INVALID_BLOCK_NUMBER,
    INVALID_BLOCK_SIZE,
    INVALID_CHUNK_SIZE,
    WRONG_PHASE,
    INVALID_PARAMETER,
    WRONG_BLOB_ID,
    BLOB_TOO_LARGE,
    UNSUPPORTED_TRANSFER_MODE,
    INTERNAL_ERROR,
    INFORMATION_UNAVAILABLE,
    /* new added */
    WRONG_BLOB_STATE,
    BLOB_TRANSFER_CANCELLED,
    WRONG_BLOCK_STATE, 
    WRONG_CHUNK_NUMBER,
    WRONG_CHUNK_NUM_IN_BLOCK,
};

enum fota_blb_transfer_mode{
    TRANSFER_MODE_PUSH=0,
    TRANSFER_MODE_PULL
};



/**
 * @brief function name
 * @param[in] param
 * @return return
 */

#ifdef __cplusplus
}
#endif

#endif