KT24-1110_65E-HA-651B/apps/soundbox/smartbox/file_transfer/file_transfer.c
2024-11-10 18:44:17 +08:00

796 lines
27 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "file_transfer.h"
#include "system/includes.h"
#include "system/fs/fs.h"
#include "btstack_3th_protocol_user.h"
#include "dev_manager.h"
#if (SMART_BOX_EN && TCFG_DEV_MANAGER_ENABLE)
#define FTP_FILE_DATA_UNIT (512) //(234)//不能超过RCSP协议的MTU大小
#define FTP_FILE_DATA_RECIEVE_REMAIN_SIZE (128) //接收缓存预留
#define FTP_FILE_DATA_RECIEVE_BUF_MIN_SIZE (FTP_FILE_DATA_UNIT + FTP_FILE_DATA_RECIEVE_REMAIN_SIZE)
#define FTP_FILE_DATA_RECIEVE_TIMEOUT (3*1000) //超时拉取数据等待时长, 超时时间到了,自动拉取
#define FTP_DOWNLOAD_FOLDER_NAME "downlad" //下载目录
#define FTP_FILE_VAILD_MARK "JL_FTP" //断点续传需要用到的文件内容标记
#define FTP_FILE_VAILD_MARK_TIMER_UNIT (10*1000) //单位ms
#define FTP_FILE_CRC_CAC_MAX_COUNTER (100) //文件校验一次校验的数据块个数
//#define FTP_DEBUG_ENABLE
#ifdef FTP_DEBUG_ENABLE
#define ftp_printf printf
#else
#define ftp_printf(...)
#endif//FTP_DEBUG_ENABLE
enum {
FTP_END_REASON_NONE = 0, //没有错误
FTP_END_REASON_WRITE_ERR, //写失败
FTP_END_REASON_DATA_OVER_LIMIT, //数据超范围
FTP_END_REASON_DATA_CRC_ERR, //文件校验失败
};
struct __file_check {
u16 crc_tmp;
u32 counter;
u32 remain;
};
struct __ftp_download {
u32 file_size;
u32 file_offset;
u8 win[FTP_FILE_DATA_UNIT];
u8 packet_id;
u8 packet_id_max;
u8 last_packet;
u16 mark_timer;
u16 get_timeout;
u16 start_timerout;
u16 file_crc;
struct __file_check check;
char *filepath;
FILE *file;
struct __dev *dev;
void (*end_callback)(void);
};
static struct __ftp_download *ftp_d = NULL;
static void file_transfer_download_get_data(void);
static void __file_transfer_download_file_check_caculate(void *priv);
//*----------------------------------------------------------------------------*/
/**@brief 校验分次处理消息发送处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void file_transfer_download_file_check_continue(void)
{
int msg[4];
msg[0] = (int)__file_transfer_download_file_check_caculate;
msg[1] = 1;
msg[2] = 0;
os_taskq_post_type("app_core", Q_CALLBACK, 3, msg);
}
//*----------------------------------------------------------------------------*/
/**@brief 文件数据块crc校验
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void __file_transfer_download_file_check_caculate(void *priv)
{
if (ftp_d == NULL) {
return ;
}
wdt_clear();
JL_ERR err = 0;
u32 cnt;
if (ftp_d->check.counter >= FTP_FILE_CRC_CAC_MAX_COUNTER) {
cnt = FTP_FILE_CRC_CAC_MAX_COUNTER;
} else {
cnt = ftp_d->check.counter;
}
printf("cnt = %d, check.counter = %d, crc_tmp = %x\n", cnt, ftp_d->check.counter, ftp_d->check.crc_tmp);
for (int i = 0; i < cnt; i++) {
fread(ftp_d->file, ftp_d->win, sizeof(ftp_d->win));
ftp_d->check.crc_tmp = CRC16_with_initval(ftp_d->win, sizeof(ftp_d->win), ftp_d->check.crc_tmp);
}
ftp_d->check.counter -= cnt;
if (ftp_d->check.counter == 0) {
if (ftp_d->check.remain) {
fread(ftp_d->file, ftp_d->win, ftp_d->check.remain);
printf("remain\n");
put_buf(ftp_d->win, ftp_d->check.remain);
ftp_d->check.crc_tmp = CRC16_with_initval(ftp_d->win, ftp_d->check.remain, ftp_d->check.crc_tmp);
}
//crc_check end
if (ftp_d->check.crc_tmp == ftp_d->file_crc) {
printf("crc check ok!!, start rename\n");
fseek(ftp_d->file, ftp_d->file_size, SEEK_SET);
//进入重命名流程
err = JL_CMD_send(JL_OPCODE_FILE_RENAME, NULL, 0, 1);
if (err) {
//命令发送失败, 直接停止
file_transfer_close();
}
return ;
} else {
printf("crc check fail, crc_tmp = %x, file_crc = %x!!\n", ftp_d->check.crc_tmp, ftp_d->file_crc);
u8 reason = FTP_END_REASON_DATA_CRC_ERR;
fdelete(ftp_d->file);
ftp_d->file = NULL;
JL_ERR err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1);
if (err) {
//命令发送失败, 直接停止
file_transfer_close();
}
}
} else {
file_transfer_download_file_check_continue();
}
}
//*----------------------------------------------------------------------------*/
/**@brief 文件文件校验处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void file_transfer_download_file_check(void)
{
ftp_d->check.crc_tmp = 0;
ftp_d->check.counter = ftp_d->file_size / sizeof(ftp_d->win);
ftp_d->check.remain = ftp_d->file_size % sizeof(ftp_d->win);
ftp_d->file_offset = ftp_d->file_size;
printf("crc_tmp = %x, counter = %d, remain = %d\n", ftp_d->check.crc_tmp, ftp_d->check.counter, ftp_d->check.remain);
fseek(ftp_d->file, 0, SEEK_SET);
file_transfer_download_file_check_continue();
}
//*----------------------------------------------------------------------------*/
/**@brief 文件传输重命名
@param rename:重命名
@return
@note 此过程接收的数据是实际文件传输的内容
*/
/*----------------------------------------------------------------------------*/
static int file_rename(const char *rename)
{
if (ftp_d && ftp_d->file) {
//rename之前先关闭文件
fclose(ftp_d->file);
ftp_d->file = NULL;
//重新打开文件
//printf("ftp_d->filepath:%s, rename:%s\n", ftp_d->filepath, rename);
ftp_d->file = fopen(ftp_d->filepath, "r");
//free(path);
if (ftp_d->file) {
//文件打开成功, 重命名
int ret = frename(ftp_d->file, rename);
if (ret) {
printf("rename fail\n");
} else {
printf("rename ok\n");
}
return ret;
} else {
printf("rename file open err!!");
}
}
return -1;
}
//*----------------------------------------------------------------------------*/
/**@brief 文件重传文件头信息保存处理
@param file:文件句柄,win:临时缓存offset:文件偏移
@return
@note 文件传输过程, 定时会触发断点续传信息保存处理
*/
/*----------------------------------------------------------------------------*/
static void file_transfer_download_vaild_mark_fill(FILE *file, u8 *win, u32 offset)
{
if (file) {
fseek(file, 0, SEEK_SET);
memset(win, 0, FTP_FILE_DATA_UNIT);
memcpy(win, FTP_FILE_VAILD_MARK, strlen(FTP_FILE_VAILD_MARK));
memcpy(win + strlen(FTP_FILE_VAILD_MARK), &offset, sizeof(offset));
fwrite(file, win, FTP_FILE_DATA_UNIT);
fseek(file, offset, SEEK_SET);
printf("============================================%s, offset = %d\n", __FUNCTION__, offset);
}
}
//*----------------------------------------------------------------------------*/
/**@brief 断点续传信息解析处理
@param file:文件句柄, 文件偏移获取指针
@return
@note 在文件传输开始的时候进行解析, 目的是找到续传文件偏移
*/
/*----------------------------------------------------------------------------*/
static void file_transfer_download_intermittent_parse(FILE *file, u32 *offset)
{
if (file) {
char mark[10] = {0};
fseek(file, 0, SEEK_SET);
int rlen = fread(file, mark, strlen(FTP_FILE_VAILD_MARK));
if (rlen) {
if (strcmp(mark, FTP_FILE_VAILD_MARK) == 0) {
printf("find VAILD_MARK !!\n");
rlen = fread(file, offset, sizeof(u32));
if (rlen) {
printf("read offset ok, %d!!\n", *offset);
fseek(file, *offset, SEEK_SET);
} else {
printf("read offset fail!!\n");
*offset = 0;
}
}
}
}
}
//*----------------------------------------------------------------------------*/
/**@brief 文件下载数据拉取超时处理
@param priv:私有参数,
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void file_transfer_download_get_timeout(void *priv)
{
ftp_printf("timeout!!!\n");
//在超时时间内没有收完所需要的数据, 重新拉取数据
file_transfer_download_get_data();
}
//*----------------------------------------------------------------------------*/
/**@brief 断点续传定时保存处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void file_transfer_download_vaild_mark_scan(void *priv)
{
if (ftp_d && ftp_d->file && ftp_d->mark_timer && ftp_d->last_packet == 0) {
file_transfer_download_vaild_mark_fill(ftp_d->file, ftp_d->win, ftp_d->file_offset);
}
}
//*----------------------------------------------------------------------------*/
/**@brief 文件下载数据拉取处理
@param 无
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void file_transfer_download_get_data(void)
{
if (ftp_d == NULL || ftp_d->file == NULL) {
ftp_printf("file not ready %d!!\n", __LINE__);
return;
}
u32 file_offset = 0;
u16 recieve_max = rcsp_packet_write_alloc_len();
if (recieve_max < FTP_FILE_DATA_RECIEVE_BUF_MIN_SIZE) {
ftp_printf("not enough buf to recieve!!\n");
return;
} else {
///预留些接收缓存给其他通信使用
recieve_max -= FTP_FILE_DATA_RECIEVE_REMAIN_SIZE;
}
ftp_d->packet_id = 0;
ftp_d->packet_id_max = recieve_max / FTP_FILE_DATA_UNIT;
recieve_max = ftp_d->packet_id_max * FTP_FILE_DATA_UNIT;
if (ftp_d->last_packet) {
recieve_max = FTP_FILE_DATA_UNIT;
file_offset = 0;
} else {
file_offset = ftp_d->file_offset;
}
ftp_printf("[get]recieve_max:%d, file_offset %d\n", recieve_max, file_offset);
u8 parm[7] = {0};
parm[0] = 0;
WRITE_BIG_U16(parm + 1, recieve_max);
WRITE_BIG_U32(parm + 3, file_offset);
JL_ERR err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER, parm, sizeof(parm), 0);
if (err) {
ftp_printf("%s fail!!! %d\n", __FUNCTION__, err);
return;
}
if (ftp_d->get_timeout == 0) {
ftp_d->get_timeout = sys_timeout_add(NULL, file_transfer_download_get_timeout, FTP_FILE_DATA_RECIEVE_TIMEOUT);
}
return;
}
//*----------------------------------------------------------------------------*/
/**@brief 文件路径长度统计
@param root_path:根目录, folder:文件夹filename:文件名
@return 文件路径长度
@note
*/
/*----------------------------------------------------------------------------*/
static u32 creat_path_len(char *root_path, const char *folder, u8 *name, u16 name_len)
{
return (strlen(root_path) + strlen(folder) + name_len + strlen("/") + 1);
}
//*----------------------------------------------------------------------------*/
/**@brief 文件路径组装处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
static void creat_file_path(char *path, char *root_path, const char *folder, u8 *name, u16 name_len)
{
strcat(path, root_path);
strcat(path, folder);
strcat(path, "/");
//strcat(path, name);
memcpy(path + strlen(root_path) + strlen(folder) + 1, name, name_len);
//printf("path = %s\n", path);
}
//*----------------------------------------------------------------------------*/
/**@brief 文件下载开始
@param OpCode_SN:数据包序列号data:数据, len:数据长度
@return 文件路径长度
@note
*/
/*----------------------------------------------------------------------------*/
void file_transfer_download_start(u8 OpCode_SN, u8 *data, u16 len)
{
if (ftp_d) {
//收到了文件传输开始命令, 停止启动超时处理
if (ftp_d->start_timerout) {
sys_timeout_del(ftp_d->start_timerout);
ftp_d->start_timerout = 0;
}
}
JL_ERR err = 0;
///创建文件
u32 file_size = READ_BIG_U32(data);//占用4byte
u16 file_crc = READ_BIG_U16(data + 4);//占用2byte
u8 *file_name = data + 4 + 2;
u16 file_name_len = len - 6;
if (ftp_d == NULL) {
ftp_d = zalloc(sizeof(struct __ftp_download));
if (ftp_d) {
printf("%s, no mem\n", __FUNCTION__);
JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_START, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0);
return ;
}
}
ftp_printf("file_size = %d, file_crc = %x\n", file_size, file_crc);
struct __dev *dev = dev_manager_find_active(0);
if (!dev) {
file_transfer_close();
ftp_printf("no dev online !!\n");
JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_START, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0);
return ;
}
char *root_path = dev_manager_get_root_path(dev);
char *folder = FTP_DOWNLOAD_FOLDER_NAME;
char *path = zalloc(creat_path_len(root_path, folder, file_name, file_name_len));
u8 new_file = 0;
ASSERT(path);
creat_file_path(path, root_path, folder, file_name, file_name_len);
ftp_d->file = fopen(path, "r");
if (ftp_d->file) {
printf("file exist\n");
new_file = 0;
fclose(ftp_d->file);
ftp_d->file = NULL;
} else {
printf("file new\n");
new_file = 1;
}
ftp_d->file = fopen(path, "w+");
ftp_d->filepath = path;
//free(path);
if (ftp_d->file == NULL) {
ftp_printf("file create err\n");
file_transfer_close();
///文件打开失败, 回复APP文件传输失败
JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_START, JL_PRO_STATUS_FAIL, OpCode_SN, NULL, 0);
return ;
}
ftp_d->dev = dev;
ftp_d->file_offset = 0;
ftp_d->file_crc = file_crc;
ftp_d->last_packet = 0;
ftp_d->file_size = file_size;
if (ftp_d->file_size > sizeof(ftp_d->win)) {
if (new_file == 0) {
///解析断点续传的文件偏移
file_transfer_download_intermittent_parse(ftp_d->file, &ftp_d->file_offset);
}
if (ftp_d->file_offset == 0 || ftp_d->file_offset > file_size) {
printf("file offset err !! reset offset \n");
ftp_d->file_offset = sizeof(ftp_d->win);
file_transfer_download_vaild_mark_fill(ftp_d->file, ftp_d->win, ftp_d->file_offset);
} else if (ftp_d->file_offset == file_size) {
//上次文件已经收完, 进入校验流程
printf("file aready download end \n");
file_transfer_download_file_check();
return ;
}
} else {
ftp_d->last_packet = 1;
}
///回复APP文件传输准备就绪
u16 file_data_unit = 0;
WRITE_BIG_U16(&file_data_unit, FTP_FILE_DATA_UNIT);
err = JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_START, JL_PRO_STATUS_SUCCESS, OpCode_SN, (u8 *)&file_data_unit, sizeof(u16));
if (err == 0) {
printf("%s ok!! file_offset: %d, data unit = %d\n", __FUNCTION__, ftp_d->file_offset, FTP_FILE_DATA_UNIT);
///回复启动成功之后,启动数据拉取操作(这里是第一次)
//fseek(ftp_d->file, ftp_d->file_offset, SEEK_SET);//重定位下文件位置
file_transfer_download_get_data();
ftp_d->mark_timer = sys_timer_add(NULL, file_transfer_download_vaild_mark_scan, FTP_FILE_VAILD_MARK_TIMER_UNIT);
return ;
} else {
ftp_printf("%s resp fail!!\n", __FUNCTION__);
file_transfer_close();
ftp_d = NULL;
}
return;
}
//*----------------------------------------------------------------------------*/
/**@brief 文件传输, 重命名处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void file_transfer_file_rename(u8 status, u8 *data, u16 len)
{
if (ftp_d) {
if (status == JL_PRO_STATUS_SUCCESS) {
printf("%s !!, %d\n", __FUNCTION__, __LINE__);
put_buf(data, len);
//重命名
if (file_rename((const char *)data) == 0) {
u8 reason = FTP_END_REASON_NONE;
int err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1);
if (err) {
file_transfer_close();
}
dev_manager_set_valid(ftp_d->dev, 1);
} else {
//有重名的, 重新获取新名称, 如:“xxx_n.mp3”,n为数字
int err = JL_CMD_send(JL_OPCODE_FILE_RENAME, NULL, 0, 1);
if (err) {
file_transfer_close();
}
}
} else {
ftp_printf("%s fail!! %d\n", __FUNCTION__, status);
if (ftp_d->file) {
//重命名失败,删除文件
printf("renam file fail, delete file\n");
fdelete(ftp_d->file);
ftp_d->file = NULL;
}
file_transfer_close();
}
}
}
//*----------------------------------------------------------------------------*/
/**@brief 文件下载结束(F->A的回复处理)
@param status:命令执行状态data:数据, len:数据长度
@return
@note
*/
/*----------------------------------------------------------------------------*/
void file_transfer_download_end(u8 status, u8 *data, u16 len)
{
if (ftp_d) {
ftp_printf("%s status %d\n", __FUNCTION__, status);
file_transfer_close();
}
}
//*----------------------------------------------------------------------------*/
/**@brief 文件传输,最后一包数据接收处理
@param data:数据内容 len:数据长度
@return
@note 文件传输流程是最后才写文件第一包数据
*/
/*----------------------------------------------------------------------------*/
static void file_transfer_download_doing_last_packet(u8 *data, u16 len)
{
u8 reason = FTP_END_REASON_NONE;
JL_ERR err = 0;
if (len > FTP_FILE_DATA_UNIT) {
printf("last packet data len err!!\n");
reason = FTP_END_REASON_DATA_OVER_LIMIT;
err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1);
if (err) {
//命令发送失败, 直接停止
file_transfer_close();
}
return ;
}
if (ftp_d->get_timeout) {
sys_timeout_del(ftp_d->get_timeout);
ftp_d->get_timeout = 0;
}
printf("get last packet ok\n");
fseek(ftp_d->file, 0, SEEK_SET);
int wlen = fwrite(ftp_d->file, data, len);
if (wlen != len) {
ftp_printf("%s err !! %d\n", __FUNCTION__, wlen);
reason = FTP_END_REASON_WRITE_ERR;//文件写异常
err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1);
if (err) {
//命令发送失败, 直接停止
file_transfer_close();
}
} else {
//文件接收完成,文件校验
file_transfer_download_file_check();
}
//fseek(ftp_d->file, ftp_d->file_offset, SEEK_SET);
}
//*----------------------------------------------------------------------------*/
/**@brief 文件传输过程处理(A->F)
@param data:数据, len:数据长度
@return
@note 此过程接收的数据是实际文件传输的内容
*/
/*----------------------------------------------------------------------------*/
void file_transfer_download_doing(u8 *data, u16 len)
{
if (ftp_d && ftp_d->file) {
ftp_printf("id = %d, len = %d\n", data[0], len - 1);
if (ftp_d->packet_id != data[0]) {
ftp_printf("warning !! packet_id err %d, %d\n", ftp_d->packet_id, data[0]);
return ;
}
len -= 1;
data += 1;
ftp_d->packet_id ++;
u8 reason = FTP_END_REASON_NONE;
int wlen = 0;
JL_ERR err = 0;
if (ftp_d->last_packet) {
file_transfer_download_doing_last_packet(data, len);
return ;
}
if (ftp_d->file_offset >= ftp_d->file_size) {
printf("err, file data is over limit!!\n");
reason = FTP_END_REASON_DATA_OVER_LIMIT;//数据超范围
err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1);
if (err) {
//命令发送失败, 直接停止
file_transfer_close();
}
return ;
}
wlen = fwrite(ftp_d->file, data, len);
if (wlen != len) {
ftp_printf("%s err !! %d\n", __FUNCTION__, wlen);
reason = FTP_END_REASON_WRITE_ERR;//文件写异常
err = JL_CMD_send(JL_OPCODE_FILE_TRANSFER_END, &reason, 1, 1);
if (err) {
//命令发送失败, 直接停止
file_transfer_close();
}
} else {
if (len != FTP_FILE_DATA_UNIT) {
ftp_printf("data is not a normal unit !!\n");
}
ftp_d->file_offset += len;
ftp_printf("ftp_d->file_offset:%d, ftp_d->file_size:%d, len:%d\n", ftp_d->file_offset, ftp_d->file_size, len);
if (ftp_d->file_offset >= ftp_d->file_size) {
ftp_printf("file recieve end!! get file first packet\n");
if (ftp_d->mark_timer) {
sys_timer_del(ftp_d->mark_timer);
ftp_d->mark_timer = 0;
}
ftp_d->last_packet = 1;
file_transfer_download_get_data();
return;
}
ftp_d->last_packet = 0;
if (ftp_d->get_timeout) {
//接收数据成功,重置一下超时
ftp_printf("reset timeout!!\n");
sys_timer_modify(ftp_d->get_timeout, FTP_FILE_DATA_RECIEVE_TIMEOUT);
}
if (ftp_d->packet_id >= ftp_d->packet_id_max) {
//该次数据包已经收完,拉取新的数据
ftp_printf("get more!!\n");
file_transfer_download_get_data();
}
}
}
}
//*----------------------------------------------------------------------------*/
/**@brief 文件传输,被动取消处理
@param OpCode_SN:数据包sn码 回复的时候用的
@return
@note
*/
/*----------------------------------------------------------------------------*/
void file_transfer_download_passive_cancel(u8 OpCode_SN, u8 *data, u16 len)
{
file_transfer_close();
printf("passive_cancel answer\n");
JL_CMD_response_send(JL_OPCODE_FILE_TRANSFER_CANCEL, JL_PRO_STATUS_SUCCESS, OpCode_SN, NULL, 0);
}
//*----------------------------------------------------------------------------*/
/**@brief 文件传输,主动取消处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void file_transfer_download_active_cancel(void)
{
if (ftp_d) {
file_transfer_close();
JL_CMD_send(JL_OPCODE_FILE_TRANSFER_CANCEL, NULL, 0, 1);
}
}
//*----------------------------------------------------------------------------*/
/**@brief 文件传输,主动取消处理回复处理
@param
@return
@note
*/
/*----------------------------------------------------------------------------*/
void file_transfer_download_active_cancel_response(u8 status, u8 *data, u16 len)
{
if (status == JL_PRO_STATUS_SUCCESS) {
printf("active_cancel_response ok!!");
}
}
//*----------------------------------------------------------------------------*/
/**@brief 文件传输关闭处理
@param
@return
@note 主要是做一些资源释放处理
*/
/*----------------------------------------------------------------------------*/
void file_transfer_close(void)
{
if (ftp_d) {
if (ftp_d->check.counter) {
printf("crc caculating !! close err\n");
return ;
}
if (ftp_d->start_timerout) {
sys_timeout_del(ftp_d->start_timerout);
ftp_d->start_timerout = 0;
}
if (ftp_d->get_timeout) {
sys_timeout_del(ftp_d->get_timeout);
ftp_d->get_timeout = 0;
}
if (ftp_d->mark_timer) {
sys_timer_del(ftp_d->mark_timer);
ftp_d->mark_timer = 0;
}
if (ftp_d->file) {
if (ftp_d->last_packet == 0) {
//文件没有传输完, 如果不是直接断电, 有机会执行更新断点续传的文件偏移信息
file_transfer_download_vaild_mark_fill(ftp_d->file, ftp_d->win, ftp_d->file_offset);
}
fclose(ftp_d->file);
}
if (ftp_d->filepath) {
free(ftp_d->filepath);
}
if (ftp_d->end_callback) {
ftp_d->end_callback();
}
free(ftp_d);
ftp_d = NULL;
printf("file_transfer_close!!!!!!\n");
}
}
//*----------------------------------------------------------------------------*/
/**@brief 文件传输启动超时处理
@param
@return
@note 响应app预处理,之后在设定时间内没有发文件传输开始命令过来触发超时
*/
/*----------------------------------------------------------------------------*/
static void file_transfer_start_timeout(void)
{
printf("%s\n", __FUNCTION__);
file_transfer_close();
}
//*----------------------------------------------------------------------------*/
/**@brief 文件传输初始化处理
@param end_callback:文件传输结束处理回调
@return
@note
*/
/*----------------------------------------------------------------------------*/
void file_transfer_init(void (*end_callback)(void))
{
if (ftp_d) {
ftp_printf("file downloading err %d!!\n", __LINE__);
return ;
}
ftp_d = zalloc(sizeof(struct __ftp_download));
if (ftp_d == NULL) {
if (end_callback) {
end_callback();
}
return ;
}
ftp_d->end_callback = end_callback;
//如果在超时时间内都没有发文件传输开始命令, 退出文件传输流程
ftp_d->start_timerout = sys_timeout_add(NULL, file_transfer_start_timeout, 2000);
}
#else
void file_transfer_init(void (*end_callback)(void))
{
}
void file_transfer_download_start(u8 OpCode_SN, u8 *data, u16 len)
{
}
void file_transfer_download_end(u8 status, u8 *data, u16 len)
{
}
void file_transfer_download_doing(u8 *data, u16 len)
{
}
void file_transfer_download_passive_cancel(u8 OpCode_SN, u8 *data, u16 len)
{
}
void file_transfer_download_active_cancel(void)
{
}
void file_transfer_download_active_cancel_response(u8 status, u8 *data, u16 len)
{
}
void file_transfer_file_rename(u8 status, u8 *data, u16 len)
{
}
void file_transfer_close(void)
{
}
#endif