Browse Source

feat: add disconnect root-cause diagnostics

test/at-buffer-mode
蔡享 1 month ago
parent
commit
cf465e6298
  1. 118
      applications/VK_Client.c
  2. 2
      applications/VK_Com.c
  3. 267
      applications/drv_ec800k.c
  4. 36
      applications/drv_ec800k.h

118
applications/VK_Client.c

@ -36,6 +36,8 @@ static uint8_t socket_rx_buffer[LTE_SOCKET_RX_CHUNK_SIZE];
static rt_size_t socket_tx_pending = 0; static rt_size_t socket_tx_pending = 0;
static rt_tick_t last_ack_query_tick = 0; static rt_tick_t last_ack_query_tick = 0;
static void lte_diag_finish_disconnect(void);
no_carrier_match_t _no_carrier_t = {0}; no_carrier_match_t _no_carrier_t = {0};
/*关闭TCP连接*/ /*关闭TCP连接*/
@ -44,6 +46,10 @@ void client_tcp_close(Cclient_t *client) {
client->connect_sta = false; client->connect_sta = false;
BSP_LTE_SetDataTxPaused(true); BSP_LTE_SetDataTxPaused(true);
if (lte_diag.disconnect_report_pending) {
BSP_LTE_CollectNetworkSnapshot();
lte_diag_finish_disconnect();
}
BSP_LTE_ClearSocketEvents(); BSP_LTE_ClearSocketEvents();
fmu_net_queue_reset(); fmu_net_queue_reset();
socket_tx_pending = 0; socket_tx_pending = 0;
@ -177,6 +183,7 @@ void lte_diag_disconnect(lte_disconnect_reason_t reason) {
lte_diag.disconnect_count++; lte_diag.disconnect_count++;
lte_diag.last_disconnect_reason = reason; lte_diag.last_disconnect_reason = reason;
lte_diag.last_disconnect_tick = now; lte_diag.last_disconnect_tick = now;
lte_diag.disconnect_report_pending = true;
LOG_I("[DISC] reason=%s count=%u connected_ticks=%u", LOG_I("[DISC] reason=%s count=%u connected_ticks=%u",
disconnect_reason_name(reason), lte_diag.disconnect_count, disconnect_reason_name(reason), lte_diag.disconnect_count,
@ -186,13 +193,18 @@ void lte_diag_disconnect(lte_disconnect_reason_t reason) {
lte_diag.uart2_rx_events, lte_diag.uart2_write_failures, lte_diag.uart2_rx_events, lte_diag.uart2_write_failures,
lte_diag.uart2_error_count, lte_diag.uart3_error_count, lte_diag.uart2_error_count, lte_diag.uart3_error_count,
lte_diag.last_uart_error_code); lte_diag.last_uart_error_code);
LOG_I("[DISC] fmu_rx=%u fmu_tx=%u server_rx=%u read_events=%u silence_timeout=%u",
lte_diag.fmu_rx_bytes, lte_diag.fmu_tx_bytes,
lte_diag.server_rx_bytes, lte_diag.server_rx_read_events,
lte_diag.server_silence_timeout_count);
LOG_I("[DISC] socket_tx=%u send_ok=%u send_fail=%u prompt_timeout=%u read_errors=%u",
lte_diag.socket_tx_bytes, lte_diag.socket_send_ok,
lte_diag.socket_send_fail, lte_diag.socket_prompt_timeouts,
LOG_I("[CONN] fmu_rx=%u fmu_tx=%u fmu_hb=%u server_rx=%u server_hb=%u events=%u",
lte_diag.fmu_rx_bytes - lte_diag.conn_fmu_rx_base,
lte_diag.fmu_tx_bytes - lte_diag.conn_fmu_tx_base,
lte_diag.fmu_heartbeats - lte_diag.conn_fmu_heartbeat_base,
lte_diag.server_rx_bytes - lte_diag.conn_server_rx_base,
lte_diag.server_heartbeats - lte_diag.conn_server_heartbeat_base,
lte_diag.server_rx_read_events - lte_diag.conn_server_events_base);
LOG_I("[CONN] socket_tx=%u send_ok=%u send_fail=%u prompt_timeout=%u read_errors=%u",
lte_diag.socket_tx_bytes - lte_diag.conn_socket_tx_base,
lte_diag.socket_send_ok - lte_diag.conn_send_ok_base,
lte_diag.socket_send_fail - lte_diag.conn_send_fail_base,
lte_diag.socket_prompt_timeouts,
lte_diag.socket_read_errors); lte_diag.socket_read_errors);
LOG_I("[DISC] acked=%u unacked=%u ack_queries=%u ack_errors=%u", LOG_I("[DISC] acked=%u unacked=%u ack_queries=%u ack_errors=%u",
lte_diag.socket_acked_bytes, lte_diag.socket_unacked_bytes, lte_diag.socket_acked_bytes, lte_diag.socket_unacked_bytes,
@ -210,13 +222,91 @@ void lte_diag_disconnect(lte_disconnect_reason_t reason) {
LOG_I("[DISC] attempts=%u reconnects=%u qioopen_fail=%u resets=%u", LOG_I("[DISC] attempts=%u reconnects=%u qioopen_fail=%u resets=%u",
lte_diag.connect_attempts, lte_diag.reconnect_count, lte_diag.connect_attempts, lte_diag.reconnect_count,
lte_diag.qioopen_failures, lte_diag.reset_count); lte_diag.qioopen_failures, lte_diag.reset_count);
LOG_I("[DISC] csq=%d cereg=%u pdp=%u heap=%u/%u min_free=%u",
lte_dev.csq, lte_dev.eps_sta, lte_dev.reset_flag == DTU_CF_NO_NEED_RESET,
heap_used, heap_total, heap_total - heap_max);
LOG_I("[DISC] heap=%u/%u min_free=%u", heap_used, heap_total,
heap_total - heap_max);
if (reason == LTE_DISC_AT_TIMEOUT || reason == LTE_DISC_QIOPEN_FAILED ||
reason == LTE_DISC_MODULE_RESET) {
const char *classification = reason == LTE_DISC_QIOPEN_FAILED
? "SOCKET_OPEN"
: "MODEM_OR_DEVICE";
LOG_I("[CLASS] class=%s confidence=MEDIUM net_snapshot=unavailable",
classification);
lte_diag.disconnect_report_pending = false;
}
lte_dev.client1->connect_sta = false; lte_dev.client1->connect_sta = false;
} }
static const char *diag_text_or_unknown(const char *text) {
return text[0] == '\0' ? "?" : text;
}
static void lte_diag_finish_disconnect(void) {
const lte_network_snapshot_t *network = &lte_diag.network;
rt_tick_t now = lte_diag.last_disconnect_tick;
rt_uint32_t connected_ms = now - lte_diag.connect_tick;
rt_uint32_t fmu_hb =
lte_diag.fmu_heartbeats - lte_diag.conn_fmu_heartbeat_base;
rt_uint32_t server_hb =
lte_diag.server_heartbeats - lte_diag.conn_server_heartbeat_base;
rt_uint32_t ack_queries =
lte_diag.socket_ack_queries - lte_diag.conn_ack_queries_base;
const char *classification = "UNKNOWN";
const char *confidence = "LOW";
const char *evidence = "insufficient";
bool registration_bad = network->cereg >= 0 && network->cereg != 1 &&
network->cereg != 5;
LOG_I("[NET] oper=%s rat=%s band=%s channel=%u tac=%s cell=%s",
diag_text_or_unknown(network->oper),
diag_text_or_unknown(network->rat),
diag_text_or_unknown(network->band), network->channel,
diag_text_or_unknown(network->tac),
diag_text_or_unknown(network->cell));
LOG_I("[NET] cereg=%d cgatt=%d pdp=%d csq=%d pdpdeact=%u",
network->cereg, network->cgatt, network->pdp, network->csq,
lte_dev.socket_pdpdeact_pending ? 1 : 0);
LOG_I("[PATH] acked=%u unacked=%u ack_queries=%u last_ack_age_ms=%u queue_drops=%u",
lte_diag.socket_acked_bytes, lte_diag.socket_unacked_bytes,
ack_queries, diag_age(now, lte_diag.last_socket_ack_tick),
lte_diag.tx_queue_drops - lte_diag.conn_queue_drops_base);
if (lte_dev.socket_pdpdeact_pending || registration_bad ||
network->cgatt == 0 || network->pdp == 0) {
classification = "CELLULAR";
confidence = "HIGH";
evidence = lte_dev.socket_pdpdeact_pending ? "pdpdeact" : "registration";
} else if (connected_ms >= 25000 && connected_ms <= 40000 &&
fmu_hb == 0 && server_hb >= 5 &&
lte_diag.socket_unacked_bytes == 0) {
classification = "SERVER_POLICY";
confidence = "HIGH";
evidence = "no_fmu_hb_30s";
} else if (lte_diag.socket_unacked_bytes > 0) {
classification = "IP_PATH";
confidence = "MEDIUM";
evidence = "tcp_unacked";
} else if (lte_diag.last_disconnect_reason == LTE_DISC_SERVER_SILENCE) {
classification = "SERVER_OR_DOWNLINK";
confidence = "MEDIUM";
evidence = "server_silence";
} else if (lte_diag.last_disconnect_reason == LTE_DISC_SOCKET_SEND) {
classification = "MODEM_OR_SOCKET";
confidence = "MEDIUM";
evidence = "socket_send_fail";
} else if (ack_queries > 0 && lte_diag.socket_unacked_bytes == 0 &&
diag_age(now, lte_diag.last_server_rx_tick) <= 5000) {
classification = "REMOTE_CLOSE";
confidence = "MEDIUM";
evidence = "recent_rx_all_acked";
}
LOG_I("[CLASS] class=%s confidence=%s evidence=%s", classification,
confidence, evidence);
lte_diag.disconnect_report_pending = false;
}
/*将EC800K软件复位*/ /*将EC800K软件复位*/
int16_t EC800K_Reset(void) { int16_t EC800K_Reset(void) {
@ -425,9 +515,7 @@ void client_yield(CLte_dev_t *pLte_dev) {
} }
rt_device_t fmu_com = fmu_com_get(); rt_device_t fmu_com = fmu_com_get();
lte_diag.server_rx_bytes += len;
lte_diag.server_rx_read_events++;
lte_diag.last_server_rx_tick = rt_tick_get();
lte_diag_server_data(pLte_dev->at_buf, len);
if (fmu_com) { if (fmu_com) {
rt_ssize_t written = rt_device_write(fmu_com, 0, rt_ssize_t written = rt_device_write(fmu_com, 0,
pLte_dev->at_buf, len); pLte_dev->at_buf, len);
@ -486,9 +574,7 @@ void client_yield(CLte_dev_t *pLte_dev) {
} }
if (read_length == 0) break; if (read_length == 0) break;
lte_diag.server_rx_bytes += read_length;
lte_diag.server_rx_read_events++;
lte_diag.last_server_rx_tick = rt_tick_get();
lte_diag_server_data(socket_rx_buffer, read_length);
#if LTE_SERVER_SILENCE_TIMEOUT_SEC > 0 #if LTE_SERVER_SILENCE_TIMEOUT_SEC > 0
last_rx_tick = lte_diag.last_server_rx_tick; last_rx_tick = lte_diag.last_server_rx_tick;
#endif #endif

2
applications/VK_Com.c

@ -132,7 +132,7 @@ void com_task(void) {
while (1) { while (1) {
len = rt_device_read(fmu_com, 0, buff, sizeof(buff)); len = rt_device_read(fmu_com, 0, buff, sizeof(buff));
if (len > 0) { if (len > 0) {
lte_diag_fmu_rx(len);
lte_diag_fmu_data(buff, len);
if (lte_dev.client1->connect_sta == true && if (lte_dev.client1->connect_sta == true &&
lte_dev.data_tx_paused == false) { lte_dev.data_tx_paused == false) {
/* 仅在客户端2连接时转发 */ /* 仅在客户端2连接时转发 */

267
applications/drv_ec800k.c

@ -43,6 +43,21 @@ static rt_size_t socket_urc_line_len = 0;
static volatile bool socket_open_seen = false; static volatile bool socket_open_seen = false;
static volatile int16_t socket_open_result = -1; static volatile int16_t socket_open_result = -1;
typedef struct {
rt_uint16_t remaining;
rt_uint16_t checksum;
rt_uint16_t received_checksum;
rt_uint8_t magic;
rt_uint8_t phase;
rt_uint8_t position;
rt_uint8_t payload_length;
rt_uint8_t incompat_flags;
bool heartbeat;
} mavlink_diag_parser_t;
static mavlink_diag_parser_t fmu_mavlink_parser;
static mavlink_diag_parser_t server_mavlink_parser;
static int parse_decimal(const char **text) { static int parse_decimal(const char **text) {
int value = 0; int value = 0;
bool found = false; bool found = false;
@ -57,6 +72,119 @@ static int parse_decimal(const char **text) {
return found ? value : -1; return found ? value : -1;
} }
static void copy_csv_token(const char **text, char *output, rt_size_t capacity) {
const char *p = *text;
rt_size_t used = 0;
char terminator = ',';
if (capacity == 0) return;
while (*p == ' ' || *p == ',') p++;
if (*p == '"') {
terminator = '"';
p++;
}
while (*p != '\0' && *p != '\r' && *p != '\n' && *p != terminator) {
if (used + 1 < capacity) output[used++] = *p;
p++;
}
while (used > 0 && output[used - 1] == ' ') used--;
output[used] = '\0';
if (*p == terminator) p++;
*text = p;
}
static void mavlink_crc_accumulate(uint8_t data, rt_uint16_t *checksum) {
uint8_t tmp = data ^ (uint8_t)(*checksum & 0xff);
tmp ^= tmp << 4;
*checksum = (*checksum >> 8) ^ ((rt_uint16_t)tmp << 8) ^
((rt_uint16_t)tmp << 3) ^ ((rt_uint16_t)tmp >> 4);
}
static void mavlink_diag_start(mavlink_diag_parser_t *parser, uint8_t magic) {
parser->magic = magic;
parser->phase = 1;
parser->position = 0;
parser->remaining = 0;
parser->checksum = 0xffff;
parser->received_checksum = 0;
parser->payload_length = 0;
parser->incompat_flags = 0;
parser->heartbeat = false;
}
static void mavlink_diag_feed(mavlink_diag_parser_t *parser,
const uint8_t *data, rt_size_t size,
rt_uint32_t *heartbeat_count) {
rt_size_t i;
for (i = 0; i < size; i++) {
uint8_t ch = data[i];
if (parser->phase == 0) {
if (ch == 0xFE || ch == 0xFD) {
mavlink_diag_start(parser, ch);
}
continue;
}
if (parser->phase == 5) {
parser->remaining--;
if (parser->remaining == 0) parser->phase = 0;
continue;
}
if (parser->phase == 2) {
mavlink_crc_accumulate(ch, &parser->checksum);
parser->remaining--;
if (parser->remaining == 0) parser->phase = 3;
continue;
}
if (parser->phase == 3) {
parser->received_checksum = ch;
parser->phase = 4;
continue;
}
if (parser->phase == 4) {
parser->received_checksum |= (rt_uint16_t)ch << 8;
mavlink_crc_accumulate(50, &parser->checksum);
if (parser->heartbeat &&
parser->checksum == parser->received_checksum) {
(*heartbeat_count)++;
}
if (parser->magic == 0xFD &&
(parser->incompat_flags & 0x01) != 0) {
parser->phase = 5;
parser->remaining = 13;
} else {
parser->phase = 0;
}
continue;
}
mavlink_crc_accumulate(ch, &parser->checksum);
if (parser->position == 0) parser->payload_length = ch;
if (parser->magic == 0xFE && parser->position == 4) {
parser->heartbeat = parser->payload_length == 9 && ch == 0;
parser->remaining = parser->payload_length;
parser->phase = parser->remaining > 0 ? 2 : 3;
} else if (parser->magic == 0xFD) {
if (parser->position == 1) parser->incompat_flags = ch;
if (parser->position == 6) parser->heartbeat = ch == 0;
if (parser->position == 7)
parser->heartbeat = parser->heartbeat && ch == 0;
if (parser->position == 8) {
parser->heartbeat = parser->payload_length == 9 &&
parser->heartbeat && ch == 0;
parser->remaining = parser->payload_length;
parser->phase = parser->remaining > 0 ? 2 : 3;
}
}
parser->position++;
}
}
static void lte_process_urc_line(const char *line) { static void lte_process_urc_line(const char *line) {
const char *p; const char *p;
@ -65,6 +193,9 @@ static void lte_process_urc_line(const char *line) {
lte_dev.socket_recv_pending = true; lte_dev.socket_recv_pending = true;
} else if (rt_strstr(line, "\"closed\"") != RT_NULL) { } else if (rt_strstr(line, "\"closed\"") != RT_NULL) {
lte_dev.socket_closed_pending = true; lte_dev.socket_closed_pending = true;
} else if (rt_strstr(line, "\"pdpdeact\"") != RT_NULL) {
lte_dev.socket_pdpdeact_pending = true;
lte_diag.pdpdeact_count++;
} }
} }
@ -196,6 +327,21 @@ void lte_diag_fmu_rx(rt_size_t size) {
lte_diag.last_fmu_rx_tick = rt_tick_get(); lte_diag.last_fmu_rx_tick = rt_tick_get();
} }
void lte_diag_fmu_data(const uint8_t *data, rt_size_t size) {
if (data == RT_NULL || size == 0) return;
lte_diag_fmu_rx(size);
mavlink_diag_feed(&fmu_mavlink_parser, data, size, &lte_diag.fmu_heartbeats);
}
void lte_diag_server_data(const uint8_t *data, rt_size_t size) {
if (data == RT_NULL || size == 0) return;
lte_diag.server_rx_bytes += size;
lte_diag.server_rx_read_events++;
lte_diag.last_server_rx_tick = rt_tick_get();
mavlink_diag_feed(&server_mavlink_parser, data, size,
&lte_diag.server_heartbeats);
}
void lte_diag_fmu_tx(rt_size_t size) { void lte_diag_fmu_tx(rt_size_t size) {
lte_diag.fmu_tx_bytes += size; lte_diag.fmu_tx_bytes += size;
lte_diag.last_fmu_tx_tick = rt_tick_get(); lte_diag.last_fmu_tx_tick = rt_tick_get();
@ -211,6 +357,26 @@ void lte_diag_connect_attempt(void) {
void lte_diag_connect_success(void) { void lte_diag_connect_success(void) {
lte_diag.connect_tick = rt_tick_get(); lte_diag.connect_tick = rt_tick_get();
lte_diag.last_server_rx_tick = lte_diag.connect_tick; lte_diag.last_server_rx_tick = lte_diag.connect_tick;
lte_diag.last_socket_ack_tick = 0;
lte_diag.socket_acked_bytes = 0;
lte_diag.socket_unacked_bytes = 0;
lte_diag.socket_prompt_timeouts = 0;
lte_diag.socket_read_errors = 0;
lte_diag.socket_ack_errors = 0;
lte_diag.tx_queue_high_water = 0;
lte_diag.conn_fmu_rx_base = lte_diag.fmu_rx_bytes;
lte_diag.conn_fmu_tx_base = lte_diag.fmu_tx_bytes;
lte_diag.conn_server_rx_base = lte_diag.server_rx_bytes;
lte_diag.conn_server_events_base = lte_diag.server_rx_read_events;
lte_diag.conn_socket_tx_base = lte_diag.socket_tx_bytes;
lte_diag.conn_send_ok_base = lte_diag.socket_send_ok;
lte_diag.conn_send_fail_base = lte_diag.socket_send_fail;
lte_diag.conn_ack_queries_base = lte_diag.socket_ack_queries;
lte_diag.conn_queue_drops_base = lte_diag.tx_queue_drops;
lte_diag.conn_fmu_heartbeat_base = lte_diag.fmu_heartbeats;
lte_diag.conn_server_heartbeat_base = lte_diag.server_heartbeats;
rt_memset(&fmu_mavlink_parser, 0, sizeof(fmu_mavlink_parser));
rt_memset(&server_mavlink_parser, 0, sizeof(server_mavlink_parser));
} }
void lte_diag_module_reset(void) { void lte_diag_module_reset(void) {
@ -248,6 +414,7 @@ void BSP_LTE_SetDataTxPaused(bool paused) {
void BSP_LTE_ClearSocketEvents(void) { void BSP_LTE_ClearSocketEvents(void) {
lte_dev.socket_recv_pending = false; lte_dev.socket_recv_pending = false;
lte_dev.socket_closed_pending = false; lte_dev.socket_closed_pending = false;
lte_dev.socket_pdpdeact_pending = false;
socket_open_seen = false; socket_open_seen = false;
socket_open_result = -1; socket_open_result = -1;
socket_urc_line_len = 0; socket_urc_line_len = 0;
@ -347,6 +514,7 @@ int16_t BSP_LTE_QuerySocketSendStatus(uint8_t connect_id) {
lte_diag.socket_acked_bytes = (rt_uint32_t)acked; lte_diag.socket_acked_bytes = (rt_uint32_t)acked;
lte_diag.socket_unacked_bytes = (rt_uint32_t)unacked; lte_diag.socket_unacked_bytes = (rt_uint32_t)unacked;
lte_diag.socket_ack_queries++; lte_diag.socket_ack_queries++;
lte_diag.last_socket_ack_tick = rt_tick_get();
return 0; return 0;
} }
@ -433,6 +601,104 @@ void BSP_LTE_InitLogClock(void) {
} }
} }
static void parse_cereg_snapshot(const char *response) {
const char *p = rt_strstr(response, "+CEREG:");
int value;
if (p == RT_NULL) return;
p += rt_strlen("+CEREG:");
value = parse_decimal(&p);
if (value < 0 || *p != ',') return;
p++;
value = parse_decimal(&p);
if (value < 0) return;
lte_diag.network.cereg = (int8_t)value;
if (*p == ',') {
copy_csv_token(&p, lte_diag.network.tac,
sizeof(lte_diag.network.tac));
copy_csv_token(&p, lte_diag.network.cell,
sizeof(lte_diag.network.cell));
}
}
static void parse_cgatt_snapshot(const char *response) {
const char *p = rt_strstr(response, "+CGATT:");
int value;
if (p == RT_NULL) return;
p += rt_strlen("+CGATT:");
value = parse_decimal(&p);
if (value >= 0) lte_diag.network.cgatt = (int8_t)value;
}
static void parse_qiact_snapshot(const char *response) {
const char *p = rt_strstr(response, "+QIACT:");
int context;
int state;
if (p == RT_NULL) {
lte_diag.network.pdp = 0;
return;
}
p += rt_strlen("+QIACT:");
context = parse_decimal(&p);
if (context < 0 || *p != ',') return;
p++;
state = parse_decimal(&p);
if (context == 1 && state >= 0) lte_diag.network.pdp = (int8_t)state;
}
static void parse_qnwinfo_snapshot(const char *response) {
const char *p = rt_strstr(response, "+QNWINFO:");
char channel[12];
if (p == RT_NULL) return;
p += rt_strlen("+QNWINFO:");
copy_csv_token(&p, lte_diag.network.rat, sizeof(lte_diag.network.rat));
copy_csv_token(&p, lte_diag.network.oper, sizeof(lte_diag.network.oper));
copy_csv_token(&p, lte_diag.network.band, sizeof(lte_diag.network.band));
copy_csv_token(&p, channel, sizeof(channel));
p = channel;
{
int value = parse_decimal(&p);
if (value >= 0) lte_diag.network.channel = (rt_uint32_t)value;
}
}
void BSP_LTE_CollectNetworkSnapshot(void) {
lte_network_snapshot_t *network = &lte_diag.network;
rt_memset(network, 0, sizeof(*network));
network->cereg = -1;
network->cgatt = -1;
network->pdp = -1;
network->csq = -1;
BSP_LTE_SendCmd(AT_CEREG2, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL);
if (BSP_LTE_SendCmd(AT_CEREG, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL) == 0) {
parse_cereg_snapshot((const char *)lte_dev.at_buf);
}
BSP_LTE_SendCmd(AT_CEREG0, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL);
if (BSP_LTE_SendCmd(AT_CGATT, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL) == 0) {
parse_cgatt_snapshot((const char *)lte_dev.at_buf);
}
if (BSP_LTE_SendCmd(AT_QIACT, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL) == 0) {
parse_qiact_snapshot((const char *)lte_dev.at_buf);
}
if (BSP_LTE_SendCmd(AT_QNWINFO, DEFAULT_EXPECT, DEFAULT_ERROR,
LTE_CMD_WAIT_NORMAL) == 0) {
parse_qnwinfo_snapshot((const char *)lte_dev.at_buf);
}
network->csq = BSP_LTE_GetCSQ();
if (network->csq >= 0) lte_dev.csq = network->csq;
}
int16_t BSP_LTE_SendCmd(const char *cmd, const char *expect, const char *error, int16_t BSP_LTE_SendCmd(const char *cmd, const char *expect, const char *error,
uint32_t waittime) { uint32_t waittime) {
lte_diag_at_begin(cmd); lte_diag_at_begin(cmd);
@ -449,6 +715,7 @@ int16_t BSP_LTE_SendCmd(const char *cmd, const char *expect, const char *error,
sizeof(lte_dev.at_buf)); sizeof(lte_dev.at_buf));
if (read_len > 0) { if (read_len > 0) {
lte_diag_uart2_rx((rt_size_t)read_len); lte_diag_uart2_rx((rt_size_t)read_len);
lte_process_text(lte_dev.at_buf, (rt_size_t)read_len);
} }
LOG_I("%s\n", lte_dev.at_buf); LOG_I("%s\n", lte_dev.at_buf);

36
applications/drv_ec800k.h

@ -66,7 +66,9 @@ extern "C" {
#define AT_CGREG "AT+CGREG?\r\n" // GPRS REG 2G #define AT_CGREG "AT+CGREG?\r\n" // GPRS REG 2G
#define AT_CEREG "AT+CEREG?\r\n" // EPS REG 4G #define AT_CEREG "AT+CEREG?\r\n" // EPS REG 4G
#define AT_CEREG0 "AT+CEREG=0\r\n" #define AT_CEREG0 "AT+CEREG=0\r\n"
#define AT_CEREG2 "AT+CEREG=2\r\n"
#define AT_CSQ "AT+CSQ\r\n" #define AT_CSQ "AT+CSQ\r\n"
#define AT_QNWINFO "AT+QNWINFO\r\n"
#define AT_CPSI "AT+CPSI?\r\n" #define AT_CPSI "AT+CPSI?\r\n"
#define AT_CIPMODE "AT+CIPMODE=1\r\n" #define AT_CIPMODE "AT+CIPMODE=1\r\n"
@ -238,6 +240,19 @@ typedef enum {
LTE_DISC_SOCKET_SEND, LTE_DISC_SOCKET_SEND,
} lte_disconnect_reason_t; } lte_disconnect_reason_t;
typedef struct {
int8_t cereg;
int8_t cgatt;
int8_t pdp;
int8_t csq;
char rat[12];
char oper[16];
char band[16];
char tac[9];
char cell[12];
rt_uint32_t channel;
} lte_network_snapshot_t;
typedef struct { typedef struct {
rt_uint32_t uart2_rx_bytes; rt_uint32_t uart2_rx_bytes;
rt_uint32_t uart2_tx_bytes; rt_uint32_t uart2_tx_bytes;
@ -270,17 +285,34 @@ typedef struct {
rt_uint32_t socket_ack_errors; rt_uint32_t socket_ack_errors;
rt_uint32_t tx_queue_drops; rt_uint32_t tx_queue_drops;
rt_uint32_t tx_queue_high_water; rt_uint32_t tx_queue_high_water;
rt_uint32_t fmu_heartbeats;
rt_uint32_t server_heartbeats;
rt_uint32_t pdpdeact_count;
rt_uint32_t conn_fmu_rx_base;
rt_uint32_t conn_fmu_tx_base;
rt_uint32_t conn_server_rx_base;
rt_uint32_t conn_server_events_base;
rt_uint32_t conn_socket_tx_base;
rt_uint32_t conn_send_ok_base;
rt_uint32_t conn_send_fail_base;
rt_uint32_t conn_ack_queries_base;
rt_uint32_t conn_queue_drops_base;
rt_uint32_t conn_fmu_heartbeat_base;
rt_uint32_t conn_server_heartbeat_base;
rt_tick_t last_uart2_rx_tick; rt_tick_t last_uart2_rx_tick;
rt_tick_t last_uart2_tx_tick; rt_tick_t last_uart2_tx_tick;
rt_tick_t last_fmu_rx_tick; rt_tick_t last_fmu_rx_tick;
rt_tick_t last_fmu_tx_tick; rt_tick_t last_fmu_tx_tick;
rt_tick_t last_server_rx_tick; rt_tick_t last_server_rx_tick;
rt_tick_t last_socket_ack_tick;
rt_tick_t connect_tick; rt_tick_t connect_tick;
rt_tick_t last_disconnect_tick; rt_tick_t last_disconnect_tick;
rt_tick_t last_at_elapsed; rt_tick_t last_at_elapsed;
rt_int32_t last_at_result; rt_int32_t last_at_result;
char last_at_cmd[20]; char last_at_cmd[20];
lte_disconnect_reason_t last_disconnect_reason; lte_disconnect_reason_t last_disconnect_reason;
lte_network_snapshot_t network;
bool disconnect_report_pending;
} lte_diag_t; } lte_diag_t;
extern lte_diag_t lte_diag; extern lte_diag_t lte_diag;
@ -292,6 +324,8 @@ void lte_diag_uart2_tx(rt_size_t size);
void lte_diag_uart_error(const char *name, rt_uint32_t error_code); void lte_diag_uart_error(const char *name, rt_uint32_t error_code);
void lte_diag_fmu_rx(rt_size_t size); void lte_diag_fmu_rx(rt_size_t size);
void lte_diag_fmu_tx(rt_size_t size); void lte_diag_fmu_tx(rt_size_t size);
void lte_diag_fmu_data(const uint8_t *data, rt_size_t size);
void lte_diag_server_data(const uint8_t *data, rt_size_t size);
void lte_diag_connect_attempt(void); void lte_diag_connect_attempt(void);
void lte_diag_connect_success(void); void lte_diag_connect_success(void);
void lte_diag_disconnect(lte_disconnect_reason_t reason); void lte_diag_disconnect(lte_disconnect_reason_t reason);
@ -321,6 +355,7 @@ typedef struct {
volatile bool data_tx_paused; volatile bool data_tx_paused;
volatile bool socket_recv_pending; volatile bool socket_recv_pending;
volatile bool socket_closed_pending; volatile bool socket_closed_pending;
volatile bool socket_pdpdeact_pending;
} CLte_dev_t; } CLte_dev_t;
extern CLte_dev_t lte_dev; extern CLte_dev_t lte_dev;
@ -350,6 +385,7 @@ int16_t BSP_LTE_ReadSocketData(uint8_t connect_id, uint8_t *data,
int16_t BSP_LTE_QuerySocketSendStatus(uint8_t connect_id); int16_t BSP_LTE_QuerySocketSendStatus(uint8_t connect_id);
void BSP_LTE_PollSocketUrc(uint32_t waittime); void BSP_LTE_PollSocketUrc(uint32_t waittime);
void BSP_LTE_ClearSocketEvents(void); void BSP_LTE_ClearSocketEvents(void);
void BSP_LTE_CollectNetworkSnapshot(void);
int BSP_LTE_GetICCID(char *pICCID); int BSP_LTE_GetICCID(char *pICCID);

Loading…
Cancel
Save