diff --git a/applications/VK_Client.c b/applications/VK_Client.c index e269d9a..a3e83cd 100644 --- a/applications/VK_Client.c +++ b/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_tick_t last_ack_query_tick = 0; +static void lte_diag_finish_disconnect(void); + no_carrier_match_t _no_carrier_t = {0}; /*关闭TCP连接*/ @@ -44,6 +46,10 @@ void client_tcp_close(Cclient_t *client) { client->connect_sta = false; BSP_LTE_SetDataTxPaused(true); + if (lte_diag.disconnect_report_pending) { + BSP_LTE_CollectNetworkSnapshot(); + lte_diag_finish_disconnect(); + } BSP_LTE_ClearSocketEvents(); fmu_net_queue_reset(); socket_tx_pending = 0; @@ -177,6 +183,7 @@ void lte_diag_disconnect(lte_disconnect_reason_t reason) { lte_diag.disconnect_count++; lte_diag.last_disconnect_reason = reason; lte_diag.last_disconnect_tick = now; + lte_diag.disconnect_report_pending = true; LOG_I("[DISC] reason=%s count=%u connected_ticks=%u", 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_error_count, lte_diag.uart3_error_count, 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); LOG_I("[DISC] acked=%u unacked=%u ack_queries=%u ack_errors=%u", 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", lte_diag.connect_attempts, lte_diag.reconnect_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; } +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 = <e_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软件复位*/ 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(); - 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) { rt_ssize_t written = rt_device_write(fmu_com, 0, pLte_dev->at_buf, len); @@ -486,9 +574,7 @@ void client_yield(CLte_dev_t *pLte_dev) { } 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 last_rx_tick = lte_diag.last_server_rx_tick; #endif diff --git a/applications/VK_Com.c b/applications/VK_Com.c index 7ade07e..89aa493 100644 --- a/applications/VK_Com.c +++ b/applications/VK_Com.c @@ -132,7 +132,7 @@ void com_task(void) { while (1) { len = rt_device_read(fmu_com, 0, buff, sizeof(buff)); if (len > 0) { - lte_diag_fmu_rx(len); + lte_diag_fmu_data(buff, len); if (lte_dev.client1->connect_sta == true && lte_dev.data_tx_paused == false) { /* 仅在客户端2连接时转发 */ diff --git a/applications/drv_ec800k.c b/applications/drv_ec800k.c index 7d81634..e0a9c1b 100644 --- a/applications/drv_ec800k.c +++ b/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 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) { int value = 0; bool found = false; @@ -57,6 +72,119 @@ static int parse_decimal(const char **text) { 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) { const char *p; @@ -65,6 +193,9 @@ static void lte_process_urc_line(const char *line) { lte_dev.socket_recv_pending = true; } else if (rt_strstr(line, "\"closed\"") != RT_NULL) { 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(); } +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, <e_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, + <e_diag.server_heartbeats); +} + void lte_diag_fmu_tx(rt_size_t size) { lte_diag.fmu_tx_bytes += size; 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) { lte_diag.connect_tick = rt_tick_get(); 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) { @@ -248,6 +414,7 @@ void BSP_LTE_SetDataTxPaused(bool paused) { void BSP_LTE_ClearSocketEvents(void) { lte_dev.socket_recv_pending = false; lte_dev.socket_closed_pending = false; + lte_dev.socket_pdpdeact_pending = false; socket_open_seen = false; socket_open_result = -1; 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_unacked_bytes = (rt_uint32_t)unacked; lte_diag.socket_ack_queries++; + lte_diag.last_socket_ack_tick = rt_tick_get(); 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 = <e_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, uint32_t waittime) { 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)); if (read_len > 0) { 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); diff --git a/applications/drv_ec800k.h b/applications/drv_ec800k.h index e8d551b..f518a45 100644 --- a/applications/drv_ec800k.h +++ b/applications/drv_ec800k.h @@ -66,7 +66,9 @@ extern "C" { #define AT_CGREG "AT+CGREG?\r\n" // GPRS REG 2G #define AT_CEREG "AT+CEREG?\r\n" // EPS REG 4G #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_QNWINFO "AT+QNWINFO\r\n" #define AT_CPSI "AT+CPSI?\r\n" #define AT_CIPMODE "AT+CIPMODE=1\r\n" @@ -238,6 +240,19 @@ typedef enum { LTE_DISC_SOCKET_SEND, } 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 { rt_uint32_t uart2_rx_bytes; rt_uint32_t uart2_tx_bytes; @@ -270,17 +285,34 @@ typedef struct { rt_uint32_t socket_ack_errors; rt_uint32_t tx_queue_drops; 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_tx_tick; rt_tick_t last_fmu_rx_tick; rt_tick_t last_fmu_tx_tick; rt_tick_t last_server_rx_tick; + rt_tick_t last_socket_ack_tick; rt_tick_t connect_tick; rt_tick_t last_disconnect_tick; rt_tick_t last_at_elapsed; rt_int32_t last_at_result; char last_at_cmd[20]; lte_disconnect_reason_t last_disconnect_reason; + lte_network_snapshot_t network; + bool disconnect_report_pending; } lte_diag_t; 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_fmu_rx(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_success(void); void lte_diag_disconnect(lte_disconnect_reason_t reason); @@ -321,6 +355,7 @@ typedef struct { volatile bool data_tx_paused; volatile bool socket_recv_pending; volatile bool socket_closed_pending; + volatile bool socket_pdpdeact_pending; } CLte_dev_t; 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); void BSP_LTE_PollSocketUrc(uint32_t waittime); void BSP_LTE_ClearSocketEvents(void); +void BSP_LTE_CollectNetworkSnapshot(void); int BSP_LTE_GetICCID(char *pICCID);