diff --git a/include/host_stream/event_recorder.h b/include/host_stream/event_recorder.h index db14936..686a17b 100644 --- a/include/host_stream/event_recorder.h +++ b/include/host_stream/event_recorder.h @@ -10,7 +10,7 @@ * A) Real-time JSON → UART → DX-BT24 BLE → iPad (bt_uart_send_json) * B) tar.gz archive → POST (OOB / cloud path) * Simulation: http://192.168.0.114:8081/api/upload - * Production: http://192.168.0.99/api/golf.cgi + * Production: http://192.168.0.99/api/golf-golface.cgi * * Grass events use a 4-level state machine (L1/L2/L3/resolved). * Hazard + person events are single-shot. @@ -27,7 +27,9 @@ void event_recorder_init(const char *upload_url, const char *sd_path, int sd_max_mb, int upload_delay_ms, - int enable); + int enable, + const char *device_id, + int dev_mode); /* Drive the state machine — call from app_header_recv_inference. */ void event_recorder_update(const stdc_analysis_t *ana); diff --git a/ini/host_stream.ini b/ini/host_stream.ini index e164066..2bafb03 100644 --- a/ini/host_stream.ini +++ b/ini/host_stream.ini @@ -99,8 +99,8 @@ bt_name = BT-24 # Reported in status_ch ; Leave empty to auto-detect on first boot; value is written back automatically. ; BLE broadcast name (event:bt_name) is derived as AresX-{lower 16-bit hex}. device_id = -upload_url = http://192.168.0.99/api/golf.cgi # Channel B: tar.gz upload (OOB/cloud path) - # Production: http://192.168.0.99/api/golf.cgi +upload_url = http://192.168.0.99/api/golf-golface.cgi # Channel B: tar.gz upload (OOB/cloud path) +upload_dev = 1 # 1: append &dev=1 to upload URL (dev); 0: production sd_path = /tmp/sdcard/events # SD card event archive path sd_max_mb = 7168 # 7 GB ??delete oldest when exceeded upload_delay_ms = 0 # 0: upload immediately after tar.gz built (tar is built after event ends, no extra delay needed) diff --git a/src/host_stream/event_recorder.c b/src/host_stream/event_recorder.c index cb5245c..a085f91 100644 --- a/src/host_stream/event_recorder.c +++ b/src/host_stream/event_recorder.c @@ -109,7 +109,9 @@ static int msg_send(const char *fifo, * Production: http://192.168.0.99/api/golf.cgi */ static char s_up_host[64] = "192.168.0.99"; static int s_up_port = 80; -static char s_up_path[128] = "/api/golf.cgi"; +static char s_up_path[128] = "/api/golf-golface.cgi"; +static char s_device_id[64] = ""; +static int s_upload_dev = 0; static char s_sd_path[256] = "/tmp/sdcard/events"; static long long s_sd_max_bytes = (long long)7 * 1024 * 1024 * 1024; @@ -244,14 +246,29 @@ 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 int http_post_file(const char *filepath) /* returns 0=OK, -1=fail */ +static int http_post_file(const char *filepath, const char *event_id) /* returns 0=OK, -1=fail */ { - const char *basename = strrchr(filepath, '/'); - basename = basename ? basename + 1 : filepath; - char url[320]; - snprintf(url, sizeof(url), "http://%s:%d%s?filename=%s", - s_up_host, s_up_port, s_up_path, basename); + + if (s_upload_dev) { + /* Dev mode: fixed test credentials, append &dev=1 */ + snprintf(url, sizeof(url), "http://%s:%d%s?did=GOLF20001&vid=1620029793&dev=1", + s_up_host, s_up_port, s_up_path); + } else { + /* Production: strip "0x"/"0X" prefix from device_id */ + const char *did = s_device_id; + if (did[0] == '0' && (did[1] == 'x' || did[1] == 'X')) + did += 2; + + /* Strip any non-numeric prefix from event_id (e.g. "TEST") */ + const char *vid = event_id; + while (*vid && (*vid < '0' || *vid > '9')) + vid++; + if (!*vid) vid = event_id; /* fallback: all non-digit, use as-is */ + + snprintf(url, sizeof(url), "http://%s:%d%s?did=%s&vid=%s", + s_up_host, s_up_port, s_up_path, did, vid); + } char cmd[640]; snprintf(cmd, sizeof(cmd), @@ -264,7 +281,7 @@ static int http_post_file(const char *filepath) /* returns 0=OK, -1=fail */ printf("[EVT] upload: kCurl failed (rc=%d)\n", rc); return -1; } - printf("[EVT] upload: %s sent OK\n", basename); + printf("[EVT] upload: %s sent OK\n", event_id); return 0; } @@ -590,29 +607,49 @@ static void *test_upload_thread(void *arg) (void)arg; test_reply("TEST_UPLOAD_START"); - /* Build a minimal test event ----------------------------------------- */ + /* Build event — format depends on upload_dev: + * dev=1 (test env) : type=test_upload, snap=test.jpg, isolated work_dir + * dev=0 (production): type=grass, snap=level1.jpg, real work_dir */ char event_id[24]; - snprintf(event_id, sizeof(event_id), "TEST%ld", (long)time(NULL)); + snprintf(event_id, sizeof(event_id), "%ld", (long)time(NULL)); + + const char *snap_name = s_upload_dev ? "test.jpg" : "level1.jpg"; + const char *evt_type = s_upload_dev ? "test_upload" : "grass"; + float duration = s_upload_dev ? 0.0f : 5.0f; char work_dir[256]; - make_work_dir(event_id, work_dir, sizeof(work_dir)); + if (s_upload_dev) + snprintf(work_dir, sizeof(work_dir), "/tmp/ev_TEST%s", event_id); + else + snprintf(work_dir, sizeof(work_dir), "/tmp/ev_%s", event_id); + mkdir(work_dir, 0755); /* 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 */ + request_snap(snap_name, work_dir, event_id, evt_type, 1, 0); - /* Check whether the snapshot arrived */ + /* Poll up to 5 s (50 × 100 ms) — stop as soon as file arrives */ char snap_path[320]; - snprintf(snap_path, sizeof(snap_path), "%s/test.jpg", work_dir); + snprintf(snap_path, sizeof(snap_path), "%s/%s", work_dir, snap_name); 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"); + int has_snap = 0; + for (int _i = 0; _i < 50; _i++) { + usleep(100000); /* 100 ms */ + if (stat(snap_path, &_st) == 0 && _st.st_size > 0) { + has_snap = 1; + printf("[TEST] upload: snapshot %s OK (%ld bytes, waited %d00ms)\n", + snap_path, (long)_st.st_size, _i + 1); + break; + } + } + if (!has_snap) + printf("[TEST] upload: snapshot %s missing after 5s\n", snap_path); /* 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); + char imgs[4][64]; + memset(imgs, 0, sizeof(imgs)); + snprintf(imgs[0], sizeof(imgs[0]), "%s", snap_name); + write_event_json(work_dir, event_id, evt_type, 1, duration, + has_snap ? (const char (*)[64])imgs : NULL, has_snap ? 1 : 0); /* Build tar.gz */ char tgz_path[384]; @@ -625,8 +662,11 @@ static void *test_upload_thread(void *arg) return NULL; } - /* Upload via kCurl */ - int ok = http_post_file(tgz_path); + /* Upload via kCurl. + * dev=1: http_post_file already uses fixed GOLF20001/1620029793. + * dev=0: use fixed test vid so cloud vendor can verify receipt easily. */ + const char *upload_vid = s_upload_dev ? event_id : "1122334455"; + int ok = http_post_file(tgz_path, upload_vid); if (ok == 0) test_reply("TEST_UPLOAD_OK"); else @@ -874,7 +914,7 @@ static void *upload_thread(void *arg) if (tgz_path[0]) { printf("[EVT] upload: posting %s to %s:%d%s\n", tgz_path, s_up_host, s_up_port, s_up_path); - http_post_file(tgz_path); + http_post_file(tgz_path, a->event_id); } sd_cleanup(); @@ -1004,7 +1044,9 @@ void event_recorder_init(const char *upload_url, const char *sd_path, int sd_max_mb, int upload_delay_ms, - int enable) + int enable, + const char *device_id, + int dev_mode) { s_enabled = enable; s_upload_delay_ms = (upload_delay_ms >= 0) ? upload_delay_ms : 60000; @@ -1015,10 +1057,13 @@ void event_recorder_init(const char *upload_url, &s_up_port, s_up_path, sizeof(s_up_path)); if (sd_path && *sd_path) snprintf(s_sd_path, sizeof(s_sd_path), "%s", sd_path); + if (device_id && *device_id) snprintf(s_device_id, sizeof(s_device_id), "%s", device_id); + s_upload_dev = dev_mode; - printf("[EVT] init: enable=%d ch_a=bt_uart ch_b=%s:%d%s sd=%s max=%dMB delay=%dms\n", + printf("[EVT] init: enable=%d ch_a=bt_uart ch_b=%s:%d%s did=%s dev=%d sd=%s max=%dMB delay=%dms\n", s_enabled, s_up_host, s_up_port, s_up_path, + s_device_id, s_upload_dev, s_sd_path, sd_max_mb, s_upload_delay_ms); bt_uart_set_extra_cmd_cb(handle_test_cmd); } diff --git a/src/host_stream/kp_firmware.c b/src/host_stream/kp_firmware.c index 5bb4c23..ef72389 100644 --- a/src/host_stream/kp_firmware.c +++ b/src/host_stream/kp_firmware.c @@ -238,6 +238,7 @@ int loadConfig(HOST_STREAM_INIT_OPT_T* pHostStreamInit) const char *ev_sd = iniparser_getstring(ini, "event:sd_path", "/tmp/sdcard/events"); int ev_max_mb = iniparser_getint(ini, "event:sd_max_mb", 7168); int ev_delay = iniparser_getint(ini, "event:upload_delay_ms", 60000); + int ev_dev = iniparser_getint(ini, "event:upload_dev", 0); /* device_id (event:device_id): raw Kn chip number string, e.g. "0xCE7B562C". * bt_name (event:bt_name): BLE broadcast name derived from kn, e.g. "AresX-562C". @@ -317,7 +318,7 @@ int loadConfig(HOST_STREAM_INIT_OPT_T* pHostStreamInit) printf("[BT] WARNING: sed INI update returned %d (%s)\n", rc, HOST_STREAM_CONFIG_PATH); } - event_recorder_init(ev_up, ev_sd, ev_max_mb, ev_delay, ev_enable); + event_recorder_init(ev_up, ev_sd, ev_max_mb, ev_delay, ev_enable, device_id, ev_dev); } /* --- [can] section: MCP2515 CAN bus via J15 SPI connector --- */