Files
banban/ql-application/threadx/interface/factory_test/factory_protocol.c
T

218 lines
7.6 KiB
C

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "ql_rtos.h"
#include "ql_rtc.h"
#include "ql_uart.h"
#include "factory_protocol.h"
#define FT_PROTOCOL_LINE_MAX 1024
typedef struct {
char session[32];
char imei[32];
char iccid[32];
char nfc_uid[32];
char start_time[40];
u32 start_ms;
u32 seq;
ft_state_t nodes[FT_NODE_COUNT];
int cdc_open;
} ft_protocol_context_t;
static ft_protocol_context_t g_protocol;
u32 ft_now_ms(void)
{
return ql_rtos_get_systicks() * 5U;
}
const char *ft_node_name(ft_node_t node)
{
static const char *names[FT_NODE_COUNT] = {
"BOOT_AUDIO", "POWER_ADC", "AUDIO_LOOPBACK", "KEY_TRIPLE",
"ESIM", "DATA_CALL", "PING", "NFC"
};
if (node < 0 || node >= FT_NODE_COUNT) {
return "UNKNOWN";
}
return names[node];
}
static const char *ft_state_name(ft_state_t state)
{
if (state == FT_STATE_PASS) return "PASS";
if (state == FT_STATE_FAIL) return "FAIL";
return "WAIT";
}
static void ft_emit(const char *fmt, ...)
{
char payload[FT_PROTOCOL_LINE_MAX - 16];
char line[FT_PROTOCOL_LINE_MAX];
va_list args;
int len;
va_start(args, fmt);
vsnprintf(payload, sizeof(payload), fmt, args);
va_end(args);
len = snprintf(line, sizeof(line), "FT1 %s\r\n", payload);
if (len < 0) return;
if (len >= (int)sizeof(line)) len = sizeof(line) - 1;
printf("%s", line);
if (g_protocol.cdc_open) {
ql_uart_write(QL_USB_CDC_PORT, (unsigned char *)line, len);
}
}
static void ft_make_session(void)
{
ql_rtc_time_t rtc = {0};
u32 now = ft_now_ms();
g_protocol.start_ms = now;
if (ql_rtc_get_time(&rtc) == 0 && rtc.tm_year >= 2024) {
snprintf(g_protocol.start_time, sizeof(g_protocol.start_time),
"%04d-%02d-%02dT%02d:%02d:%02d",
rtc.tm_year, rtc.tm_mon, rtc.tm_mday,
rtc.tm_hour, rtc.tm_min, rtc.tm_sec);
snprintf(g_protocol.session, sizeof(g_protocol.session),
"%04d%02d%02d-%02d%02d%02d",
rtc.tm_year, rtc.tm_mon, rtc.tm_mday,
rtc.tm_hour, rtc.tm_min, rtc.tm_sec);
} else {
strcpy(g_protocol.start_time, "");
snprintf(g_protocol.session, sizeof(g_protocol.session), "BOOT-%010lu",
(unsigned long)now);
}
}
void ft_protocol_init(void)
{
memset(&g_protocol, 0, sizeof(g_protocol));
g_protocol.cdc_open =
(ql_uart_open(QL_USB_CDC_PORT, QL_UART_BAUD_115200, QL_FC_NONE) == 0);
ft_make_session();
}
static void ft_copy(char *dst, unsigned int dst_size, const char *src)
{
if (!dst || dst_size == 0) return;
if (!src) src = "";
snprintf(dst, dst_size, "%s", src);
}
void ft_protocol_set_imei(const char *imei)
{
ft_copy(g_protocol.imei, sizeof(g_protocol.imei), imei);
}
void ft_protocol_set_iccid(const char *iccid)
{
ft_copy(g_protocol.iccid, sizeof(g_protocol.iccid), iccid);
}
void ft_protocol_set_nfc_uid(const char *uid)
{
ft_copy(g_protocol.nfc_uid, sizeof(g_protocol.nfc_uid), uid);
}
const char *ft_protocol_imei(void) { return g_protocol.imei; }
const char *ft_protocol_iccid(void) { return g_protocol.iccid; }
const char *ft_protocol_nfc_uid(void) { return g_protocol.nfc_uid; }
void ft_protocol_session_start(void)
{
ft_emit("{\"v\":%d,\"type\":\"session_start\",\"seq\":%lu,"
"\"session\":\"%s\",\"uptime_ms\":%lu,\"imei\":\"%s\","
"\"iccid\":\"%s\",\"nfc_uid\":\"%s\",\"fw\":\"%s\","
"\"ping_host\":\"%s\",\"start_time\":%s%s%s}",
FT_PROTOCOL_VERSION, (unsigned long)++g_protocol.seq,
g_protocol.session, (unsigned long)ft_now_ms(), g_protocol.imei,
g_protocol.iccid, g_protocol.nfc_uid, FT_FIRMWARE_VERSION,
FT_PING_HOST, g_protocol.start_time[0] ? "\"" : "null",
g_protocol.start_time, g_protocol.start_time[0] ? "\"" : "");
}
void ft_protocol_node_start(ft_node_t node)
{
ft_emit("{\"v\":%d,\"type\":\"node_start\",\"seq\":%lu,"
"\"session\":\"%s\",\"uptime_ms\":%lu,\"imei\":\"%s\","
"\"iccid\":\"%s\",\"nfc_uid\":\"%s\",\"node\":%d,"
"\"name\":\"%s\"}",
FT_PROTOCOL_VERSION, (unsigned long)++g_protocol.seq,
g_protocol.session, (unsigned long)ft_now_ms(), g_protocol.imei,
g_protocol.iccid, g_protocol.nfc_uid, node, ft_node_name(node));
}
void ft_protocol_node_progress(ft_node_t node, int current, int required)
{
ft_emit("{\"v\":%d,\"type\":\"node_progress\",\"seq\":%lu,"
"\"session\":\"%s\",\"uptime_ms\":%lu,\"imei\":\"%s\","
"\"iccid\":\"%s\",\"nfc_uid\":\"%s\",\"node\":%d,"
"\"name\":\"%s\",\"result\":\"PASS\","
"\"data\":{\"current\":%d,\"required\":%d}}",
FT_PROTOCOL_VERSION, (unsigned long)++g_protocol.seq,
g_protocol.session, (unsigned long)ft_now_ms(), g_protocol.imei,
g_protocol.iccid, g_protocol.nfc_uid, node, ft_node_name(node),
current, required);
}
void ft_protocol_node_result(ft_node_t node, int passed, ft_error_t code,
u32 elapsed_ms, const char *data_json)
{
const char *result = passed ? "PASS" : "FAIL";
if (node >= 0 && node < FT_NODE_COUNT) {
g_protocol.nodes[node] = passed ? FT_STATE_PASS : FT_STATE_FAIL;
}
if (!data_json || !data_json[0]) data_json = "{}";
ft_emit("{\"v\":%d,\"type\":\"node_result\",\"seq\":%lu,"
"\"session\":\"%s\",\"uptime_ms\":%lu,\"imei\":\"%s\","
"\"iccid\":\"%s\",\"nfc_uid\":\"%s\",\"node\":%d,"
"\"name\":\"%s\",\"result\":\"%s\",\"code\":%d,"
"\"elapsed_ms\":%lu,\"data\":%s}",
FT_PROTOCOL_VERSION, (unsigned long)++g_protocol.seq,
g_protocol.session, (unsigned long)ft_now_ms(), g_protocol.imei,
g_protocol.iccid, g_protocol.nfc_uid, node, ft_node_name(node),
result, code, (unsigned long)elapsed_ms, data_json);
}
void ft_protocol_session_result(int passed, ft_error_t code)
{
ft_emit("{\"v\":%d,\"type\":\"session_result\",\"seq\":%lu,"
"\"session\":\"%s\",\"uptime_ms\":%lu,\"result\":\"%s\","
"\"fail_code\":%d,\"imei\":\"%s\",\"iccid\":\"%s\","
"\"nfc_uid\":\"%s\",\"start_time\":%s%s%s,"
"\"duration_ms\":%lu,\"nodes\":{"
"\"BOOT_AUDIO\":\"%s\",\"POWER_ADC\":\"%s\","
"\"AUDIO_LOOPBACK\":\"%s\",\"KEY_TRIPLE\":\"%s\","
"\"ESIM\":\"%s\",\"DATA_CALL\":\"%s\","
"\"PING\":\"%s\",\"NFC\":\"%s\"}}",
FT_PROTOCOL_VERSION, (unsigned long)++g_protocol.seq,
g_protocol.session, (unsigned long)ft_now_ms(), passed ? "PASS" : "FAIL",
code, g_protocol.imei, g_protocol.iccid, g_protocol.nfc_uid,
g_protocol.start_time[0] ? "\"" : "null", g_protocol.start_time,
g_protocol.start_time[0] ? "\"" : "",
(unsigned long)(ft_now_ms() - g_protocol.start_ms),
ft_state_name(g_protocol.nodes[0]), ft_state_name(g_protocol.nodes[1]),
ft_state_name(g_protocol.nodes[2]), ft_state_name(g_protocol.nodes[3]),
ft_state_name(g_protocol.nodes[4]), ft_state_name(g_protocol.nodes[5]),
ft_state_name(g_protocol.nodes[6]), ft_state_name(g_protocol.nodes[7]));
}
void ft_protocol_power_off(void)
{
ft_emit("{\"v\":%d,\"type\":\"power_off\",\"seq\":%lu,"
"\"session\":\"%s\",\"uptime_ms\":%lu,\"imei\":\"%s\","
"\"iccid\":\"%s\",\"nfc_uid\":\"%s\",\"code\":0}",
FT_PROTOCOL_VERSION, (unsigned long)++g_protocol.seq,
g_protocol.session, (unsigned long)ft_now_ms(), g_protocol.imei,
g_protocol.iccid, g_protocol.nfc_uid);
}