diff --git a/src/host_stream/event_recorder.c b/src/host_stream/event_recorder.c index dcd28aa..e983d34 100644 --- a/src/host_stream/event_recorder.c +++ b/src/host_stream/event_recorder.c @@ -244,7 +244,7 @@ static int open_socket_to(const char *host, int port) /* ── Channel B: POST tar.gz via kCurl ───────────────────────────────────── */ #define KCURL_PATH "/mnt/flash/plus/kp_firmware/kp_firmware_0/kp_firmware/bin/kCurl" -static void http_post_file(const char *filepath) +static int http_post_file(const char *filepath) /* returns 0=OK, -1=fail */ { const char *basename = strrchr(filepath, '/'); basename = basename ? basename + 1 : filepath; @@ -260,10 +260,12 @@ static void http_post_file(const char *filepath) printf("[EVT] upload: kCurl → %s\n", url); int rc = system(cmd); - if (rc != 0) + if (rc != 0) { printf("[EVT] upload: kCurl failed (rc=%d)\n", rc); - else - printf("[EVT] upload: %s sent OK\n", basename); + return -1; + } + printf("[EVT] upload: %s sent OK\n", basename); + return 0; } /* @@ -578,6 +580,59 @@ static void *test_buzzer_all_thread(void *arg) return NULL; } +static void *test_upload_thread(void *arg) +{ + (void)arg; + test_reply("TEST_UPLOAD_START"); + + /* Build a minimal test event ----------------------------------------- */ + char event_id[24]; + snprintf(event_id, sizeof(event_id), "TEST%ld", (long)time(NULL)); + + char work_dir[256]; + make_work_dir(event_id, work_dir, sizeof(work_dir)); + + /* Request one JPEG snapshot from the VMF thread */ + request_snap("test.jpg", work_dir, event_id, "test_upload", 1, 0); + usleep(800000); /* up to 800 ms for VMF to deliver the frame */ + + /* Check whether the snapshot arrived */ + char snap_path[320]; + snprintf(snap_path, sizeof(snap_path), "%s/test.jpg", work_dir); + struct stat _st; + int has_snap = (stat(snap_path, &_st) == 0 && _st.st_size > 0) ? 1 : 0; + printf("[TEST] upload: snapshot %s (%s)\n", + snap_path, has_snap ? "OK" : "missing — continuing without image"); + + /* Write event.json */ + const char imgs[4][64] = { "test.jpg", "", "", "" }; + write_event_json(work_dir, event_id, "test_upload", 1, 0.0f, + has_snap ? imgs : NULL, has_snap ? 1 : 0); + + /* Build tar.gz */ + char tgz_path[384]; + build_targz(work_dir, event_id, tgz_path, sizeof(tgz_path)); + + if (tgz_path[0] == '\0') { + test_reply("TEST_UPLOAD_FAIL TAR_FAILED"); + rm_work_dir(work_dir); + s_test_all_running = 0; + return NULL; + } + + /* Upload via kCurl */ + int ok = http_post_file(tgz_path); + if (ok == 0) + test_reply("TEST_UPLOAD_OK"); + else + test_reply("TEST_UPLOAD_FAIL CURL_FAILED"); + + sd_cleanup(); + rm_work_dir(work_dir); + s_test_all_running = 0; + return NULL; +} + static void *test_all_thread(void *arg) { int obs = arg ? (int)(intptr_t)arg : TEST_OBS_DEFAULT_SEC; @@ -700,6 +755,10 @@ static void handle_test_cmd(const char *raw) printf("[TEST BUZZER] bt_uart_send_json returned — printing reply\n"); printf("[TEST] reply: %s\n", ack); printf("[TEST BUZZER] done\n"); + } else if (strncmp(cmd, "TEST_UPLOAD", 11) == 0) { + if (s_test_all_running) { test_reply("TEST_ERR ALL_ALREADY_RUNNING"); return; } + s_test_all_running = 1; + pthread_t tid; pthread_create(&tid, NULL, test_upload_thread, NULL); pthread_detach(tid); } else if (strncmp(cmd, "TEST_ALL", 8) == 0) { if (s_test_all_running) { test_reply("TEST_ERR ALL_ALREADY_RUNNING"); return; } int obs = TEST_OBS_DEFAULT_SEC; diff --git a/src/pre_post_proc/stdc_post_process.c b/src/pre_post_proc/stdc_post_process.c index 6f2402d..bba0a60 100644 --- a/src/pre_post_proc/stdc_post_process.c +++ b/src/pre_post_proc/stdc_post_process.c @@ -7,12 +7,15 @@ #include #include #include +#include #include "kp_struct.h" #include "ncpu_gen_struct.h" #include "demo_post_utils.h" #include "stdc_post_process.h" +extern unsigned int g_verbose_log; + typedef struct { uint8_t *prev_roi_luma; uint32_t prev_roi_capacity; @@ -317,17 +320,27 @@ int stdc_post_process(int model_id, struct kdp_image_s *image_p) if (ana->col_pond_ratio >= THR_POND_COLLISION) ana->collision_risk = 1; /* ------------------------------------------------------- - * 4. Log summary + * 4. Log summary (throttled to 1Hz, verbose_log only) * ------------------------------------------------------- */ - printf("[STDC] frame=%u moving=%d diff=%.2f grass_roi=%.1f%% grass_time=%.1fs grass_warn=%d " - "person=%.1f%% car=%.1f%% tree=%.1f%% tree_growth=%.1f%% collision=%d\n", - ana->frame_count, ana->is_moving, ana->motion_diff, - ana->grass_roi_ratio * 100.0f, ana->grass_duration_sec, ana->grass_warning, - ana->class_ratio[STDC_CLASS_PERSON] * 100.0f, - ana->class_ratio[STDC_CLASS_CAR] * 100.0f, - ana->class_ratio[STDC_CLASS_TREE] * 100.0f, - ana->tree_roi_growth * 100.0f, - ana->collision_risk); + if (g_verbose_log) { + static struct timeval s_last_post_log = {0, 0}; + struct timeval now; + gettimeofday(&now, NULL); + long elapsed_us = (now.tv_sec - s_last_post_log.tv_sec) * 1000000L + + (now.tv_usec - s_last_post_log.tv_usec); + if (elapsed_us >= 1000000L) { + s_last_post_log = now; + printf("[STDC] frame=%u moving=%d diff=%.2f grass_roi=%.1f%% grass_time=%.1fs grass_warn=%d " + "person=%.1f%% car=%.1f%% tree=%.1f%% tree_growth=%.1f%% collision=%d\n", + ana->frame_count, ana->is_moving, ana->motion_diff, + ana->grass_roi_ratio * 100.0f, ana->grass_duration_sec, ana->grass_warning, + ana->class_ratio[STDC_CLASS_PERSON] * 100.0f, + ana->class_ratio[STDC_CLASS_CAR] * 100.0f, + ana->class_ratio[STDC_CLASS_TREE] * 100.0f, + ana->tree_roi_growth * 100.0f, + ana->collision_risk); + } + } return KP_SUCCESS; }