TcpService = TcpServiceInit()
TcpService.start_socket_thread()
elif cmd== "1E":
- # 解析参数,支持断点重传模式(格式:URL|resume_from_byte)
+ # 解析参数,支持断点重传和写延时配置
+ # 格式:
+ # URL
+ # URL|resume_from_byte
+ # URL|resume_from_byte|write_delay_ms
parm_str = str(parm)
- if '|' in parm_str:
- # 断点重传模式:分离URL和重传位置
- parts = parm_str.split('|', 1) # 只分割第一个|符号
- if len(parts) == 2:
- url = parts[0]
- try:
- resume_from_byte = int(parts[1])
- download_file_spi(url, resume_from_byte=resume_from_byte)
- except ValueError:
- # 如果重传位置不是有效数字,使用默认值0
- download_file_spi(parts[0], resume_from_byte=0)
- else:
- # 格式错误,使用默认模式
- download_file_spi(parm_str)
- else:
- # 普通下载模式
- download_file_spi(parm_str)
+ url = parm_str
+ resume_from_byte = 0
+ write_delay_ms = 10
+
+ parts = parm_str.split('|')
+ if len(parts) >= 1 and parts[0]:
+ url = parts[0]
+ if len(parts) >= 2:
+ try:
+ resume_from_byte = int(parts[1])
+ except ValueError:
+ resume_from_byte = 0
+ if len(parts) >= 3:
+ try:
+ write_delay_ms = int(parts[2])
+ except ValueError:
+ write_delay_ms = 10
+
+ download_file_spi(url, resume_from_byte=resume_from_byte, write_delay_ms=write_delay_ms)
elif cmd == "AC":#
if self.ack_sem==1:
self.ack_sem=0
直接从固定URL下载文件并通过SPI发送,用于测试SPI传输速度
"""
- def __init__(self, url=None, timeout=30, sizeof=255, spi_obj=None, resume_from_byte=0):
+ def __init__(self, url=None, timeout=30, sizeof=255, spi_obj=None, resume_from_byte=0, write_delay_ms=10):
"""
初始化SPI传输测试
self.timeout = timeout
self.sizeof = sizeof
self.resume_from_byte = max(0, int(resume_from_byte)) # 确保非负整数
+ self.write_delay_ms = max(0, int(write_delay_ms)) # SPI写入后的延时,默认10ms
self.downloader = HttpFileDownloader(timeout=timeout, sizeof=sizeof)
# 初始化SPI对象
if hasattr(self.spi_obj, 'write'):
try:
self.spi_obj.write(tx_buffer, chunk_len)
- utime.sleep_ms(10)
+ if self.write_delay_ms > 0:
+ utime.sleep_ms(self.write_delay_ms)
except Exception as e:
clog.error("SPI write error: {}".format(e))
self.close()
# ==================== 外部接口函数 ====================
# 提供简单的函数接口,可以从外部传入URL进行下载和SPI传输
-def download_file_spi(url, timeout=30, sizeof=255, spi_obj=None, resume_from_byte=0):
+def download_file_spi(url, timeout=30, sizeof=255, spi_obj=None, resume_from_byte=0, write_delay_ms=10):
"""
下载文件并通过SPI传输的简单接口函数
clog.error("download_file_spi: Invalid URL parameter")
return False, 0.0, -1
- test = HttpFileDownloadSpiTest(url=url, timeout=timeout, sizeof=sizeof, spi_obj=spi_obj, resume_from_byte=resume_from_byte)
+ test = HttpFileDownloadSpiTest(url=url, timeout=timeout, sizeof=sizeof, spi_obj=spi_obj, resume_from_byte=resume_from_byte, write_delay_ms=write_delay_ms)
try:
success, download_time, file_size = test.start_download_and_send()
if success:
const char *file_path = (strlen(g_download_file_path) > 0) ? g_download_file_path : NULL;
// 调用断点重传函数
- int resume_ret = http_file_download_resume(g_download_url, file_path, g_total_received_bytes, 0);
+ int resume_ret = http_file_download_resume(g_download_url, file_path, g_total_received_bytes, 0, 0);
if (resume_ret != 0) {
cat1_print_err("HTTP download: Failed to resume download, error: %d\n", resume_ret);
* 3. 使用信号量阻塞等待下载完成
* 4. 下载完成后关闭文件并返回
*/
-int http_file_download_start(const char *url, const char *file_path, uint32_t timeout_ms)
+int http_file_download_start(const char *url, const char *file_path, uint32_t timeout_ms, uint32_t write_delay_ms)
{
if (url == NULL || strlen(url) == 0) {
cat1_print_err("HTTP file download: Invalid URL\n");
cat1_print_info("HTTP file download: Timeout timer restarted (%u ms)\n", g_download_timeout_ms);
}
- // 通过UDP发送下载指令到CAT1(携带URL地址)
- udp_send_msg_toCat1(UDP_CMD_HTTP_FILE_DOWNLOAD, (char *)url);
+ // 通过UDP发送下载指令到CAT1,附带写延时参数(格式:URL|resume_from_byte|write_delay_ms)
+ char udp_msg[1024] = {0};
+ int msg_len = snprintf(udp_msg, sizeof(udp_msg), "%s|%u|%u", url, 0u, write_delay_ms);
+ if (msg_len < 0 || msg_len >= (int)sizeof(udp_msg)) {
+ cat1_print_err("HTTP file download: Failed to format UDP message\n");
+ g_download_state = HTTP_DOWNLOAD_STATE_IDLE;
+ return -1;
+ }
+ udp_send_msg_toCat1(UDP_CMD_HTTP_FILE_DOWNLOAD, udp_msg);
cat1_print_info("HTTP file download: Download command sent, waiting for completion...\n");
* 3. 使用信号量阻塞等待下载完成
* 4. 下载完成后关闭文件并返回
*/
-int http_file_download_start_with_resume(const char *url, const char *file_path, uint32_t resume_from_byte, uint32_t timeout_ms)
+int http_file_download_start_with_resume(const char *url, const char *file_path, uint32_t resume_from_byte, uint32_t timeout_ms, uint32_t write_delay_ms)
{
if (url == NULL || strlen(url) == 0) {
cat1_print_err("HTTP file download: Invalid URL\n");
cat1_print_info("HTTP file download: Timeout timer restarted (%u ms)\n", g_download_timeout_ms);
}
- // 通过UDP发送下载指令到CAT1
- if (resume_from_byte > 0) {
- // 断点重传:发送URL|resume_from_byte格式
- char udp_msg[1024] = {0};
- int msg_len = snprintf(udp_msg, sizeof(udp_msg), "%s|%u", url, resume_from_byte);
- if (msg_len < 0 || msg_len >= (int)sizeof(udp_msg)) {
- cat1_print_err("HTTP file download: Failed to format UDP message\n");
- if (g_download_file_fd >= 0) {
- close(g_download_file_fd);
- g_download_file_fd = -1;
- }
- return -1;
+ // 通过UDP发送下载指令到CAT1,附带写延时参数
+ char udp_msg[1024] = {0};
+ int msg_len = snprintf(udp_msg, sizeof(udp_msg), "%s|%u|%u", url, resume_from_byte, write_delay_ms);
+ if (msg_len < 0 || msg_len >= (int)sizeof(udp_msg)) {
+ cat1_print_err("HTTP file download: Failed to format UDP message\n");
+ if (g_download_file_fd >= 0) {
+ close(g_download_file_fd);
+ g_download_file_fd = -1;
}
- udp_send_msg_toCat1(UDP_CMD_HTTP_FILE_DOWNLOAD, udp_msg);
- cat1_print_info("HTTP file download: Resume command sent (URL: %s, resume from byte: %u)\n", url, resume_from_byte);
- } else {
- // 从头下载:只发送URL
- udp_send_msg_toCat1(UDP_CMD_HTTP_FILE_DOWNLOAD, (char *)url);
- cat1_print_info("HTTP file download: Download command sent\n");
+ return -1;
}
+ udp_send_msg_toCat1(UDP_CMD_HTTP_FILE_DOWNLOAD, udp_msg);
+ cat1_print_info("HTTP file download: Download command sent (URL: %s, resume from byte: %u, write delay: %u ms)\n", url, resume_from_byte, write_delay_ms);
cat1_print_info("HTTP file download: Waiting for completion...\n");
* - 文件会在下载完成或出错时由回调函数自动关闭
* - 可以通过 http_file_download_get_state() 查询下载状态
*/
-int http_file_download_resume(const char *url, const char *file_path, uint32_t resume_from_byte, uint32_t timeout_ms)
+int http_file_download_resume(const char *url, const char *file_path, uint32_t resume_from_byte, uint32_t timeout_ms, uint32_t write_delay_ms)
{
if (url == NULL || strlen(url) == 0) {
cat1_print_err("HTTP file download resume: Invalid URL\n");
// 格式化UDP消息:URL|resume_from_byte
char udp_msg[1024] = {0};
- int msg_len = snprintf(udp_msg, sizeof(udp_msg), "%s|%u", url, resume_from_byte);
+ int msg_len = snprintf(udp_msg, sizeof(udp_msg), "%s|%u|%u", url, resume_from_byte, write_delay_ms);
if (msg_len < 0 || msg_len >= (int)sizeof(udp_msg)) {
cat1_print_err("HTTP file download resume: Failed to format UDP message\n");
if (g_download_file_fd >= 0) {
* @param url 要下载的文件URL
* @param file_path 保存文件的路径,NULL或空字符串表示不保存文件(仅接收数据)
* @param timeout_ms 超时时间(毫秒),0表示使用默认值(300秒)
+ * @param write_delay_ms SPI写入后的延时(毫秒),0表示使用默认(10ms)
* @return 0成功,-1失败
*
* 此函数会:
* 3. 使用信号量阻塞等待下载完成
* 4. 下载完成后关闭文件并返回
*/
-int http_file_download_start(const char *url, const char *file_path, uint32_t timeout_ms);
+int http_file_download_start(const char *url, const char *file_path, uint32_t timeout_ms, uint32_t write_delay_ms);
/**
* @brief 开始HTTP文件下载(阻塞接口,支持断点重传)
* @param file_path 保存文件的路径,NULL或空字符串表示不保存文件(仅接收数据)
* @param resume_from_byte 断点重传起始字节位置(0表示从头开始下载)
* @param timeout_ms 超时时间(毫秒),0表示使用默认值(300秒)
+ * @param write_delay_ms SPI写入后的延时(毫秒),0表示使用默认(10ms)
* @return 0成功,-1失败
*
* 此函数会:
* 3. 使用信号量阻塞等待下载完成
* 4. 下载完成后关闭文件并返回
*/
-int http_file_download_start_with_resume(const char *url, const char *file_path, uint32_t resume_from_byte, uint32_t timeout_ms);
+int http_file_download_start_with_resume(const char *url, const char *file_path, uint32_t resume_from_byte, uint32_t timeout_ms, uint32_t write_delay_ms);
/**
* @brief 开始HTTP文件断点重传(非阻塞接口)
* @param file_path 保存文件的路径,NULL或空字符串表示不保存文件(仅接收数据)
* @param resume_from_byte 断点重传起始字节位置(从该位置继续下载)
* @param timeout_ms 超时时间(毫秒),此参数已废弃,保留用于兼容性
+ * @param write_delay_ms SPI写入后的延时(毫秒),0表示使用默认(10ms)
* @return 0成功,-1失败
*
* 此函数会:
* - 文件会在下载完成或出错时由回调函数自动关闭
* - 可以通过 http_file_download_get_state() 查询下载状态
*/
-int http_file_download_resume(const char *url, const char *file_path, uint32_t resume_from_byte, uint32_t timeout_ms);
+int http_file_download_resume(const char *url, const char *file_path, uint32_t resume_from_byte, uint32_t timeout_ms, uint32_t write_delay_ms);
/**
* @brief 通知下载完成(由外部调用,例如从CAT1收到完成消息时)
cat1_print_info("Timeout: %u ms (%u seconds)\n", timeout_ms, timeout_ms / 1000);
// 开始下载(阻塞接口)
- int result = http_file_download_start("https://file-virtual-person-qcl.test.leiniao.com/ambybox/Emotions/StraightEyes/Amber/WorkAndStudy.mp4", actual_file_path, timeout_ms);
+ int result = http_file_download_start("https://file-virtual-person-qcl.test.leiniao.com/ambybox/Emotions/StraightEyes/Amber/WorkAndStudy.mp4", actual_file_path, timeout_ms, 10);
if (result == 0) {
// 获取统计信息
cat1_print_info("HTTPDLCLIENT: No file path provided, data will not be saved\n");
// 使用新的SPI传输接口(不保存文件)
- int result = http_file_download_start(url, NULL, 0); // 使用默认超时时间,不保存文件
+ int result = http_file_download_start(url, NULL, 0, 10); // 使用默认超时时间,不保存文件
if (result == 0) {
uint32_t total_bytes, total_packets;
const char *story_theme = "冒险"; // 默认主题
// 解析参数
- if (para != NULL && paraLen > 0) {
- uint8_t argv[LN_MAX_ARGC][LN_MAX_ARGV_LEN] = {0};
- uint32_t argc = 0;
+ // if (para != NULL && paraLen > 0) {
+ // uint8_t argv[LN_MAX_ARGC][LN_MAX_ARGV_LEN] = {0};
+ // uint32_t argc = 0;
- if (ConvertCmdToParam(para, paraLen, argv, &argc) == LN_SUCCESS && argc >= 1) {
- story_theme = (const char *)argv[0];
- }
- }
+ // if (ConvertCmdToParam(para, paraLen, argv, &argc) == LN_SUCCESS && argc >= 1) {
+ // story_theme = (const char *)argv[0];
+ // }
+ // }
printf("[LN][WS_SEND_RANDOM_STORY] Sending random story request with theme: %s\n", story_theme);
uapi_ln_add_vote();
// int ret = uapi_ln_download_file_resume(url, save_path);
- int ret = http_file_download_start(url, save_path, 300*100);
+ int ret = http_file_download_start(url, save_path, 300*100, 10);
if (ERRCODE_SUCC != ret)
{
for (int i = 1; i <= max_retries; i++)
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD_RESUME_WITH_RETRY] 重试 %d/%d", i, max_retries);
// ret = uapi_ln_download_file_resume(url, save_path);
- ret = http_file_download_start(url, save_path, 300*100);
+ ret = http_file_download_start(url, save_path, 300*100, 10);
if (ERRCODE_SUCC == ret)
{
WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "[DOWNLOAD_RESUME_WITH_RETRY] 重试成功 %d", i);
}
// 开始下载,超时时间设置为300秒(300*1000毫秒)
- int ret = http_file_download_start(full_url, save_path, 300*1000);
+ int ret = http_file_download_start(full_url, save_path, 300*1000, 10);
// 反初始化HTTP文件下载服务
http_file_download_deinit();
WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "[HTTP_DL] Download service already initialized");
return 0;
}
+ cat_sync_timer_control(0);
+
int ret = http_file_download_init(ln_http_download_data_callback);
if (ret == 0) {
g_py_ver, LN_HTTP_DOWNLOAD_MIN_PY_VER);
return;
}
+ cat_sync_timer_control(1);
+
if (!g_download_service_initialized) {
WEARABLE_LOGW(WEARABLE_LOG_MODULE_APP, "[HTTP_DL] Download service not initialized");
url, timeout_ms);
// file_path传入NULL,不写入文件,数据通过内部回调处理
- int ret = http_file_download_start(url, NULL, timeout_ms);
+ int ret = http_file_download_start(url, NULL, timeout_ms, 10);
if (ret == 0) {
// 获取下载统计信息
}
// file_path传入NULL,不写入文件,数据通过内部回调处理
- int ret = http_file_download_start_with_resume(url, NULL, resume_from_byte, timeout_ms);
+ int ret = http_file_download_start_with_resume(url, NULL, resume_from_byte, timeout_ms, 10);
if (ret == 0) {
// 获取下载统计信息
}
// 验证数据长度合理性(应该在0到SPI_PACKET_DATA_SIZE之间)
- if (data_len > SPI_PACKET_DATA_SIZE || data_len==0) {
+ if (data_len > SPI_PACKET_DATA_SIZE ) {
printf("SPI packet error: invalid data length %u (max: %u)\n",
data_len, SPI_PACKET_DATA_SIZE);
total_byte_error_cnt++;