Add Test_Upload item for development/product cloud

This commit is contained in:
miketsai 2026-07-06 15:02:11 +08:00
parent aa75c47772
commit 83e2256192
4 changed files with 79 additions and 31 deletions

View File

@ -10,7 +10,7 @@
* A) Real-time JSON UART DX-BT24 BLE iPad (bt_uart_send_json)
* B) tar.gz archive POST <upload_url> (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);

View File

@ -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)

View File

@ -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);
}

View File

@ -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 --- */