1. 解决本地注册设备的流程无法正常控制设备的问题

2. 修改之前的 版本固件命名不对的问题
3. 增加debug kit,但是默认不开启(还在调试中)
This commit is contained in:
2025-11-04 21:24:15 +08:00
parent 21c6d05bad
commit 8270708ef2
27 changed files with 893 additions and 34 deletions

View File

@@ -665,8 +665,9 @@ int hilink_ble_main(void)
#endif
/* 启动Hilink SDK */
if (HILINK_Main() != 0) {
HILINK_SAL_NOTICE("HILINK_Main start error");
ret = HILINK_Main();
if (ret != 0) {
HILINK_SAL_NOTICE("HILINK_Main start error:%d\r\n", ret);
return -1;
}
e_printf("HILINK_Main start success\r\n");

View File

@@ -20,9 +20,9 @@
#include "hilink_entry.h"
#endif
extern void handle_device_online(void);
extern void handle_device_unbind(void);
extern void handle_device_offline(void);
extern void handle_device_register(void);
extern void handle_device_unregister(void);
extern int myhandle_put_brightness(const char* svc_id, const char* payload, unsigned int len);
extern int myhandle_put_cct(const char* svc_id, const char* payload, unsigned int len);
@@ -598,7 +598,6 @@ void HILINK_NotifyDevStatus(int status)
BLE_CfgNetAdvCtrl(0);
(void)BLE_CfgNetAdvCtrl(0xFFFFFFFF);
#endif
handle_device_offline();
break;
case HILINK_M2M_CLOUD_ONLINE:
/* 设备连接云端成功,请在此处添加实现 */
@@ -607,8 +606,6 @@ void HILINK_NotifyDevStatus(int status)
BLE_CfgNetAdvCtrl(0);
(void)BLE_CfgNetAdvCtrl(0xFFFFFFFF);
#endif
/* 设备连接云端成功,请在此处添加实现 */
handle_device_online(); // 处理设备上线
break;
case HILINK_M2M_LONG_OFFLINE:
/* 设备与云端连接长时间断开,请在此处添加实现 */
@@ -632,7 +629,6 @@ void HILINK_NotifyDevStatus(int status)
case HILINK_LINK_CONNECTED_WIFI:
/* 设备已经连上路由器,请在此处添加实现 */
hf_set_wifi_state(1);
handle_device_online();
break;
case HILINK_M2M_CONNECTTING_CLOUD:
/* 设备正在连接云端,请在此处添加实现 */
@@ -642,14 +638,17 @@ void HILINK_NotifyDevStatus(int status)
hf_set_wifi_state(0);
break;
case HILINK_DEVICE_REGISTERED:
/* 设备被注册,请在此处添加实现 */
/* 设备被注册:退出配网逻辑并完成绑定后的处理 */
handle_device_register();
break;
case HILINK_DEVICE_UNREGISTER:
/* 设备被解绑,请在此处添加实现 */
/* 设备被解绑:先执行解绑/下线处理,再做解绑清理 */
handle_device_unregister();
handle_device_unbind();
break;
case HILINK_REVOKE_FLAG_SET:
/* 设备被复位标记置位,请在此处添加实现 */
handle_device_unregister();
handle_device_unbind();
break;
case HILINK_NEGO_REG_INFO_FAIL:

View File

@@ -9,6 +9,13 @@ set(SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/spotlight/spotlight_main.c
${CMAKE_CURRENT_SOURCE_DIR}/spotlight/device_module.c
${CMAKE_CURRENT_SOURCE_DIR}/spotlight/factory_test.c
${CMAKE_CURRENT_SOURCE_DIR}/debug_kit/core/dk_service.c
${CMAKE_CURRENT_SOURCE_DIR}/debug_kit/core/dk_manager.c
${CMAKE_CURRENT_SOURCE_DIR}/debug_kit/core/dk_wifi_scanner.c
${CMAKE_CURRENT_SOURCE_DIR}/debug_kit/core/dk_tcp_console.c
${CMAKE_CURRENT_SOURCE_DIR}/debug_kit/core/dk_http_ota.c
${CMAKE_CURRENT_SOURCE_DIR}/debug_kit/core/dk_udp_announce.c
${CMAKE_CURRENT_SOURCE_DIR}/debug_kit/core/dk_ring.c
)
if (DEFINES MATCHES "CONFIG_SPOTLIGHT_UT")
list(APPEND SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/spotlight/spotlight_ut.c)
@@ -20,6 +27,7 @@ endif()
set(PUBLIC_HEADER
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/spotlight/
${CMAKE_CURRENT_SOURCE_DIR}/debug_kit/include
)
set(PRIVATE_HEADER

View File

@@ -7,10 +7,26 @@
*/
#include "hsf.h"
#include "errcode.h"
#include "systick.h"
#include "debug_kit/include/debug_kit.h"
#include "spotlight.h"
#ifdef HF_MCU_OTA
#include "mcu_update.h"
#endif
static void *dk_delayed_start(const char *arg)
{
(void)arg;
unsigned int wait_ms = 0;
while (!hf_hilink_main_is_runing()) {
msleep(100);
if ((wait_ms += 100) > 10000) { break; }
}
msleep(300);
debug_kit_init();
return NULL;
}
int g_module_id = HFM_TYPE_LPT262;
const int hf_lpt_262_gpio_fid_to_pid_map_table[HFM_MAX_FUNC_CODE]=
{
@@ -223,6 +239,8 @@ int USER_FUNC user_app_main(void)
HF_Debug(DEBUG_WARN,"start uart fail!\r\n");
}
spotlight_main();
// 延后启动 debug kit等待 HiLink Main 运行后再启动,避免启动期资源竞争
// dk_delayed_start(NULL);
#ifdef HF_MCU_OTA
if(hf_mcu_init() != HF_SUCCESS)
HF_Debug(DEBUG_WARN,"init mcu ota fail!\r\n");

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,50 @@
#ifndef DK_CONFIG_H
#define DK_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DBG_SCAN_PERIOD_S
#define DBG_SCAN_PERIOD_S 10
#endif
#ifndef DBG_SCAN_DWELL_MS
#define DBG_SCAN_DWELL_MS 100
#endif
#ifndef DBG_CPU_BUSY_PCT
#define DBG_CPU_BUSY_PCT 60
#endif
#ifndef DBG_LWIP_Q_BUSY_PCT
#define DBG_LWIP_Q_BUSY_PCT 80
#endif
#ifndef DBG_CONSOLE_PORT
#define DBG_CONSOLE_PORT 2323
#endif
#ifndef DBG_OTA_PORT
#define DBG_OTA_PORT 8070
#endif
#ifndef DBG_BROADCAST_PORT
#define DBG_BROADCAST_PORT 37501
#endif
#ifndef DBG_RING_KB
#define DBG_RING_KB 16
#endif
#ifndef DBG_CONSOLE_RATE_KBPS
#define DBG_CONSOLE_RATE_KBPS 100
#endif
#ifndef DBG_FIRST_CONN_TIMEOUT_S
#define DBG_FIRST_CONN_TIMEOUT_S 300
#endif
#define DBG_TRIGGER_SSID "EK_HF_DEBUG"
typedef enum {
DBG_STATE_CLOSED = 0,
DBG_STATE_DEBUG = 1,
} dbg_state_t;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,176 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "securec.h"
#include "soc_osal.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include "dk_config.h"
#include "debug_kit.h"
#include "errcode.h"
#include "upg_definitions.h"
#include "upg_common.h"
#include "upg_verify.h"
#include "upg_alloc.h"
static volatile bool g_http_running = false;
static bool g_upg_ready = false;
static bool ensure_upg_ready(void)
{
if (g_upg_ready) return true;
extern errcode_t ws63_upg_init(void);
errcode_t rc = ws63_upg_init();
if (rc == ERRCODE_SUCC) { g_upg_ready = true; return true; }
return false;
}
static int send_text(int fd, int code, const char *status, const char *body)
{
char hdr[256];
int n = snprintf(hdr, sizeof(hdr),
"HTTP/1.1 %d %s\r\nContent-Type: text/plain\r\nContent-Length: %u\r\nConnection: close\r\n\r\n",
code, status, (unsigned)strlen(body));
(void)lwip_send(fd, hdr, n, 0);
(void)lwip_send(fd, body, (int)strlen(body), 0);
return 0;
}
static int send_json(int fd, int code, const char *status, const char *json)
{
char hdr[256];
int n = snprintf(hdr, sizeof(hdr),
"HTTP/1.1 %d %s\r\nContent-Type: application/json\r\nContent-Length: %u\r\nConnection: close\r\n\r\n",
code, status, (unsigned)strlen(json));
(void)lwip_send(fd, hdr, n, 0);
(void)lwip_send(fd, json, (int)strlen(json), 0);
return 0;
}
static int read_line(int fd, char *buf, int max)
{
int i = 0;
while (i < max - 1) {
char c; int n = lwip_recv(fd, &c, 1, 0);
if (n <= 0) return -1;
if (c == '\r') { continue; }
if (c == '\n') { break; }
buf[i++] = c;
}
buf[i] = 0; return i;
}
static int read_exact(int fd, char *buf, int len)
{
int got = 0; while (got < len) { int n = lwip_recv(fd, buf + got, len - got, 0); if (n <= 0) return -1; got += n; } return 0;
}
static void handle_client(int cfd)
{
char line[256];
if (read_line(cfd, line, sizeof(line)) <= 0) { lwip_close(cfd); return; }
char method[8] = {0}, path[64] = {0};
(void)sscanf(line, "%7s %63s", method, path);
DK_LOGI("HTTP %s %s", method, path);
int content_len = 0;
while (1) {
int r = read_line(cfd, line, sizeof(line));
if (r <= 0) { lwip_close(cfd); return; }
if (r == 0) break;
if (strncasecmp(line, "Content-Length:", 15) == 0) content_len = atoi(line + 15);
}
if (strcmp(method, "POST") == 0 && strcmp(path, "/ota/prepare") == 0) {
if (!ensure_upg_ready()) { send_text(cfd, 503, "Service Unavailable", "ERR_UPG_INIT"); goto end; }
if (content_len <= 0 || content_len > 256) { send_text(cfd, 400, "Bad Request", "ERR_INVALID_ARGS"); goto end; }
char body[256] = {0};
if (read_exact(cfd, body, content_len) != 0) { goto end; }
char *p = strstr(body, "length");
if (p == NULL) { send_text(cfd, 400, "Bad Request", "ERR_INVALID_ARGS"); goto end; }
uint32_t len = (uint32_t)atoi(p + 7);
upg_prepare_info_t info = {0}; info.package_len = len;
errcode_t ret = uapi_upg_prepare(&info);
DK_LOGI("OTA prepare len=%u ret=%d", (unsigned)len, (int)ret);
if (ret != ERRCODE_SUCC) { send_text(cfd, 500, "Internal", "ERR_INTERNAL"); } else { send_text(cfd, 200, "OK", "OK"); }
goto end;
}
if (strcmp(method, "PUT") == 0 && strncmp(path, "/ota/chunk", 10) == 0) {
if (!ensure_upg_ready()) { send_text(cfd, 503, "Service Unavailable", "ERR_UPG_INIT"); goto end; }
char *q = strstr(path, "offset="); if (!q) { send_text(cfd, 400, "Bad Request", "ERR_INVALID_ARGS"); goto end; }
uint32_t offset = (uint32_t)atoi(q + 7);
if (content_len <= 0 || (content_len % 4) != 0) { send_text(cfd, 400, "Bad Request", "ERR_INVALID_ARGS"); goto end; }
char *buf = (char *)malloc((size_t)content_len); if (!buf) { send_text(cfd, 500, "Internal", "ERR_INTERNAL"); goto end; }
if (read_exact(cfd, buf, content_len) != 0) { free(buf); goto end; }
errcode_t ret = uapi_upg_write_package_sync(offset, (const uint8_t *)buf, (uint16_t)content_len);
DK_LOGI("OTA chunk offset=%u len=%d ret=%d", (unsigned)offset, content_len, (int)ret);
free(buf);
if (ret != ERRCODE_SUCC) { send_text(cfd, 409, "Conflict", "ERR_STATE"); } else { send_text(cfd, 200, "OK", "OK"); }
goto end;
}
if (strcmp(method, "POST") == 0 && strcmp(path, "/ota/commit") == 0) {
if (!ensure_upg_ready()) { send_text(cfd, 503, "Service Unavailable", "ERR_UPG_INIT"); goto end; }
upg_package_header_t *hdr = NULL; errcode_t ret = upg_get_package_header(&hdr);
if (ret != ERRCODE_SUCC || hdr == NULL) { send_text(cfd, 409, "Conflict", "ERR_STATE"); goto end; }
ret = uapi_upg_verify_file(hdr); if (ret != ERRCODE_SUCC) { DK_LOGE("OTA verify failed ret=%d", (int)ret); send_text(cfd, 422, "Unprocessable", "ERR_VERIFY_FAILED"); upg_free(hdr); goto end; }
upg_free(hdr);
ret = uapi_upg_request_upgrade(true);
DK_LOGI("OTA commit ret=%d (device may reboot)", (int)ret);
if (ret != ERRCODE_SUCC) { send_text(cfd, 500, "Internal", "ERR_INTERNAL"); } else { send_text(cfd, 200, "OK", "OK"); }
goto end;
}
if (strcmp(method, "GET") == 0 && strcmp(path, "/ota/status") == 0) {
if (!ensure_upg_ready()) { send_text(cfd, 503, "Service Unavailable", "ERR_UPG_INIT"); goto end; }
upg_status_t st = uapi_upg_get_status(); const char *s = "NONE";
if (st == UPG_STATUS_UPDATING) s = "UPDATING"; else if (st == UPG_STATUS_SUCC) s = "SUCC"; else if (st == UPG_STATUS_FAIL) s = "FAIL";
char json[64]; (void)snprintf(json, sizeof(json), "{\"status\":\"%s\"}", s);
send_json(cfd, 200, "OK", json); goto end;
}
send_text(cfd, 404, "Not Found", "NOT_FOUND");
end:
lwip_close(cfd);
}
static void *http_server_task(const char *arg)
{
(void)arg;
int sfd = lwip_socket(AF_INET, SOCK_STREAM, 0);
if (sfd < 0) return NULL;
int on = 1; (void)lwip_setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
struct sockaddr_in addr = {0}; addr.sin_family = AF_INET; addr.sin_addr.s_addr = lwip_htonl(INADDR_ANY);
int base = DBG_OTA_PORT; int bound_port = 0;
for (int i = 0; i < 10; i++) { addr.sin_port = lwip_htons((uint16_t)(base + i)); if (lwip_bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) == 0) { bound_port = base + i; break; } }
if (bound_port == 0) { lwip_close(sfd); return NULL; }
dbg_set_ota_port(bound_port);
DK_LOGI("HTTP OTA listening on %d", bound_port);
(void)lwip_listen(sfd, 2);
g_http_running = true;
while (g_http_running) {
struct sockaddr_in cli; socklen_t cl = sizeof(cli);
int cfd = lwip_accept(sfd, (struct sockaddr *)&cli, &cl);
if (cfd < 0) continue;
debug_service_on_first_client_connected();
DK_LOGI("HTTP OTA client %s:%u", inet_ntoa(cli.sin_addr), (unsigned)lwip_ntohs(cli.sin_port));
handle_client(cfd);
}
lwip_close(sfd);
return NULL;
}
void http_ota_start(void)
{
osal_kthread_lock();
osal_task *task = osal_kthread_create((osal_kthread_handler)http_server_task, 0,
"dk_http", 0x1200);
if (task != NULL) { (void)osal_kthread_set_priority(task, 30); osal_kfree(task); }
osal_kthread_unlock();
}
void http_ota_stop(void)
{
g_http_running = false;
}

View File

@@ -0,0 +1,7 @@
#ifndef DK_HTTP_OTA_H
#define DK_HTTP_OTA_H
void http_ota_start(void);
void http_ota_stop(void);
#endif

View File

@@ -0,0 +1,102 @@
#include <string.h>
#include "securec.h"
#include "osal_task.h"
#include "soc_osal.h"
#include "systick.h"
#include "dk_manager.h"
#include "debug_kit.h"
#include "dk_wifi_scanner.h"
#include "dk_tcp_console.h"
#include "dk_http_ota.h"
#include "dk_udp_announce.h"
#include "dk_ring.h"
typedef struct {
dbg_state_t state;
uint64_t enter_time_ms;
uint64_t last_activity_ms;
bool first_conn_timer_active;
} dbg_ctx_t;
static dbg_ctx_t g_dbg = {0};
static void enter_debug_mode(void)
{
if (g_dbg.state == DBG_STATE_DEBUG) return;
dbg_ring_init();
g_dbg.state = DBG_STATE_DEBUG;
g_dbg.enter_time_ms = uapi_systick_get_ms();
g_dbg.first_conn_timer_active = true;
DK_LOGI("enter debug mode, window %us", (unsigned)DBG_FIRST_CONN_TIMEOUT_S);
udp_announce_start();
tcp_console_start();
http_ota_start();
}
static void exit_debug_mode(void)
{
if (g_dbg.state != DBG_STATE_DEBUG) return;
http_ota_stop();
tcp_console_stop();
udp_announce_stop();
g_dbg.state = DBG_STATE_CLOSED;
g_dbg.first_conn_timer_active = false;
DK_LOGI("exit debug mode");
}
static void *debug_manager_task(const char *arg)
{
(void)arg;
g_dbg.state = DBG_STATE_CLOSED;
g_dbg.enter_time_ms = 0;
g_dbg.first_conn_timer_active = false;
wifi_scanner_start();
DK_LOGI("manager started");
while (1) {
osal_msleep(50);
if (g_dbg.state == DBG_STATE_DEBUG && g_dbg.first_conn_timer_active) {
uint64_t now = uapi_systick_get_ms();
if (now - g_dbg.enter_time_ms > (uint64_t)DBG_FIRST_CONN_TIMEOUT_S * 1000ULL) {
DK_LOGW("first-conn timeout, closing debug mode");
exit_debug_mode();
}
}
}
return NULL;
}
void debug_manager_init(void)
{
osal_kthread_lock();
osal_task *task = osal_kthread_create((osal_kthread_handler)debug_manager_task, 0,
"dk_mgr", 0x1000);
if (task != NULL) {
(void)osal_kthread_set_priority(task, 29);
osal_kfree(task);
}
osal_kthread_unlock();
}
void debug_manager_notify_ssid_hit(bool sta_connected)
{
DK_LOGI("trigger SSID hit (sta_connected=%d)", sta_connected ? 1 : 0);
enter_debug_mode();
}
void debug_manager_notify_client_activity(void)
{
g_dbg.first_conn_timer_active = false;
DK_LOGI("first-conn window closed by client activity");
}
bool debug_manager_is_debug(void)
{
return g_dbg.state == DBG_STATE_DEBUG;
}
void debug_manager_force_exit(void)
{
exit_debug_mode();
}

View File

@@ -0,0 +1,22 @@
#ifndef DK_MANAGER_H
#define DK_MANAGER_H
#include <stdbool.h>
#include <stdint.h>
#include "dk_config.h"
#ifdef __cplusplus
extern "C" {
#endif
void debug_manager_init(void);
void debug_manager_notify_ssid_hit(bool sta_connected);
void debug_manager_notify_client_activity(void);
bool debug_manager_is_debug(void);
void debug_manager_force_exit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,100 @@
#include <string.h>
#include <stdlib.h>
#include "securec.h"
#include "dk_config.h"
#include "systick.h"
#include "debug_kit.h"
#define RB_IDX_CAP 2048
typedef struct __attribute__((packed)) {
uint32_t ts_ms;
uint16_t len;
} rec_hdr_t;
static uint8_t *g_rb;
static uint32_t g_rb_size;
static uint32_t g_head;
static uint32_t g_idx[RB_IDX_CAP];
static uint32_t g_idx_head;
static int g_mirror_level = 2;
static inline uint64_t now_ms(void) { return uapi_systick_get_ms(); }
void dbg_ring_init(void)
{
if (g_rb == NULL) {
static const uint32_t try_kb[] = { DBG_RING_KB, 24, 16, 8, 4 };
for (unsigned i = 0; i < sizeof(try_kb)/sizeof(try_kb[0]); i++) {
uint32_t sz = try_kb[i] * 1024U;
if (sz == 0) continue;
uint8_t *p = (uint8_t *)malloc(sz);
if (p) {
g_rb = p;
g_rb_size = sz;
(void)memset_s(g_rb, g_rb_size, 0, g_rb_size);
break;
}
}
if (g_rb) {
DK_LOGI("log ring init, size=%uKB", (unsigned)(g_rb_size / 1024U));
} else {
DK_LOGW("log ring alloc failed");
}
}
g_head = 0; g_idx_head = 0;
}
void dbg_console_mirror_set_level(int level)
{
g_mirror_level = level;
}
void dbg_ring_write(const char *buf, unsigned int len)
{
if (!g_rb || !buf || len == 0) return;
rec_hdr_t h = { .ts_ms = (uint32_t)now_ms(), .len = (uint16_t)(len > 1024 ? 1024 : len) };
unsigned int need = sizeof(h) + h.len;
if (g_rb_size == 0 || need > g_rb_size) return;
if (g_head + need > g_rb_size) g_head = 0;
(void)memcpy_s(&g_rb[g_head], g_rb_size - g_head, &h, sizeof(h));
(void)memcpy_s(&g_rb[g_head + sizeof(h)], g_rb_size - g_head - sizeof(h), buf, h.len);
g_idx[g_idx_head % RB_IDX_CAP] = g_head;
g_idx_head++;
g_head += need;
}
static unsigned int output_from(uint32_t off, int (*out_fn)(const char *, unsigned int))
{
rec_hdr_t h; (void)memcpy_s(&h, sizeof(h), &g_rb[off], sizeof(h));
const char *p = (const char *)&g_rb[off + sizeof(h)];
return (unsigned int)out_fn(p, h.len);
}
unsigned int dbg_ring_tail_lines(unsigned int n, int (*out_fn)(const char *, unsigned int))
{
if (!g_rb || !out_fn) return 0;
unsigned int emitted = 0;
unsigned int count = (g_idx_head > RB_IDX_CAP) ? RB_IDX_CAP : g_idx_head;
if (n > count) n = count;
for (int i = (int)g_idx_head - (int)n; i < (int)g_idx_head; i++) {
uint32_t off = g_idx[(uint32_t)i % RB_IDX_CAP];
emitted += output_from(off, out_fn);
}
return emitted;
}
unsigned int dbg_ring_dump_seconds(unsigned int seconds, int (*out_fn)(const char *, unsigned int))
{
if (!g_rb || !out_fn) return 0;
uint32_t threshold = (uint32_t)(now_ms() - (uint64_t)seconds * 1000ULL);
unsigned int emitted = 0;
unsigned int count = (g_idx_head > RB_IDX_CAP) ? RB_IDX_CAP : g_idx_head;
for (int i = (int)g_idx_head - 1; i >= (int)g_idx_head - (int)count; i--) {
uint32_t off = g_idx[(uint32_t)i % RB_IDX_CAP];
rec_hdr_t h; (void)memcpy_s(&h, sizeof(h), &g_rb[off], sizeof(h));
if (h.ts_ms < threshold) break;
emitted += output_from(off, out_fn);
}
return emitted;
}

View File

@@ -0,0 +1,12 @@
#ifndef DK_RING_H
#define DK_RING_H
#include <stdint.h>
void dbg_ring_init(void);
void dbg_ring_write(const char *buf, unsigned int len);
unsigned int dbg_ring_tail_lines(unsigned int n, int (*out_fn)(const char *, unsigned int));
unsigned int dbg_ring_dump_seconds(unsigned int seconds, int (*out_fn)(const char *, unsigned int));
void dbg_console_mirror_set_level(int level);
#endif

View File

@@ -0,0 +1,38 @@
#include "dk_config.h"
#include "debug_kit.h"
#include "dk_manager.h"
static int g_dbg_console_port = DBG_CONSOLE_PORT;
static int g_dbg_ota_port = DBG_OTA_PORT;
void debug_kit_init(void)
{
debug_manager_init();
DK_LOGI("init");
}
void debug_service_on_first_client_connected(void)
{
debug_manager_notify_client_activity();
DK_LOGI("first client activity");
}
int dbg_get_console_port(void)
{
return g_dbg_console_port;
}
int dbg_get_ota_port(void)
{
return g_dbg_ota_port;
}
void dbg_set_console_port(int port)
{
if (port > 0) g_dbg_console_port = port;
}
void dbg_set_ota_port(int port)
{
if (port > 0) g_dbg_ota_port = port;
}

View File

@@ -0,0 +1,129 @@
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include "securec.h"
#include "soc_osal.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include "dk_config.h"
#include "debug_kit.h"
#include "dk_manager.h"
#include "dk_ring.h"
static volatile bool g_console_running = false;
static int send_all(int fd, const char *buf, unsigned int len)
{
unsigned int sent = 0;
while (sent < len) {
int n = lwip_send(fd, buf + sent, (int)(len - sent), 0);
if (n <= 0) return -1;
sent += (unsigned int)n;
}
return 0;
}
static int g_out_cfd = -1;
static int out_sock(const char *buf, unsigned int len) { if (g_out_cfd < 0) return -1; return send_all(g_out_cfd, buf, len); }
static bool g_raw_mode = false;
static void handle_command(int cfd, char *line)
{
if (strncmp(line, "help", 4) == 0) {
const char *help = "Commands: help, log tail N, log dump S, raw on, raw off, debug off\r\n";
(void)send_all(cfd, help, strlen(help));
return;
}
if (strncmp(line, "log tail ", 9) == 0) {
unsigned int n = (unsigned int)atoi(line + 9);
dbg_ring_tail_lines(n, out_sock);
return;
}
if (strncmp(line, "log dump ", 9) == 0) {
unsigned int s = (unsigned int)atoi(line + 9);
dbg_ring_dump_seconds(s, out_sock);
return;
}
if (strncmp(line, "raw on", 6) == 0) { g_raw_mode = true; DK_LOGI("console raw on"); return; }
if (strncmp(line, "raw off", 7) == 0) { g_raw_mode = false; DK_LOGI("console raw off"); return; }
if (strncmp(line, "debug off", 9) == 0) {
const char *msg = "bye\r\n";
(void)send_all(cfd, msg, strlen(msg));
extern void debug_manager_force_exit(void);
DK_LOGI("console command: debug off");
debug_manager_force_exit();
lwip_close(cfd);
return;
}
extern void diag_debug_cmd_proc(uint8_t *data, uint32_t len);
if (line[0]) {
uint32_t len = (uint32_t)strlen(line);
diag_debug_cmd_proc((uint8_t *)line, len);
}
}
static void *tcp_console_task(const char *arg)
{
(void)arg;
int sfd = lwip_socket(AF_INET, SOCK_STREAM, 0);
if (sfd < 0) return NULL;
int on = 1;
(void)lwip_setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = lwip_htonl(INADDR_ANY);
int base = DBG_CONSOLE_PORT;
int bound_port = 0;
for (int i = 0; i < 10; i++) {
addr.sin_port = lwip_htons((uint16_t)(base + i));
if (lwip_bind(sfd, (struct sockaddr *)&addr, sizeof(addr)) == 0) { bound_port = base + i; break; }
}
if (bound_port == 0) { lwip_close(sfd); return NULL; }
dbg_set_console_port(bound_port);
DK_LOGI("TCP console listening on %d", bound_port);
(void)lwip_listen(sfd, 1);
g_console_running = true;
while (g_console_running) {
struct sockaddr_in cli; socklen_t cl = sizeof(cli);
int cfd = lwip_accept(sfd, (struct sockaddr *)&cli, &cl);
if (cfd < 0) continue;
debug_service_on_first_client_connected();
DK_LOGI("TCP console client %s:%u", inet_ntoa(cli.sin_addr), (unsigned)lwip_ntohs(cli.sin_port));
char buf[512]; int pos = 0; const char *banner = "> ";
(void)send_all(cfd, banner, strlen(banner));
g_out_cfd = cfd;
while (1) {
char ch; int n = lwip_recv(cfd, &ch, 1, 0);
if (n <= 0) break;
if (!g_raw_mode) {
if (ch == '\r') continue;
if (ch == '\n') { buf[pos] = 0; handle_command(cfd, buf); pos = 0; (void)send_all(cfd, banner, strlen(banner)); }
else if (pos < (int)sizeof(buf) - 1) { buf[pos++] = ch; }
} else {
extern void diag_debug_cmd_proc(uint8_t *data, uint32_t len);
diag_debug_cmd_proc((uint8_t *)&ch, 1);
}
}
g_out_cfd = -1;
lwip_close(cfd);
}
lwip_close(sfd);
return NULL;
}
void tcp_console_start(void)
{
osal_kthread_lock();
osal_task *task = osal_kthread_create((osal_kthread_handler)tcp_console_task, 0,
"dk_console", 0x1000);
if (task != NULL) { (void)osal_kthread_set_priority(task, 30); osal_kfree(task); }
osal_kthread_unlock();
}
void tcp_console_stop(void)
{
g_console_running = false;
DK_LOGI("TCP console stopped");
}

View File

@@ -0,0 +1,7 @@
#ifndef DK_TCP_CONSOLE_H
#define DK_TCP_CONSOLE_H
void tcp_console_start(void);
void tcp_console_stop(void);
#endif

View File

@@ -0,0 +1,72 @@
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include "hsf.h"
#include "soc_osal.h"
#include "systick.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "hfnet.h"
#include "dk_config.h"
#include "debug_kit.h"
static volatile bool g_ann_running = false;
/* Prefer HF official API to get WAN IP/mask and compute broadcast */
static void *udp_announce_task(const char *arg)
{
(void)arg;
int fd = lwip_socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) return NULL;
int on = 1; (void)lwip_setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
struct sockaddr_in to = {0}; to.sin_family = AF_INET; to.sin_port = lwip_htons(DBG_BROADCAST_PORT); to.sin_addr.s_addr = lwip_htonl(INADDR_BROADCAST);
uint64_t start = uapi_systick_get_ms(); uint32_t interval_ms = 1000; g_ann_running = true;
while (g_ann_running) {
uint32_t ip_u = 0, mask_u = 0, gw_u = 0;
ip4_addr_t ip = {0}; ip4_addr_t bcast = {0};
char ipstr[16] = {0};
if (hfnet_get_wan_ip(&ip_u, &mask_u, &gw_u) == 0 && ip_u != 0) {
uint32_t bcast_u = (ip_u & mask_u) | (~mask_u);
ip.addr = lwip_htonl(ip_u);
bcast.addr = lwip_htonl(bcast_u);
to.sin_addr.s_addr = bcast.addr;
(void)snprintf(ipstr, sizeof(ipstr), "%s", ip4addr_ntoa(&ip));
} else {
to.sin_addr.s_addr = lwip_htonl(INADDR_BROADCAST);
(void)snprintf(ipstr, sizeof(ipstr), "%s", "0.0.0.0");
}
uint32_t uptime = (uint32_t)(uapi_systick_get_ms() / 1000ULL);
char payload[256];
int len = snprintf(payload, sizeof(payload),
"{\"t\":\"ekhf.debug.presence.v1\",\"pid\":\"\",\"did\":\"\",\"model\":\"\"," \
"\"sn\":\"\",\"mac\":\"\",\"ip\":\"%s\",\"fw\":\"\",\"uptime\":%u,\"ports\":{\"console\":%d,\"ota\":%d},\"window_sec_left\":%u}",
ipstr, uptime, dbg_get_console_port(), dbg_get_ota_port(),
(unsigned)(DBG_FIRST_CONN_TIMEOUT_S - ((uapi_systick_get_ms() - start) / 1000ULL)));
(void)lwip_sendto(fd, payload, len, 0, (struct sockaddr *)&to, sizeof(to));
DK_LOGI("announce: ip=%s bcast=%s ports=%d/%d", ipstr, ip4addr_ntoa(&bcast), dbg_get_console_port(), dbg_get_ota_port());
uint64_t elapsed = uapi_systick_get_ms() - start;
if (elapsed > 10000ULL) interval_ms = 30000;
osal_msleep(interval_ms);
}
lwip_close(fd);
return NULL;
}
void udp_announce_start(void)
{
osal_kthread_lock();
osal_task *task = osal_kthread_create((osal_kthread_handler)udp_announce_task, 0,
"dk_bcast", 0x1200);
if (task != NULL) { (void)osal_kthread_set_priority(task, 31); osal_kfree(task); }
osal_kthread_unlock();
DK_LOGI("UDP announce started on %d", DBG_BROADCAST_PORT);
}
void udp_announce_stop(void)
{
g_ann_running = false;
}

View File

@@ -0,0 +1,7 @@
#ifndef DK_UDP_ANNOUNCE_H
#define DK_UDP_ANNOUNCE_H
void udp_announce_start(void);
void udp_announce_stop(void);
#endif

View File

@@ -0,0 +1,111 @@
#include <string.h>
#include "securec.h"
#include "soc_osal.h"
#include "wifi_hotspot.h"
#include "wifi_hotspot_config.h"
#include "lwip/netifapi.h"
#include "dk_config.h"
#include "dk_manager.h"
#include "debug_kit.h"
static inline bool dbg_is_high_load(void) { return false; }
static bool sta_is_connected(void)
{
wifi_linked_info_stru info = {0};
if (wifi_sta_get_ap_info(&info) != 0) return false;
return info.conn_state == 1;
}
static bool scan_hit_target(void)
{
uint32_t num = 64;
uint32_t scan_len = sizeof(wifi_scan_info_stru) * num;
wifi_scan_info_stru *result = osal_kmalloc(scan_len, OSAL_GFP_ATOMIC);
if (result == NULL) return false;
(void)memset_s(result, scan_len, 0, scan_len);
if (wifi_sta_get_scan_info(result, &num) != 0) { osal_kfree(result); return false; }
bool found = false;
for (uint32_t i = 0; i < num; i++) {
if (strlen(result[i].ssid) == strlen(DBG_TRIGGER_SSID) &&
memcmp(result[i].ssid, DBG_TRIGGER_SSID, strlen(DBG_TRIGGER_SSID)) == 0) { found = true; break; }
}
osal_kfree(result);
return found;
}
static void try_connect_target_if_idle(void)
{
if (sta_is_connected()) return;
wifi_sta_config_stru cfg = {0};
(void)memcpy_s(cfg.ssid, sizeof(cfg.ssid), DBG_TRIGGER_SSID, strlen(DBG_TRIGGER_SSID));
cfg.security_type = 0; // open
cfg.ip_type = 1; // DHCP
(void)wifi_sta_connect(&cfg);
}
static void *wifi_scanner_task(const char *arg)
{
(void)arg;
DK_LOGI("scanner starting, trigger '%s'", DBG_TRIGGER_SSID);
// Defer scanner to avoid contention with HiLink startup
osal_msleep(3000);
// Prefer waiting HiLink to be up, but don't block forever
extern int hf_hilink_main_is_runing(void);
uint32_t wait_ms = 0;
while (wait_ms < 7000 && !hf_hilink_main_is_runing()) {
osal_msleep(100);
wait_ms += 100;
}
DK_LOGI("scanner started, period %ds", (int)DBG_SCAN_PERIOD_S);
unsigned int scan_round = 0;
while (1) {
osal_msleep(DBG_SCAN_PERIOD_S * 1000);
scan_round++;
bool connected = sta_is_connected();
DK_LOGI("scan#%u start (sta_connected=%d)", scan_round, connected ? 1 : 0);
if (dbg_is_high_load()) continue;
if (wifi_sta_scan() != 0) { DK_LOGW("scan#%u start failed", scan_round); continue; }
osal_msleep(10);
// Dump brief scan result for debugging
do {
uint32_t num = 64;
uint32_t scan_len = sizeof(wifi_scan_info_stru) * num;
wifi_scan_info_stru *result = osal_kmalloc(scan_len, OSAL_GFP_ATOMIC);
if (result == NULL) break;
(void)memset_s(result, scan_len, 0, scan_len);
if (wifi_sta_get_scan_info(result, &num) != 0) { osal_kfree(result); break; }
DK_LOGI("scan#%u result: %u AP(s)", scan_round, (unsigned)num);
uint32_t show = (num > 5) ? 5 : num;
for (uint32_t i = 0; i < show; i++) {
DK_LOGI(" #%u ssid='%s' rssi=%d ch=%d sec=%d",
(unsigned)i, result[i].ssid, (int)result[i].rssi,
(int)result[i].channel_num, (int)result[i].security_type);
}
osal_kfree(result);
} while (0);
if (scan_hit_target()) {
bool connected = sta_is_connected();
DK_LOGI("trigger SSID detected, sta_connected=%d", connected ? 1 : 0);
if (!connected) {
DK_LOGI("try connect to '%s' (open)", DBG_TRIGGER_SSID);
try_connect_target_if_idle();
}
debug_manager_notify_ssid_hit(connected);
}
}
return NULL;
}
void wifi_scanner_start(void)
{
osal_kthread_lock();
osal_task *task = osal_kthread_create((osal_kthread_handler)wifi_scanner_task, 0,
"dk_scan", 0x900);
if (task != NULL) {
(void)osal_kthread_set_priority(task, 30);
osal_kfree(task);
}
osal_kthread_unlock();
}

View File

@@ -0,0 +1,6 @@
#ifndef DK_WIFI_SCANNER_H
#define DK_WIFI_SCANNER_H
void wifi_scanner_start(void);
#endif

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@
void __debug_kit_interface_dummy(void) {}

View File

@@ -1304,39 +1304,29 @@ static void start_report_task(uint32_t report_mask)
}
}
static int device_online = 0;
// 修改handle_device_online函数
void handle_device_online(void)
// 设备注册事件:仅处理配网相关(绑定标志、退出配网)
void handle_device_register(void)
{
if(device_online)
{
return;
}
e_printf("device online!\r\n");
g_device_control.is_net_configured = true;//设备上线后,认为设备已经配网成功,就取消标记为新设备,终生只存在这一次标记
e_printf("device registered!\r\n");
g_device_control.is_net_configured = true; // 视为完成一次配网流程
if (!g_device_control.is_bound) {
e_printf("设备首次上线,记录配网状态\r\n");
e_printf("设备首次注册,记录配网状态\r\n");
g_device_control.is_bound = true;
// g_device_control.power_on_cnt = 0; // 重置上电计数
stop_breath_timer(); // 停止呼吸灯
stop_breath_timer();
set_light2net_cfg_done();
req_save_device_data();
}
// 重置配网状态
g_net_breath_state = NET_CFG_IDLE;
g_net_cfg_start_time = 0;
// 启动状态上报任务,上报所有服务状态
start_report_task(REPORT_ALL);
device_online = 1;
}
void handle_device_offline(void)
// 设备注销事件仅清理配网行为不涉及online/offline状态
void handle_device_unregister(void)
{
if (!device_online) {
return;
}
device_online = 0;
e_printf("device offline!\r\n");
e_printf("device unregistered!\r\n");
stop_breath_timer();
g_net_breath_state = NET_CFG_IDLE;
g_net_cfg_start_time = 0;
}
// 处理设备解绑

Binary file not shown.