pinebuds/services/ibrt_ota/inc/ota_control.h

427 lines
13 KiB
C

#ifndef _OTA_CONTROL_H_
#define _OTA_CONTROL_H_
#include "co_bt_defines.h"
#define LOG_TAG "[OTA_CONTROL] "
#define OTA_BES_CONTROL_DEBUG
#ifdef OTA_BES_CONTROL_DEBUG
#define LOG_DBG(num,str,...) TRACE(num,LOG_TAG""str, ##__VA_ARGS__) // DEBUG OUTPUT
#define LOG_MSG(num,str,...) TRACE(num,LOG_TAG""str, ##__VA_ARGS__) // MESSAGE OUTPUT
#define LOG_ERR(num,str,...) TRACE(num,LOG_TAG"err:"""str, ##__VA_ARGS__) // ERROR OUTPUT
#define LOG_FUNC_LINE() TRACE(2,LOG_TAG"%s:%d\n", __FUNCTION__, __LINE__)
#define LOG_FUNC_IN() TRACE(1,LOG_TAG"%s ++++\n", __FUNCTION__)
#define LOG_FUNC_OUT() TRACE(1,LOG_TAG"%s ----\n", __FUNCTION__)
#define LOG_DUMP DUMP8
#else
#define LOG_DBG(num,str,...)
#define LOG_MSG(num,str,...) TRACE(num,LOG_TAG""str, ##__VA_ARGS__)
#define LOG_ERR(num,str,...) TRACE(num,LOG_TAG"err:"""str, ##__VA_ARGS__)
#define LOG_FUNC_LINE()
#define LOG_FUNC_IN()
#define LOG_FUNC_OUT()
#define LOG_DUMP
#endif
#define ERASE_LEN_UNIT 4096
#define OTA_SW_VERSION 1
#define OTA_HW_VERSION 1
#define DATA_PATH_BLE 1
#define DATA_PATH_SPP 2
#ifndef NORMAL_BOOT
#define NORMAL_BOOT 0xBE57EC1C
#endif
#ifndef COPY_NEW_IMAGE
#define COPY_NEW_IMAGE 0x5a5a5a5a
#endif
#define OTA_TWS_INFO_SIZE 128
#define OTA_BUF_SIZE 1024
#define OTA_WATCH_DOG_PING_TIMER_ID 0
#ifndef NEW_IMAGE_FLASH_OFFSET
#define NEW_IMAGE_FLASH_OFFSET 0x180000
#endif
#define OTA_FLASH_LOGIC_ADDR (FLASH_NC_BASE)
#define DATA_ACK_FOR_SPP_DATAPATH_ENABLED 1
#define PUYA_FLASH_ERASE_LIMIT 0
#define OTA_RS_INFO_MASTER_SEND_RS_REQ_CMD 1
#define OTA_RS_INFO_MASTER_DISCONECT_CMD 2
#define OTAUPLOG_HEADSIZE (sizeof(otaUpgradeLog.randomCode) + sizeof(otaUpgradeLog.totalImageSize) + sizeof(otaUpgradeLog.crc32OfImage))
#define FLASH_SECTOR_SIZE_IN_BYTES 4096
#define OTA_OFFSET 0x1000
#define OTA_INFO_IN_OTA_BOOT_SEC (FLASHX_BASE+OTA_OFFSET)
#define OTA_DATA_BUFFER_SIZE_FOR_BURNING FLASH_SECTOR_SIZE_IN_BYTES
#define BES_OTA_START_MAGIC_CODE 0x54534542 // BEST
#define BES_OTA_NAME_LENGTH 32
#define BES_OTA_BLE_DATA_PACKET_MAX_SIZE 512
#define BES_OTA_BT_DATA_PACKET_MAX_SIZE L2CAP_MTU
#define IMAGE_RECV_FLASH_CHECK 1 // It's best to turn it on durning development and not a big deal off in the release.
#define MAX_IMAGE_SIZE ((uint32_t)(NEW_IMAGE_FLASH_OFFSET - __APP_IMAGE_FLASH_OFFSET__))
#define MIN_SEG_ALIGN 256
typedef void (*ota_transmit_data_t)(uint8_t* ptrData, uint32_t dataLen);
typedef void (*ota_transmission_done_t)(void);
enum
{
OTA_RESULT_ERR_RECV_SIZE = 2,
OTA_RESULT_ERR_FLASH_OFFSET,
OTA_RESULT_ERR_SEG_VERIFY,
OTA_RESULT_ERR_BREAKPOINT,
OTA_RESULT_ERR_IMAGE_SIZE,
};
/**
* @brief The format of the start OTA control packet
*
*/
typedef struct
{
uint8_t packetType; // should be OTA_COMMAND_START
uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE
uint32_t imageSize; // total image size
uint32_t crc32OfImage; // crc32 of the whole image
} __attribute__ ((__packed__)) OTA_CONTROL_START_T;
/**
* @brief The format of the start OTA response packet
*
*/
typedef struct
{
uint8_t packetType; // should be OTA_RSP_START
uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE
uint16_t swVersion;
uint16_t hwVersion;
uint16_t MTU; // MTU exchange result, central will send images in the unit of MTU
} __attribute__ ((__packed__)) OTA_START_RSP_T;
typedef struct
{
uint32_t lengthOfFollowingData;
uint32_t startLocationToWriteImage; // the offset of the flash to start writing the image
uint32_t isToClearUserData : 1;
uint32_t isToRenameBT : 1;
uint32_t isToRenameBLE : 1;
uint32_t isToUpdateBTAddr : 1;
uint32_t isToUpdateBLEAddr : 1;
uint32_t reserve : 27;
uint8_t newBTName[BES_OTA_NAME_LENGTH];
uint8_t newBLEName[BES_OTA_NAME_LENGTH];
uint8_t newBTAddr[BD_ADDR_LEN];
uint8_t newBLEAddr[BD_ADDR_LEN];
uint32_t crcOfConfiguration; // CRC of data from lengthOfFollowingData to newBLEAddr
} __attribute__ ((__packed__)) OTA_FLOW_CONFIGURATION_T;
/**
* @brief The format of the start OTA control packet
*
*/
typedef struct
{
uint8_t packetType; // should be OTA_COMMAND_CONFIG_OTA
OTA_FLOW_CONFIGURATION_T config;
} __attribute__ ((__packed__)) OTA_COMMAND_CONFIG_T;
/**
* @brief The format of the OTA configuration response packet
*
*/
typedef struct
{
uint8_t packetType; // should be OTA_RSP_CONFIG
uint8_t isConfigurationDone; // 1 if the configuration has been done successfully, otherwise, 0
} __attribute__ ((__packed__)) OTA_RSP_CONFIG_T;
/**
* @brief The format of the segment verification request
*
*/
typedef struct
{
uint8_t packetType; // should be OTA_COMMAND_SEGMENT_VERIFY
uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE
uint32_t crc32OfSegment; // crc32 of the 1% segment
} __attribute__ ((__packed__)) OTA_CONTROL_SEGMENT_VERIFY_T;
/**
* @brief The format of the segment verification request
*
*/
typedef struct
{
uint8_t packetType; // should be OTA_RSP_SEGMENT_VERIFY
uint8_t isVerificationPassed;
} __attribute__ ((__packed__)) OTA_RSP_SEGMENT_VERIFY_T;
/**
* @brief The format of the OTA result response
*
*/
typedef struct
{
uint8_t packetType; // should be OTA_RSP_RESULT
uint8_t isVerificationPassed;
} __attribute__ ((__packed__)) OTA_RSP_OTA_RESULT_T;
/**
* @brief The format of the OTA reading flash content command
*
*/
typedef struct
{
uint8_t packetType; // should be OTA_READ_FLASH_CONTENT
uint8_t isToStart; // true to start, false to stop
uint32_t startAddr;
uint32_t lengthToRead;
} __attribute__ ((__packed__)) OTA_READ_FLASH_CONTENT_REQ_T;
/**
* @brief The format of the OTA reading flash content command
*
*/
typedef struct
{
uint8_t packetType; // should be OTA_READ_FLASH_CONTENT
uint8_t isReadingReqHandledSuccessfully;
} __attribute__ ((__packed__)) OTA_READ_FLASH_CONTENT_RSP_T;
typedef struct
{
uint8_t packetType; // should be OTA_CONTROL_RESUME_VERIFY
uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE
uint8_t randomCode[32];
uint32_t segmentSize;
uint32_t crc32; // CRC32 of randomCode and segment size
} __attribute__ ((__packed__)) OTA_CONTROL_RESUME_VERIFY_T;
typedef struct
{
uint8_t packetType; // should be OTA_RSP_RESUME_VERIFY
uint32_t breakPoint;
uint8_t randomCode[32];
uint32_t crc32; // CRC32 of breakPoint and randomCode
} __attribute__ ((__packed__)) OTA_RSP_RESUME_VERIFY_T;
typedef struct
{
uint8_t packetType; // should be
uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE
} __attribute__ ((__packed__)) OTA_GET_VERSION_REQ_T;
typedef struct
{
uint8_t packetType; // should be
uint32_t magicCode;
uint8_t deviceType;
uint8_t leftVersion[4]; //or stereo version
uint8_t rightVersion[4]; //stereo not needed
} __attribute__ ((__packed__)) OTA_RSP_OTA_VERSION_T;
typedef struct
{
uint8_t packetType; // should be
uint8_t success;
} __attribute__ ((__packed__)) OTA_RSP_SELECTION_T;
typedef struct
{
uint8_t packetType; // should be
uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE
} __attribute__ ((__packed__)) OTA_FORCE_REBOOT_T;
typedef struct
{
uint8_t packetType; // should be
uint32_t magicCode; // should be BES_OTA_START_MAGIC_CODE
} __attribute__ ((__packed__)) OTA_IMAGE_APPLY_REQ_T;
typedef struct
{
uint8_t packetType; // should be
uint8_t success;
} __attribute__ ((__packed__)) OTA_RSP_APPLY_T;
typedef struct
{
uint8_t packetType;
} __attribute__ ((__packed__)) OTA_START_ROLE_SWITCH_T;
typedef struct
{
uint8_t packetType;
} __attribute__ ((__packed__)) OTA_ROLE_SWITCH_COMPLETE_T;
/**
* @brief The OTA handling data structure
*
*/
typedef struct
{
uint8_t* dataBufferForBurning;
uint32_t dstFlashOffsetForNewImage;
uint32_t offsetInDataBufferForBurning;
uint32_t offsetInFlashToProgram;
uint32_t totalImageSize;
uint32_t alreadyReceivedDataSizeOfImage;
uint32_t offsetInFlashOfCurrentSegment;
uint32_t offsetOfImageOfCurrentSegment;
uint32_t crc32OfImage;
uint32_t crc32OfSegment;
uint8_t isOTAInProgress;
uint8_t isPendingForReboot;
uint32_t flasehOffsetOfUserDataPool;
uint32_t flasehOffsetOfFactoryDataPool;
// configuration of the OTA
OTA_FLOW_CONFIGURATION_T configuration;
uint32_t AlreadyReceivedConfigurationLength;
uint16_t dataPacketSize;
ota_transmit_data_t transmitHander;
uint32_t offsetInFlashToRead;
uint32_t leftSizeOfFlashContentToRead;
uint8_t dataPathType;
bool resume_at_breakpoint;
uint32_t breakPoint;
uint32_t i_log;
} OTA_CONTROL_ENV_T;
typedef struct
{
uint32_t magicNumber; // NORMAL_BOOT or COPY_NEW_IMAGE
uint32_t imageSize;
uint32_t imageCrc;
} FLASH_OTA_BOOT_INFO_T;
typedef struct
{
uint8_t randomCode[32];
uint32_t totalImageSize;
uint32_t crc32OfImage;
uint32_t upgradeSize[(ERASE_LEN_UNIT - 32 - 2*sizeof(uint32_t)) / 4];
}FLASH_OTA_UPGRADE_LOG_FLASH_T;
/**
* @brief The control packet type
*
*/
typedef enum
{
OTA_COMMAND_START = 0x80, // from central to device, to let OTA start
OTA_RSP_START, // from device to centrl, to let it know that it has been ready for OTA
OTA_COMMAND_SEGMENT_VERIFY, // from central to device, sent per 1% of image, inform device to do CRC check on those 1%
OTA_RSP_SEGMENT_VERIFY,
OTA_RSP_RESULT,
OTA_DATA_PACKET,
OTA_COMMAND_CONFIG_OTA, // from central to device, to configure the following OTA flow
OTA_RSP_CONFIG,
OTA_COMMAND_GET_OTA_RESULT,
OTA_READ_FLASH_CONTENT,
OTA_FLASH_CONTENT_DATA = 0x8A,
OTA_DATA_ACK,
OTA_COMMAND_RESUME_VERIFY,
OTA_RSP_RESUME_VERIFY,
OTA_COMMAND_GET_VERSION,
OTA_RSP_VERSION,
OTA_COMMAND_SIDE_SELECTION = 0x90,
OTA_RSP_SIDE_SELECTION,
OTA_COMMAND_IMAGE_APPLY,
OTA_RSP_IMAGE_APPLY,
OTA_RSP_START_ROLE_SWITCH = 0x95,
OTA_RSP_ROLE_SWITCH_COMPLETE,
} OTA_CONTROL_PACKET_TYPE_E;
typedef struct
{
uint8_t typeCode;
uint16_t rsp_seq;
uint16_t length;
uint8_t p_buff[OTA_TWS_INFO_SIZE];
}OTA_IBRT_TWS_CMD_EXECUTED_RESULT_FROM_SLAVE_T;
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Format of the data xfer handler function, to send data to central
*
* @param ptrData Pointer of the data to send
* @param dataLen Length of the data to send
*
*/
extern void app_ibrt_ota_segment_crc_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length);
extern void app_ibrt_ota_start_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length);
extern void app_ibrt_ota_config_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length);
extern void app_ibrt_ota_image_crc_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length);
extern void app_ibrt_ota_get_version_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length);
extern void app_ibrt_ota_select_side_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length);
extern void app_ibrt_ota_image_overwrite_cmd_send_handler(uint16_t rsp_seq, uint8_t *p_buff, uint16_t length);
void ota_control_register_transmitter(ota_transmit_data_t transmit_handle);
void ota_control_update_MTU(uint16_t mtu);
void ota_update_info(void);
void ota_check_and_reboot_to_use_new_image(void);
void ota_control_reset_env(void);
void ota_execute_the_final_operation(void);
bool ota_is_in_progress(void);
void ota_control_set_datapath_type(uint8_t datapathType);
void ibrt_ota_send_start_response(bool isViaBle);
void ibrt_ota_send_configuration_response(bool isDone);
void ota_control_image_apply_rsp(uint8_t success);
void ibrt_ota_send_segment_verification_response(bool isPass);
void ibrt_ota_send_result_response(uint8_t isSuccessful);
void ota_randomCode_log(uint8_t randomCode[]);
void ota_control_send_resume_response(uint32_t breakPoint, uint8_t randomCode[]);
void ota_bes_handle_received_data(uint8_t *otaBuf, bool isViaBle,uint16_t dataLenth);
void ota_ibrt_handle_received_data(uint8_t *otaBuf, bool isViaBle, uint16_t len);
void ota_control_side_selection_rsp(uint8_t success);
uint8_t ota_control_get_datapath_type(void);
uint32_t app_get_magic_number(void);
void ota_flash_init(void);
void Bes_exit_ota_state(void);
void ibrt_ota_send_version_rsp(void);
void ota_upgradeLog_destroy(void);
void ota_status_change(bool status);
void ota_control_send_start_role_switch(void);
void ota_control_send_role_switch_complete(void);
uint8_t app_get_bes_ota_state(void);
bool app_check_is_ota_role_switch_initiator(void);
void app_set_ota_role_switch_initiator(bool is_initiate);
void bes_ota_send_role_switch_req(void);
void app_statistics_get_ota_pkt_in_role_switch(void);
bool app_check_user_can_role_switch_in_ota(void);
#ifdef __cplusplus
}
#endif
#endif