/*---------------------------------------------------------------------------- * 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 #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 #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); } }