866 lines
45 KiB
C
866 lines
45 KiB
C
/*----------------------------------------------------------------------------
|
||
* Copyright (c) Fenda Technologies Co., Ltd. 2022. All rights reserved.
|
||
*
|
||
* Description: ble_protocol_file_upload.c
|
||
*
|
||
* Author: saimen
|
||
*
|
||
* Create: 2024-12-03
|
||
*--------------------------------------------------------------------------*/
|
||
|
||
#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 "service_lucky_clover.h"
|
||
#include "broadcast_feature.h"
|
||
#include "service_charger.h"
|
||
#include "service_sleep.h"
|
||
#include "ble_protocol_file_download.h"
|
||
|
||
#ifdef __cplusplus
|
||
extern "C"
|
||
{
|
||
#endif
|
||
#include "TjdUiAppCameraToC.h"
|
||
// #include "TjdUiWatchFaceCtrl.h"
|
||
#include "service_gps.h"
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#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
|
||
|
||
#define BLE_FILE_TRANSFER_TIME_OUT (15)
|
||
#define TJD_FS_DIR_GPS_BAT TJD_FS_DIR_GPS"bat"
|
||
#define FS_VOLUME_USER "/user/"
|
||
#define FS_VOLUME_UPDATE "/update/"
|
||
#define FS_NODE_INFO_SPACE 16
|
||
|
||
FileDescriptionInfo_t g_file_description = {0};
|
||
FileTransferInfo_t g_files_transfer = {0};
|
||
DirDescriptionInfo_t g_dir_description = {0};
|
||
|
||
typedef void (*file_transfer_callback_t)(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
typedef struct {
|
||
file_transfer_callback_t start;
|
||
file_transfer_callback_t end;
|
||
file_transfer_callback_t data;
|
||
} FileTransferCallback_t;
|
||
FileTransferCallback_t g_files_transfer_Callback[FileType_MAX];
|
||
|
||
UpgradeContext g_file_decription_context;
|
||
|
||
//文件下载中回调集中处理
|
||
extern void file_download_callback_start_type_fiemware(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
extern void file_download_callback_end_type_fiemware(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
extern void file_download_callback_data_type_fiemware(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
extern void file_download_callback_start_type_dial_original(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
extern void file_download_callback_end_type_dial_original(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
extern void file_download_callback_start_type_dial_doc(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
extern void file_download_callback_end_type_dial_doc(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
extern void file_download_callback_end_type_dial_custom(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
extern void file_download_callback_end_type_gps(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
extern void file_download_callback_end_type_js(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer);
|
||
|
||
void tjd_ble_protocol_file_download_callback_init(void)
|
||
{
|
||
static_print_debug("tjd_ble_protocol_file_download_callback_init():...........\n");
|
||
memset_s(g_files_transfer_Callback, sizeof(g_files_transfer_Callback), 0, sizeof(g_files_transfer_Callback));
|
||
g_files_transfer_Callback[TYPE_FIRMWARE].start = file_download_callback_start_type_fiemware;
|
||
g_files_transfer_Callback[TYPE_FIRMWARE].end = file_download_callback_end_type_fiemware;
|
||
g_files_transfer_Callback[TYPE_FIRMWARE].data = file_download_callback_data_type_fiemware;
|
||
|
||
g_files_transfer_Callback[TYPE_AIDIAL_ORIGINAL].start = file_download_callback_start_type_dial_original;
|
||
g_files_transfer_Callback[TYPE_AIDIAL_ORIGINAL].end = file_download_callback_end_type_dial_original;
|
||
|
||
g_files_transfer_Callback[TYPE_DIAL_DOC].start = file_download_callback_start_type_dial_doc;
|
||
g_files_transfer_Callback[TYPE_DIAL_DOC].end = file_download_callback_end_type_dial_doc;
|
||
|
||
g_files_transfer_Callback[TYPE_DIAL_DIAGRAM].end = file_download_callback_end_type_dial_custom;
|
||
g_files_transfer_Callback[TYPE_DIAL_MULTIGRAPH].end = file_download_callback_end_type_dial_custom;
|
||
g_files_transfer_Callback[TYPE_DIAL_VIDEO].end = file_download_callback_end_type_dial_custom;
|
||
g_files_transfer_Callback[TYPE_GPS].end = file_download_callback_end_type_gps;
|
||
g_files_transfer_Callback[TYPE_JS_APP].end = file_download_callback_end_type_js;
|
||
}
|
||
|
||
void tjd_file_transfer_err_operation(void)
|
||
{
|
||
switch(g_file_description.file_type){
|
||
case TYPE_E_BOOK:
|
||
static_print_error("TYPE_E_BOOK file transfer error");
|
||
tjd_fs_api_path_remove((char *)g_file_description.file_name);
|
||
break;
|
||
case TYPE_JS_APP:
|
||
static_print_error("TYPE_JS_APP file transfer error");
|
||
tjd_fs_api_path_remove((char *)g_file_description.file_name);
|
||
break;
|
||
default:
|
||
static_print_error("file transfer error");
|
||
tjd_fs_api_path_remove((char *)g_file_description.file_name);
|
||
break;
|
||
}
|
||
}
|
||
|
||
int tjd_service_timer_cnt = 0;
|
||
//文件下载通信超时检测
|
||
signed int tjd_task_service_timer_check_timeout(void *param)
|
||
{
|
||
unsigned long *p_param = (unsigned long *)param;
|
||
uint64_t temp_time = 0;
|
||
tjd_driver_rtc_get_ops()->get_timestamp(&temp_time);
|
||
static_print_debug("tjd_task_service_timer_check_timeout(): param=%ld\r\n", *p_param);
|
||
static_print_debug("tjd_task_service_timer_check_timeout(): temp_time=%ld\r\n", temp_time);
|
||
static_print_debug("tjd_task_service_timer_check_timeout(): g_files_transfer.file_status=%d\r\n", g_files_transfer.file_status);
|
||
if(temp_time - *p_param > BLE_FILE_TRANSFER_TIME_OUT) {
|
||
if(g_files_transfer.file_status != FileTransfer_NULL) {
|
||
tjd_ble_file_breakpoint_save();
|
||
g_files_transfer.file_status = FileTransfer_Timeout;
|
||
if(g_files_transfer_Callback[g_file_description.file_type].end)
|
||
{
|
||
g_files_transfer_Callback[g_file_description.file_type].end(&g_file_description, &g_files_transfer);
|
||
}
|
||
}
|
||
return 0; //自动删除超时检测
|
||
} else if(((temp_time - *p_param)%5==4) && g_files_transfer.file_status != FileTransfer_NULL) {
|
||
static_print_debug("tjd_task_service_timer_check_timeout(): repeat =%ld\r\n", *p_param);
|
||
tjd_service_timer_cnt ++;
|
||
static_print_debug("tjd_task_service_timer_check_timeout(): tjd_service_timer_cnt =%d\r\n", tjd_service_timer_cnt);
|
||
if(tjd_service_timer_cnt > 3) {
|
||
tjd_service_timer_cnt = 0;
|
||
ble_api_cmd_info_reset();
|
||
tjd_file_transfer_err_operation();
|
||
uint8_t resp_data[9] = {0};
|
||
resp_data[0] = 0x00;
|
||
resp_data[1] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[2] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[3] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[4] = g_files_transfer.operation_file_size & 0xFF;
|
||
resp_data[5] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[6] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[7] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[8] = g_files_transfer.operation_file_size & 0xFF;
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, resp_data, sizeof(resp_data), DOWNLOAD_FILE_DATA, gatt_server_id, g_server_conn_id);
|
||
}else{
|
||
ble_api_cmd_info_reset();
|
||
uint8_t resp_data[9] = {0};
|
||
resp_data[0] = 0x01;
|
||
resp_data[1] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[2] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[3] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[4] = g_files_transfer.operation_file_size & 0xFF;
|
||
resp_data[5] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[6] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[7] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[8] = g_files_transfer.operation_file_size & 0xFF;
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, resp_data, sizeof(resp_data), DOWNLOAD_FILE_DATA, gatt_server_id, g_server_conn_id);
|
||
}
|
||
}
|
||
return 1000; //定时执行间隔单位为ms
|
||
}
|
||
|
||
void tjd_task_service_check_timeout_start(void)
|
||
{
|
||
queue_default_info_t msg_data = { tjd_task_service_timer_check_timeout, &g_files_transfer.operation_last_time, 1000, NULL };//1000ms首次执行的等待时间。
|
||
osal_msg_queue_write_copy(tjd_task_service_timer_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0);
|
||
}
|
||
|
||
//基础接口:开始
|
||
uint32_t tjd_ble_get_file_download_current_offset(void)
|
||
{
|
||
if(g_files_transfer.file_status != FileTransfer_NULL) {
|
||
return g_files_transfer.operation_file_size;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
void tjd_ble_protocol_dir_transfer_enter_handle(uint8_t file_total_type, uint8_t file_total_number, uint32_t file_total_size)
|
||
{
|
||
static_print_debug("tjd_ble_protocol_dir_transfer_enter_handle():%d-%d-%d\n", file_total_type, file_total_number, file_total_size);
|
||
g_dir_description.file_total_type = file_total_type;
|
||
g_dir_description.file_total_number = file_total_number;
|
||
g_dir_description.file_total_size = file_total_size;
|
||
memset_s(&g_files_transfer, sizeof(g_files_transfer), 0, sizeof(g_files_transfer));
|
||
}
|
||
|
||
void tjd_ble_protocol_dir_transfer_exit_handle(void)
|
||
{
|
||
static_print_debug("tjd_ble_protocol_dir_transfer_exit_handle()\n");
|
||
g_dir_description.file_total_type = FileType_MAX;
|
||
g_dir_description.file_total_number = 0;
|
||
g_dir_description.file_total_size = 0;
|
||
memset_s(&g_files_transfer, sizeof(g_files_transfer), 0, sizeof(g_files_transfer));
|
||
}
|
||
|
||
void tjd_ble_protocol_file_download_transfer_reset(void)
|
||
{
|
||
static_print_debug("tjd_ble_protocol_file_download_transfer_reset()\n");
|
||
memset_s(&g_file_description, sizeof(g_file_description), 0, sizeof(g_file_description));
|
||
memset_s(&g_files_transfer, sizeof(g_files_transfer), 0, sizeof(g_files_transfer));
|
||
g_dir_description.file_total_type = FileType_MAX;
|
||
g_file_description.file_type = FileType_MAX;
|
||
}
|
||
//断点保存
|
||
void tjd_ble_file_breakpoint_save(void)
|
||
{
|
||
static_print_debug("tjd_ble_file_breakpoint_save()");
|
||
if(g_files_transfer.file_status != FileTransfer_NULL && g_files_transfer.operation_file_size != 0 && g_file_description.file_crc32!= 0 && g_file_description.file_name!= NULL){
|
||
if(g_files_transfer.breakpoint_en == true || g_file_description.file_size >= 1024*1000) { //使用断点功能
|
||
sql_bt_set_breakpoint_info(g_files_transfer.operation_file_size, g_file_description.file_crc32, (char *)g_file_description.file_name);
|
||
static_print_debug("sql set breakpoint info, g_files_transfer.operation_file_size : %d, g_file_description.file_crc32 : %x, g_file_description.file_name : %s",
|
||
g_files_transfer.operation_file_size, g_file_description.file_crc32, g_file_description.file_name);
|
||
}
|
||
}
|
||
}
|
||
|
||
//断点恢复
|
||
bool tjd_ble_file_breakpoint_recover(FileDescriptionInfo_t *p_description, FileTransferInfo_t *p_transfer)
|
||
{
|
||
breakpoint_info_t breakpoint_info = {0};
|
||
if(!sql_bt_get_breakpoint_info(&breakpoint_info.offset_byte, &breakpoint_info.crc_32,(char *)breakpoint_info.file_name)){
|
||
return false;
|
||
}
|
||
|
||
if(strcmp(breakpoint_info.file_name, (const char *)p_description->file_name) != 0){
|
||
return false;
|
||
}
|
||
|
||
struct stat file_stat ={0};
|
||
if(stat((char *)p_description->file_name, &file_stat) != 0)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if(file_stat.st_size != breakpoint_info.offset_byte) {
|
||
return false;
|
||
}
|
||
|
||
if(p_description->file_crc32 != breakpoint_info.crc_32) {
|
||
return false;
|
||
}
|
||
static_print_debug("breakpoint info offset_byte : %d, crc_32 : %x, file_name : %s",breakpoint_info.offset_byte, breakpoint_info.crc_32,breakpoint_info.file_name);
|
||
p_transfer->operation_file_size = breakpoint_info.offset_byte;
|
||
if(p_description->file_type != FileType_MAX && p_description->file_type == g_dir_description.file_total_type) {
|
||
p_transfer->operation_total_size += p_transfer->operation_file_size;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
DirDescriptionInfo_t *tjd_ble_get_dir_description(void)
|
||
{
|
||
return &g_dir_description;
|
||
}
|
||
|
||
FileTransferInfo_t *tjd_ble_get_transfer_info(void)
|
||
{
|
||
return &g_files_transfer;
|
||
}
|
||
|
||
//protocol 相关接口 start
|
||
void tjd_file_pre_operation(void)
|
||
{
|
||
struct stat file_stat ={0};
|
||
int ret = stat((char *)g_file_description.file_name, &file_stat);
|
||
if (ret == 0) {
|
||
static_print_debug("file exist");
|
||
// 文件存在,删除文件
|
||
// ret = tjd_remove_rsvd_part((char *)base_dir, (char *)g_file_description.file_name);
|
||
ret = unlink((char *)g_file_description.file_name);
|
||
if (ret < 0) {
|
||
static_print_error("remove file fail");
|
||
}
|
||
static_print_debug("remove file success");
|
||
}
|
||
}
|
||
|
||
void tjd_ble_protocol_file_description(uint8_t server_id, uint16_t conn_id, uint8_t *write_cb_para, uint16_t len, uint8_t cmd_id)
|
||
{
|
||
// TODO: app下发文件描述:DOWNLOAD_FILE_DESCRIPTION
|
||
static_print_debug("tjd_ble_protocol_file_description():%d", g_files_transfer.file_status);
|
||
uint16_t valid_data_len = len - 9;
|
||
uint8_t data_index = 4;
|
||
uint16_t file_description_len = (write_cb_para[data_index] << 8) | write_cb_para[data_index + 1];
|
||
uint16_t rec_file_description_offset = (write_cb_para[data_index + 2] << 8) | write_cb_para[data_index + 3];
|
||
valid_data_len = (valid_data_len > file_description_len)? file_description_len : valid_data_len;
|
||
|
||
uint64_t temp_time = 0;
|
||
tjd_driver_rtc_get_ops()->get_timestamp(&temp_time);
|
||
if(temp_time - g_files_transfer.operation_last_time > BLE_FILE_TRANSFER_TIME_OUT || g_files_transfer.file_status == FileTransfer_Timeout) {
|
||
g_files_transfer.file_status = FileTransfer_NULL;
|
||
}
|
||
g_files_transfer.operation_last_time = temp_time;
|
||
|
||
if (g_files_transfer.file_status == FileTransfer_NULL) {
|
||
static_print_debug("%s , line is %d", __FUNCTION__, __LINE__);
|
||
memset_s(&g_file_decription_context, sizeof(g_file_decription_context), 0, sizeof(g_file_decription_context));
|
||
g_file_decription_context.buffer_offset = 0;
|
||
g_file_decription_context.expected_seq = file_description_len;
|
||
if(g_file_decription_context.buffer == NULL) {
|
||
g_file_decription_context.buffer = (uint8_t *)malloc(file_description_len);
|
||
}
|
||
memset_s(g_file_decription_context.buffer, file_description_len, 0, file_description_len);
|
||
g_files_transfer.file_status = FileTransfer_Description;
|
||
}
|
||
|
||
if (g_file_decription_context.buffer_offset != rec_file_description_offset) {
|
||
static_print_error("g_file_decription_context.buffer_offset != rec_file_description_offset");
|
||
uint8_t data[3] = {0};
|
||
data[0] = 0x00;
|
||
data[1] = (g_file_decription_context.buffer_offset >> 8) & 0xFF;
|
||
data[2] = g_file_decription_context.buffer_offset & 0xFF;
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
|
||
free(g_file_decription_context.buffer);
|
||
g_file_decription_context.buffer = NULL;
|
||
g_file_decription_context.buffer_offset = 0;
|
||
g_file_decription_context.expected_seq = 0;
|
||
return;
|
||
}
|
||
static_print_debug("file description len : %d, rec_file_description_offset : %d", file_description_len, rec_file_description_offset);
|
||
memcpy_s(g_file_decription_context.buffer + rec_file_description_offset, file_description_len - rec_file_description_offset, &write_cb_para[data_index + 4], valid_data_len);
|
||
g_file_decription_context.buffer_offset = rec_file_description_offset + valid_data_len;
|
||
|
||
if (g_files_transfer.file_status == FileTransfer_Description && g_file_decription_context.buffer_offset == file_description_len) {
|
||
//文件描述,文件传输信息重置
|
||
g_files_transfer.file_status = FileTransfer_DescriptionDone;
|
||
memset_s(&g_file_description, sizeof(g_file_description), 0, sizeof(g_file_description));
|
||
g_files_transfer.operation_file_size = 0;
|
||
// 表盘LTV文件描述如 0301040602123456780603F1F1F1F10804313233343536
|
||
// 0301040602123456780603F1F1F1F10804313233343536
|
||
for (int i = 0; i < file_description_len;) { // 遍历文件描述
|
||
uint8_t len = g_file_decription_context.buffer[i];
|
||
uint8_t type = g_file_decription_context.buffer[i + 1];
|
||
// static_print_debug("i : %u, type : %u, len : %u", i, type, len);
|
||
switch (type) {
|
||
case 0x01: { // 文件类型
|
||
memcpy_s(&g_file_description.file_type, sizeof(g_file_description.file_type), &g_file_decription_context.buffer[i + 2], len - 2);
|
||
static_print_warn("file type : %u", g_file_description.file_type);
|
||
break;
|
||
}
|
||
case 0x02: { // 文件总字节
|
||
g_file_description.file_size = (g_file_decription_context.buffer[i + 2] << 24) |
|
||
(g_file_decription_context.buffer[i + 3] << 16) |
|
||
(g_file_decription_context.buffer[i + 4] << 8) |
|
||
g_file_decription_context.buffer[i + 5];
|
||
static_print_warn("file total bytes : %u ", g_file_description.file_size);
|
||
break;
|
||
}
|
||
case 0x03: { // 文件crc32
|
||
g_file_description.file_crc32 = (g_file_decription_context.buffer[i + 2] << 24) |
|
||
(g_file_decription_context.buffer[i + 3] << 16) |
|
||
(g_file_decription_context.buffer[i + 4] << 8) |
|
||
g_file_decription_context.buffer[i + 5];
|
||
static_print_warn("file total crc32 : %08x", g_file_description.file_crc32);
|
||
break;
|
||
}
|
||
case 0x04: { // 文件名称
|
||
const char *suffix = (const char *)&g_file_decription_context.buffer[i+2];
|
||
if(len - 2 > PROTOCOL_FILE_NAME_LEN_MAX-1){
|
||
static_print_error("error:file_name len:%d, len max:%d", (len - 2), (PROTOCOL_FILE_NAME_LEN_MAX-1));
|
||
break;
|
||
}
|
||
switch (g_file_description.file_type) {
|
||
case TYPE_LOG: {
|
||
static_print_debug("log file");
|
||
// strcat(g_rec_file_path, TJD_FS_DIR_UPDATE);
|
||
break;
|
||
}
|
||
case TYPE_FIRMWARE: {
|
||
static_print_debug("firmware file");
|
||
// 如果文件后缀名是 .fwkpg 则认为是固件文件
|
||
// 需存放在“/update/”目录下,否则存放在“/user/tjd_res/”目录下
|
||
|
||
const char *extension_update = ".fwpkg";
|
||
int str_len = len - 2;
|
||
int extension_update_len = strlen(extension_update);
|
||
// int extension_res_len = strlen(extension_res);
|
||
if(str_len >= extension_update_len && strncmp(suffix + str_len - extension_update_len,extension_update,extension_update_len) == 0){
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_UPDATE);
|
||
tjd_ota_set_fimrware_size(g_file_description.file_size);
|
||
}else {
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_RES);
|
||
}
|
||
|
||
break;
|
||
}
|
||
case TYPE_RESOURCE_FILES: {
|
||
static_print_debug("resource files");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_RES);
|
||
break;
|
||
}
|
||
case TYPE_MULTILINGUAL_DOC: {
|
||
static_print_debug("multilingual doc file");
|
||
// strcat(g_rec_file_path, TJD_FS_DIR_DOC);
|
||
break;
|
||
}
|
||
case TYPE_DIAL_DOC: {
|
||
static_print_debug("dial doc file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_WF);
|
||
break;
|
||
}
|
||
case TYPE_PICTURE: {
|
||
static_print_debug("picture file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_ALBUM);
|
||
break;
|
||
}
|
||
case TYPE_VIDEO: {
|
||
static_print_debug("video file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_ALBUM);
|
||
break;
|
||
}
|
||
case TYPE_E_BOOK: {
|
||
static_print_debug("e-book file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_BOOK);
|
||
break;
|
||
}
|
||
case TYPE_MUSIC: {
|
||
static_print_debug("music file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_MUSIC);
|
||
break;
|
||
}
|
||
case TYPE_AIDIAL_ORIGINAL: {
|
||
static_print_debug("aidial original file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_WFP);
|
||
if(access(TJD_FS_DIR_WFP, 0) != 0){
|
||
mkdir(TJD_FS_DIR_WFP, 0777);
|
||
static_print_debug("mkdir /user/tjd_wfp dirent success");
|
||
}
|
||
break;
|
||
}
|
||
case TYPE_AIDIAL_THUMBNAIL: {
|
||
static_print_debug("aidial thumbnail file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_WFP);
|
||
if(access(TJD_FS_DIR_WFP, 0) != 0){
|
||
mkdir(TJD_FS_DIR_WFP, 0777);
|
||
static_print_debug("mkdir /user/tjd_wfp dirent success");
|
||
}
|
||
break;
|
||
}
|
||
case TYPE_AIDIAL_PREVIEW: {
|
||
static_print_debug("aidial preview file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_WFP);
|
||
if(access(TJD_FS_DIR_WFP, 0) != 0){
|
||
mkdir(TJD_FS_DIR_WFP, 0777);
|
||
static_print_debug("mkdir /user/tjd_wfp dirent success");
|
||
}
|
||
break;
|
||
}
|
||
case TYPE_GPS: {
|
||
static_print_debug("gps file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_GPS_BAT);
|
||
//如果 ""/user/tjd_gpsbat"" 目录不存在,则创建该目录
|
||
if(access(TJD_FS_DIR_GPS_BAT, 0) != 0){
|
||
mkdir(TJD_FS_DIR_GPS_BAT, 0777);
|
||
static_print_debug("mkdir /user/tjd_gpsbat dirent success");
|
||
}
|
||
break;
|
||
}
|
||
case TYPE_DIAL_DIAGRAM: {
|
||
static_print_debug("dial diagram file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_WFC);
|
||
//如果 ""/user/tjd_wfc"" 目录不存在,则创建该目录
|
||
if(access(TJD_FS_DIR_WFC, 0) != 0){
|
||
mkdir(TJD_FS_DIR_WFC, 0777);
|
||
static_print_debug("mkdir /user/tjd_wfc dirent success");
|
||
}
|
||
break;
|
||
}
|
||
case TYPE_DIAL_MULTIGRAPH: {
|
||
static_print_debug("dial multigraph file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_WFC);
|
||
//如果 ""/user/tjd_wfc"" 目录不存在,则创建该目录
|
||
if(access(TJD_FS_DIR_WFC, 0) != 0){
|
||
mkdir(TJD_FS_DIR_WFC, 0777);
|
||
static_print_debug("mkdir /user/tjd_wfc dirent success");
|
||
}
|
||
break;
|
||
}
|
||
case TYPE_DIAL_VIDEO: {
|
||
static_print_debug("dial video file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_WFC);
|
||
//如果 ""/user/tjd_wfc"" 目录不存在,则创建该目录
|
||
if(access(TJD_FS_DIR_WFC, 0) != 0){
|
||
mkdir(TJD_FS_DIR_WFC, 0777);
|
||
static_print_debug("mkdir /user/tjd_wfc dirent success");
|
||
}
|
||
break;
|
||
}
|
||
case TYPE_DIAL_PREVIEW: {
|
||
static_print_debug("dial preview file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_WFC);
|
||
//如果 ""/user/tjd_wfc"" 目录不存在,则创建该目录
|
||
if(access(TJD_FS_DIR_WFC, 0) != 0){
|
||
mkdir(TJD_FS_DIR_WFC, 0777);
|
||
static_print_debug("mkdir /user/tjd_wfc dirent success");
|
||
}
|
||
break;
|
||
}
|
||
case TYPE_JS_APP: {
|
||
static_print_debug("js app file");
|
||
strcat((const char *)g_file_description.file_name, TJD_FS_DIR_JS);
|
||
//如果 "/system/tjd_extapp"" 目录不存在,则创建该目录
|
||
if(access(TJD_FS_DIR_JS, 0) != 0){
|
||
mkdir(TJD_FS_DIR_JS, 0777);
|
||
static_print_debug("mkdir /system/tjd_extapp dirent success");
|
||
}
|
||
break;
|
||
}
|
||
default: {
|
||
static_print_error("unknown file type");
|
||
break;
|
||
}
|
||
}
|
||
/*
|
||
1、一文件名不能包括#号。
|
||
2、如果文件名中出#号说明文件完整路径要被重定义。将"#"替换为"/"就是真实目标路径。OTA时方便全固件升级
|
||
3、例:APP下发文件名为:user#log#abc.txt=user/log/abc.txt
|
||
*/
|
||
if(strnstr(suffix, "#", len - 2) == NULL){
|
||
strcat((char *)g_file_description.file_name, "/");
|
||
strncat((char *)g_file_description.file_name, (char *)&g_file_decription_context.buffer[i + 2], len - 2);
|
||
} else {
|
||
g_file_description.file_name[0] = 0;
|
||
strncat((char *)g_file_description.file_name, (char *)&g_file_decription_context.buffer[i + 2], len - 2);
|
||
char * ret = strstr((char *)g_file_description.file_name, "#");
|
||
while(ret != NULL){
|
||
memset(ret, '/', 1);
|
||
ret = strstr(ret + 1, "#");
|
||
}
|
||
}
|
||
static_print_warn("file file name : %s", g_file_description.file_name);
|
||
break;
|
||
}
|
||
// case 0x05: { // 文件用途枚举
|
||
// memcpy_s(&g_file_description.file_usage, sizeof(g_file_description.file_usage),
|
||
// &g_file_decription_context.buffer[i + 2], len - 2);
|
||
// static_print_debug("file purpose : %u", g_file_description.file_usage);
|
||
// break;
|
||
// }
|
||
case 0x06: { // 图片宽度 图片高度
|
||
memcpy_s(&g_file_description.pictures_width, sizeof(g_file_description.pictures_width),
|
||
&g_file_decription_context.buffer[i + 2], 2);
|
||
memcpy_s(&g_file_description.pictures_height, sizeof(g_file_description.pictures_height),
|
||
&g_file_decription_context.buffer[i + 4], 2);
|
||
static_print_warn("image width : %u, height : %u", g_file_description.pictures_width,
|
||
g_file_description.pictures_height);
|
||
break;
|
||
}
|
||
case 0x07: { // 视频宽度 视频高度
|
||
memcpy_s(&g_file_description.video_width, sizeof(g_file_description.video_width),
|
||
&g_file_decription_context.buffer[i + 2], 2);
|
||
memcpy_s(&g_file_description.video_height, sizeof(g_file_description.video_height),
|
||
&g_file_decription_context.buffer[i + 4], 2);
|
||
static_print_warn("video width : %u, height : %u", g_file_description.video_width,
|
||
g_file_description.video_height);
|
||
break;
|
||
}
|
||
default: {
|
||
static_print_error("unknown type : %u", type);
|
||
break;
|
||
}
|
||
}
|
||
i += len;
|
||
}
|
||
|
||
uint8_t data[3] = {0};
|
||
data[0] = 0x02;
|
||
data[1] = (g_file_decription_context.buffer_offset >> 8) & 0xFF;
|
||
data[2] = g_file_decription_context.buffer_offset & 0xFF;
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
|
||
free(g_file_decription_context.buffer);
|
||
g_file_decription_context.buffer = NULL;
|
||
g_file_decription_context.buffer_offset = 0;
|
||
g_file_decription_context.expected_seq = 0;
|
||
return;
|
||
} else {
|
||
uint8_t data[3] = {0};
|
||
data[0] = 0x01;
|
||
data[1] = (g_file_decription_context.buffer_offset >> 8) & 0xFF;
|
||
data[2] = g_file_decription_context.buffer_offset & 0xFF;
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), cmd_id, server_id, conn_id);
|
||
return;
|
||
}
|
||
}
|
||
|
||
void tjd_ble_protocol_file_start(uint8_t server_id, uint16_t conn_id, uint8_t *write_cb_para, uint16_t len, uint8_t cmd_id)
|
||
{
|
||
static_print_debug("send file start:%d", g_files_transfer.file_status);
|
||
if(g_files_transfer.file_status == FileTransfer_DescriptionDone)
|
||
{
|
||
g_files_transfer.file_status = FileTransfer_Start;
|
||
}
|
||
|
||
if(g_files_transfer_Callback[g_file_description.file_type].start)
|
||
{
|
||
g_files_transfer_Callback[g_file_description.file_type].start(&g_file_description, &g_files_transfer);
|
||
}
|
||
// 电量检测 /* 待完善 */
|
||
|
||
// 存在检测
|
||
// 如果CRC与size一致,则发送02直接跳过当前文件传输,否则,发送01,等待app下发文件数据
|
||
static_print_debug("g_file_description.file_name: %s", g_file_description.file_name);
|
||
struct stat file_stat = {0};
|
||
int stat_ret = stat((char *)g_file_description.file_name,&file_stat);
|
||
static_print_debug("access ret is %d", stat_ret);
|
||
if(stat_ret == 0){
|
||
uint32_t crc32_local = calculateFileCRC32((char *)g_file_description.file_name, g_file_description.file_size);
|
||
static_print_debug("%s , line is %d", __FUNCTION__, __LINE__);
|
||
uint32_t crc32_remote = g_file_description.file_crc32;
|
||
|
||
static_print_debug("crc32_local is %08x, crc32_remote is %08x", crc32_local, crc32_remote);
|
||
if (crc32_local == crc32_remote && g_file_description.file_size == file_stat.st_size) {
|
||
static_print_debug("crc32 is same, send 02 to skip current file");
|
||
g_files_transfer.operation_file_size += g_file_description.file_size;
|
||
if(g_dir_description.file_total_type == g_file_description.file_type) {
|
||
g_files_transfer.operation_total_size += g_file_description.file_size;
|
||
g_files_transfer.operation_total_number++;
|
||
}
|
||
g_files_transfer.file_status = FileTransfer_NULL;
|
||
static_print_debug("files transfer end: total_size=%d,file_size=%d", g_files_transfer.operation_total_size, g_files_transfer.operation_file_size);
|
||
|
||
uint8_t data[] = {0x02};
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), DOWNLOAD_FILE_SRART, server_id, conn_id);
|
||
return;
|
||
}
|
||
}
|
||
//空间检测
|
||
struct statfs fs_stat = {0};
|
||
char fs_volume[64] = {0};
|
||
char *str_ret = NULL;
|
||
if(g_file_description.file_name[0] == '/'){
|
||
str_ret = strnstr((const char *)&g_file_description.file_name[1], "/", PROTOCOL_FILE_NAME_LEN_MAX);
|
||
if(str_ret) {
|
||
memcpy_s(fs_volume, sizeof(fs_volume), g_file_description.file_name, (size_t)((uint32_t)str_ret - (uint32_t)g_file_description.file_name));
|
||
}
|
||
} else {
|
||
str_ret = strnstr((const char *)g_file_description.file_name, "/", PROTOCOL_FILE_NAME_LEN_MAX);
|
||
if(str_ret) {
|
||
memcpy_s(fs_volume, sizeof(fs_volume), g_file_description.file_name, (size_t)((uint32_t)str_ret - (uint32_t)g_file_description.file_name));
|
||
}
|
||
}
|
||
|
||
if (statfs(fs_volume, &fs_stat) != 0) {
|
||
static_print_error("error:statfs() = null");
|
||
}
|
||
static_print_debug("fs_stat.f_bfree :[%s] %ld-%ld", fs_volume, fs_stat.f_bfree, fs_stat.f_bsize);
|
||
|
||
if (fs_stat.f_bfree >= FS_NODE_INFO_SPACE) {
|
||
fs_stat.f_bfree = fs_stat.f_bfree - FS_NODE_INFO_SPACE;
|
||
} else {
|
||
fs_stat.f_bfree = 0;
|
||
}
|
||
|
||
if(stat_ret != 0) {
|
||
static_print_debug("file stat() = null:[%s]", g_file_description.file_name);
|
||
} else {
|
||
uint32_t file_blocks = file_stat.st_size / file_stat.st_blksize ;
|
||
fs_stat.f_bfree += file_blocks;
|
||
static_print_debug("file stat() = ok:[%s] st_size=%ld", g_file_description.file_name, file_stat.st_size);
|
||
}
|
||
uint32_t free_space = fs_stat.f_bfree * fs_stat.f_bsize;
|
||
if ((free_space < g_file_description.file_size) && g_file_description.file_size != 0 ) {
|
||
static_print_error("not enough space! free space : %d , file size : %d",free_space, g_file_description.file_size);
|
||
uint8_t data[] = {0x03};
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), DOWNLOAD_FILE_SRART, server_id, conn_id);
|
||
return;
|
||
}
|
||
//正常开始
|
||
// gap_conn_param_update_t conn_param = { 0 };
|
||
// conn_param.conn_handle = conn_id; /* param 0: conn_handle */
|
||
// conn_param.interval_min = 6; /* param 1: interval_min */
|
||
// conn_param.interval_max = 10; /* param 2: interval_max */
|
||
// conn_param.slave_latency = 0; /* param 3: slave_latency */
|
||
// conn_param.timeout_multiplier = 300; /* param 4: timeout_multiplier */
|
||
// errcode_t update_ret = gap_ble_connect_param_update(&conn_param);
|
||
// static_print_debug("gap ble update connection parameters ret: %u", update_ret);
|
||
uint8_t data[] = {0x01};
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), DOWNLOAD_FILE_SRART, server_id, conn_id);
|
||
}
|
||
|
||
void tjd_ble_protocol_file_data(uint8_t server_id, uint16_t conn_id, uint8_t *write_cb_para, uint16_t len ,uint8_t cmd_id)
|
||
{
|
||
int ret = 0;
|
||
uint16_t write_len = write_cb_para[1] << 8 | write_cb_para[2];
|
||
uint32_t remaining_size = g_file_description.file_size - g_files_transfer.operation_file_size;
|
||
uint16_t data_len = write_len - 9;
|
||
uint16_t valid_data_len = len - 9;
|
||
uint32_t cmd_offset = write_cb_para[4];
|
||
cmd_offset <<= 8;
|
||
cmd_offset += write_cb_para[5];
|
||
cmd_offset <<= 8;
|
||
cmd_offset += write_cb_para[6];
|
||
cmd_offset <<= 8;
|
||
cmd_offset += write_cb_para[7];
|
||
tjd_service_timer_cnt = 0;
|
||
tjd_driver_rtc_get_ops()->get_timestamp(&g_files_transfer.operation_last_time);
|
||
if(g_files_transfer.file_status == FileTransfer_Start)
|
||
{
|
||
g_files_transfer.file_status = FileTransfer_Data;
|
||
tjd_task_service_check_timeout_start();
|
||
static_print_debug("write_len : %d, remaining_size : %d, data_len : %d, valid_data_len : %d, cmd_offset=%d\n", write_len, remaining_size, data_len, valid_data_len, cmd_offset);
|
||
|
||
if(tjd_ble_file_breakpoint_recover(&g_file_description, &g_files_transfer) == false) //无断点内容
|
||
{
|
||
tjd_file_pre_operation();
|
||
goto ACCEPTFILEDATA;
|
||
} else {
|
||
if(cmd_offset == g_files_transfer.operation_file_size) {
|
||
goto ACCEPTFILEDATA;
|
||
}
|
||
uint8_t resp_data[9] = {0};
|
||
resp_data[0] = 0x02;
|
||
resp_data[1] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[2] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[3] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[4] = g_files_transfer.operation_file_size & 0xFF;
|
||
resp_data[5] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[6] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[7] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[8] = g_files_transfer.operation_file_size & 0xFF;
|
||
// (uint32_t *)(&resp_data[1]) = g_files_transfer.operation_file_size;
|
||
// (uint32_t *)(&resp_data[5]) = download_breakpoint_resume_offset;
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, resp_data, sizeof(resp_data), cmd_id, server_id, conn_id);
|
||
return;
|
||
}
|
||
}else if(g_files_transfer.file_status == FileTransfer_Data) {
|
||
ACCEPTFILEDATA:
|
||
if(cmd_offset != g_files_transfer.operation_file_size) {
|
||
static_print_error("error:g_files_transfer.operation_file_size:%d,cmd_offset:%d", g_files_transfer.operation_file_size, cmd_offset);
|
||
uint8_t resp_data[9] = {0};
|
||
resp_data[0] = 0x02;
|
||
resp_data[1] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[2] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[3] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[4] = g_files_transfer.operation_file_size & 0xFF;
|
||
resp_data[5] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[6] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[7] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[8] = g_files_transfer.operation_file_size & 0xFF;
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, resp_data, sizeof(resp_data), cmd_id, server_id, conn_id);
|
||
} else {
|
||
if(data_len > 0){
|
||
if(remaining_size <= data_len){
|
||
ret = tjd_fs_api_file_append((const char *)g_file_description.file_name, write_cb_para + 8, remaining_size);
|
||
g_files_transfer.operation_file_size += remaining_size;
|
||
if(g_dir_description.file_total_type == g_file_description.file_type) {
|
||
g_files_transfer.operation_total_size += remaining_size;
|
||
}
|
||
}else{
|
||
ret = tjd_fs_api_file_append((const char *)g_file_description.file_name, write_cb_para + 8, len - 9);
|
||
g_files_transfer.operation_file_size += valid_data_len;
|
||
if(g_dir_description.file_total_type == g_file_description.file_type) {
|
||
g_files_transfer.operation_total_size += valid_data_len;
|
||
}
|
||
}
|
||
|
||
if(g_files_transfer_Callback[g_file_description.file_type].data)
|
||
{
|
||
g_files_transfer_Callback[g_file_description.file_type].data(&g_file_description, &g_files_transfer);
|
||
}
|
||
uint8_t resp_data[9] = {0};
|
||
resp_data[0] = 0x01;
|
||
resp_data[1] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[2] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[3] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[4] = g_files_transfer.operation_file_size & 0xFF;
|
||
resp_data[5] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[6] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[7] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[8] = g_files_transfer.operation_file_size & 0xFF;
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, resp_data, sizeof(resp_data), cmd_id, server_id, conn_id);
|
||
}else{
|
||
static_print_error("error: valid_data_len is In vain");
|
||
tjd_file_transfer_err_operation();
|
||
uint8_t resp_data[9] = {0};
|
||
resp_data[0] = 0x00;
|
||
resp_data[1] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[2] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[3] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[4] = g_files_transfer.operation_file_size & 0xFF;
|
||
resp_data[5] = g_files_transfer.operation_file_size >> 24;
|
||
resp_data[6] = (g_files_transfer.operation_file_size >> 16) & 0xFF;
|
||
resp_data[7] = (g_files_transfer.operation_file_size >> 8) & 0xFF;
|
||
resp_data[8] = g_files_transfer.operation_file_size & 0xFF;
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, resp_data, sizeof(resp_data), cmd_id, server_id, conn_id);
|
||
}
|
||
}
|
||
|
||
// static_print_debug("send resp data");
|
||
if (g_files_transfer.operation_file_size == g_file_description.file_size) {
|
||
static_print_debug("files transfer end: total_size=%d,file_size=%d", g_files_transfer.operation_total_size, g_files_transfer.operation_file_size);
|
||
static_print_debug("file_type : %d",g_file_description.file_type);
|
||
g_files_transfer.file_status = FileTransfer_NULL;
|
||
if(g_dir_description.file_total_type == g_file_description.file_type) {
|
||
g_files_transfer.operation_total_number++;
|
||
}
|
||
}
|
||
|
||
}else{
|
||
static_print_error("error:g_files_transfer.file_status:%d,file:%s", g_files_transfer.file_status, g_file_description.file_name);
|
||
}
|
||
}
|
||
|
||
void tjd_ble_protocol_file_end(uint8_t server_id, uint16_t conn_id, uint8_t *write_cb_para, uint16_t len, uint8_t cmd_id)
|
||
{
|
||
static_print_debug("tjd_ble_protocol_file_end():%d", g_files_transfer.file_status);
|
||
if(g_files_transfer_Callback[g_file_description.file_type].end)
|
||
{
|
||
g_files_transfer_Callback[g_file_description.file_type].end(&g_file_description, &g_files_transfer);
|
||
}
|
||
|
||
g_files_transfer.file_status = FileTransfer_NULL;
|
||
// g_file_transport_buf = NULL;
|
||
// memset(&g_file_description, 0, sizeof(g_file_description));
|
||
// gap_conn_param_update_t conn_param = { 0 };
|
||
// conn_param.conn_handle = conn_id; /* param 0: conn_handle */
|
||
// conn_param.interval_min = 16; /* param 1: interval_min */
|
||
// conn_param.interval_max = 32; /* param 2: interval_max */
|
||
// conn_param.slave_latency = 50; /* param 3: slave_latency */
|
||
// conn_param.timeout_multiplier = 300; /* param 4: timeout_multiplier */
|
||
// errcode_t ret = gap_ble_connect_param_update(&conn_param);
|
||
// static_print_debug("gap ble update connection parameters ret: %u", ret);
|
||
uint8_t data[] = {0x01};
|
||
tjd_ble_protocol_send_data(PROTOCOL_FRAME_RSP_HEAD_2, data, sizeof(data), DOWNLOAD_FILE_END_DATA, server_id, conn_id);
|
||
//sql_bt_set_breakpoint_info(0, 0, " ");
|
||
}
|