mcu_hi3321_watch/tjd/ble/ble_protocol_ota_service.c
2025-05-26 20:15:20 +08:00

256 lines
9.7 KiB
C

/*----------------------------------------------------------------------------
* Copyright (c) Fenda Technologies Co., Ltd. 2022. All rights reserved.
*
* Description: ble_protocol_ota_service.c
*
* Author: saimen
*
* Create: 2024-12-13
*--------------------------------------------------------------------------*/
#include "ble_port_protocol.h"
#include "ble_api.h"
#include "ble_port.h"
#include "bts_br_gap.h"
#include "bts_gatt_server.h"
#include "bts_le_gap.h"
#include "ctype.h"
#include "osal_addr.h"
#include "rtc_api.h"
#include "securec.h"
#include "sql_all.h"
#include "stdlib.h"
#include "string.h"
#include "sys_config.h"
#include "sys_typedef.h"
#include "time.h"
// #include "TjdUiMessagePopUpPage.h"
#include "fcntl.h"
#include "fs_api_ext.h"
#include "fs_user_common.h"
#include "linux/crc32.h"
#include "los_ringbuf.h"
#include "sys/statfs.h"
#include "unistd.h"
#include <sys/stat.h>
#include "power_display_service.h"
#include "service_bt.h"
#include "thread_init.h"
// #include "semaphore.h"
#include "upg_porting.h"
#include "osal_task.h"
#include "osal_semaphore.h"
#include "soc_osal.h"
#include <dirent.h>
#include "broadcast_feature.h"
#include "ble_protocol_file_download.h"
#include "ble_protocol_ota_service.h"
#define ENABLE_STATIC_PRINT 0
#define static_print_error(...) sys_bt_log_e(__VA_ARGS__) //错误信息打印一般常开
#define static_print_warn(...) sys_bt_log_w(__VA_ARGS__) //警告信息打印一般常开
#if ENABLE_STATIC_PRINT
#define static_print_debug(...) sys_bt_log_d(__VA_ARGS__)
#define static_print_info(...) sys_bt_log_i(__VA_ARGS__)
#else
#define static_print_debug(...)
#define static_print_info(...)
#endif
static uint8_t g_ota_send_data_mask = 0; // ota发送数据标志位
static uint32_t g_ota_firmware_file_size = 0;
static bool g_ota_start_flag = false;
static ota_schedule_callback_t g_ota_schedule_callback = NULL;
extern DirDescriptionInfo_t *tjd_ble_get_dir_description(void);
extern FileTransferInfo_t *tjd_ble_get_transfer_info(void);
uint32_t tjd_ota_get_fimrware_size(void) { return g_ota_firmware_file_size; }
void tjd_ota_set_fimrware_size(uint32_t fileSize) { g_ota_firmware_file_size = fileSize; }
void register_ota_schedule_callback(ota_schedule_callback_t callback) { g_ota_schedule_callback = callback; }
void unregister_ota_schedule_callback(void) { g_ota_schedule_callback = NULL; }
void tjd_ota_breakpoint_callback(void)
{
tjd_ble_file_breakpoint_save();
if(g_ota_send_data_mask == true){
g_ota_send_data_mask = false;
tjd_show_ota_interrupt_view();
const power_display_svr_api_t *display_api = power_display_svr_get_api();
errcode_t ret = display_api->set_screen_set_keepon_timeout(0);
if(ret != ERRCODE_SUCC){
static_print_error("set_screen_set_keepon_timeout 0 fail! ret : %x" , ret);
}
ret =display_api->set_auto_timeout_function(true);
if(ret != ERRCODE_SUCC){
static_print_error("set_auto_timeout_function true fail! ret : %x" , ret);
}
ret = display_api->set_screen_set_keepon_timeout(5000);
if(ret != ERRCODE_SUCC){
static_print_error("set_screen_set_keepon_timeout 5000 fail! ret : %x" , ret);
}
}
}
void tjd_ota_upgrade_operation(void)
{
uint8_t data[] = {0x01};
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), DOWNLOAD_FILE_END_DATA, gatt_server_id,g_server_conn_id);
// #ifdef SUPPORT_RECOVERY_DISPLAY
// recovery_display_init();
// recovery_display_sample();
// #endif
uint32_t packsize_= g_ota_firmware_file_size;
g_ota_firmware_file_size = 0;
upg_prepare_info_t prepare_info = {
.package_len = packsize_
};
// prepare_info.package_len = packsize_;
static_print_debug("%s , line is %d ,prepare_info.package_len = %d , packsize_ = %d", __FUNCTION__, __LINE__, prepare_info.package_len,packsize_);
if(prepare_info.package_len != 0){
errcode_t ret = uapi_upg_prepare(&prepare_info);
if(ret != ERRCODE_SUCC){
printf("uapi_upg_prepare fail! ret = %d\n",ret);
}
ret = uapi_upg_request_upgrade(false);
if(ret != ERRCODE_SUCC){
printf("uapi_upg_request_upgrade fail! ret = %d\n",ret);
}
ret = uapi_upg_start();
if(ret != ERRCODE_SUCC){
printf("uapi_upg_start fail! ret = %d\n",ret);
}
upg_reboot();
}else{
tjd_restart_device();
}
}
void tjd_ota_recovery_upgrade_operation(uint32_t file_size)
{
uint32_t packsize_= file_size;
upg_prepare_info_t prepare_info = {
.package_len = packsize_
};
// prepare_info.package_len = packsize_;
static_print_debug("%s , line is %d ,prepare_info.package_len = %d , packsize_ = %d", __FUNCTION__, __LINE__, prepare_info.package_len,packsize_);
if(prepare_info.package_len != 0){
errcode_t ret = uapi_upg_prepare(&prepare_info);
if(ret != ERRCODE_SUCC){
printf("uapi_upg_prepare fail! ret = %d\n",ret);
}
ret = uapi_upg_request_upgrade(false);
if(ret != ERRCODE_SUCC){
printf("uapi_upg_request_upgrade fail! ret = %d\n",ret);
}
ret = uapi_upg_start();
if(ret != ERRCODE_SUCC){
printf("uapi_upg_start fail! ret = %d\n",ret);
}
upg_reboot();
}else{
tjd_restart_device();
}
}
void tjd_ble_protocol_switch_ota(uint8_t server_id, uint16_t conn_id, uint8_t *write_cb_para, uint16_t len , uint8_t cmd_id)
{
uint8_t ota_file_num = 0;
uint32_t ota_file_size = 0;
if (write_cb_para[4] == 0x00) {
static_print_debug("exit OTA mode switch to BLE mode");
// 通知app退出ota模式
uint8_t data[2] = {0};
data[0] = 0x00;
data[1] = 0x01;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
static_print_debug("total file size is %d-%d,file number:%d-%d", tjd_ble_get_transfer_info()->operation_total_size, tjd_ble_get_dir_description()->file_total_size, tjd_ble_get_transfer_info()->operation_total_number, tjd_ble_get_dir_description()->file_total_number);
if (tjd_ble_get_transfer_info()->operation_total_size >= tjd_ble_get_dir_description()->file_total_size) {
tjd_ota_recovery_upgrade_operation(g_ota_firmware_file_size);
}
g_ota_send_data_mask = false;
tjd_service_ble_sync_data_open(); //打开30分钟一次请求同步数据任务
tjd_ble_protocol_dir_transfer_exit_handle();
// tjd_exit_app_view();
return;
} else if (write_cb_para[4] == 0x01) {
static_print_debug("switch to OTA mode");
// TODO: 进入OTA模式
tjd_service_ble_sync_data_close(); //关闭30分钟一次请求同步数据任务
static_print_debug("check power supply");
// TODO: 检查电源电量
// if(power_supply_check() == POWER_SUPPLY_LOW){
// static_print_error("power supply is low, exit OTA mode\n");
// }
// 通知app成功进入ota模式
uint8_t data[2] = {0};
data[0] = 0x01;
data[1] = 0x01;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
static_print_debug("%s , line is %d", __FUNCTION__, __LINE__);
g_ota_send_data_mask = true;
ota_file_num = write_cb_para[5];
ota_file_size = (write_cb_para[6] << 24) | (write_cb_para[7] << 16) |
(write_cb_para[8] << 8) | write_cb_para[9];
static_print_debug("ota file num: %d, ota file size: %d", ota_file_num, ota_file_size);
g_ota_start_flag = false;
tjd_ble_protocol_dir_transfer_enter_handle(TYPE_FIRMWARE, ota_file_num, ota_file_size);
static_print_debug("enter OTA mode");
const power_display_svr_api_t *display_api = power_display_svr_get_api();
if (display_api->get_screen_state() != SCREEN_ON) {
display_api->turn_on_screen();
}
errcode_t ret =display_api->set_auto_timeout_function(0);
if(ret != ERRCODE_SUCC){
static_print_error("set_auto_timeout_function fail! ret : %x" , ret);
}
ret = display_api->set_screen_set_keepon_timeout(-1);
if(ret != ERRCODE_SUCC){
static_print_error("set_screen_set_keepon_timeout fail! ret : %x" , ret);
}
tjd_into_ota_view();
// if(g_into_ota_view_callback != NULL){
// g_into_ota_view_callback();
// }
} else {
static_print_debug("unknown OTA mode switch");
uint8_t data[2] = {0};
data[0] = 0x01;
data[1] = 0x00;
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
return;
}
}
void file_download_callback_start_type_fiemware(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
{
static_print_debug("file_download_callback_start_type_fiemware()");
file_download_callback_data_type_fiemware(p_description, p_transfer);
}
void file_download_callback_end_type_fiemware(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
{
static_print_debug("file_download_callback_end_type_fiemware()");
file_download_callback_data_type_fiemware(p_description, p_transfer);
}
void file_download_callback_data_type_fiemware(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
{
if (g_ota_schedule_callback != NULL) {
static_print_debug("file_download_callback_data_type_fiemware():%d-%d",p_transfer->operation_total_size, tjd_ble_get_dir_description()->file_total_size);
g_ota_schedule_callback(p_transfer->operation_total_size, tjd_ble_get_dir_description()->file_total_size);
}
}