#include "VK_Client.h" #include #include "VK_Com.h" #include "drv_ec800k.h" #include "VK_Log.h" #include "rtdef.h" #include "rtthread.h" #include "rttypes.h" #ifdef EDU_TRAINING #if defined(__CC_ARM) && !defined(__clang__) #define VK_MAVLINK_DO_PRAGMA(x) _Pragma(#x) #define __pragma(x) VK_MAVLINK_DO_PRAGMA(x) #pragma anon_unions #endif #include "VKFly/mavlink.h" #include "mavlink_helpers.h" #if defined(__CC_ARM) && !defined(__clang__) #undef __pragma #undef VK_MAVLINK_DO_PRAGMA #endif #endif #define DBG_TAG "LINK_LOG" #define DBG_LVL DBG_INFO #include "rtdbg.h" static char cmd_cmd[128] = {0}; no_carrier_match_t _no_carrier_t = {0}; /*关闭TCP连接*/ void client_tcp_close(Cclient_t *client) { char close_cmd[24]; client->connect_sta = false; rt_snprintf(close_cmd, sizeof(close_cmd), AT_QICLOSE, client->connect_ID); BSP_LTE_SendCmd(close_cmd, DEFAULT_EXPECT, DEFAULT_ERROR, LTE_CMD_WAIT_QICLOSE); client->error_cnt = 0; } static int no_carrier_char_parser(uint8_t ch){ int ret = 0; switch(_no_carrier_t.match_stage){ case 0: if(ch == 0x4E){ _no_carrier_t.match_stage++; }else { _no_carrier_t.match_stage = 0; ret = -1; } break; case 1: if(ch == 0x4F){ _no_carrier_t.match_stage++; }else{ _no_carrier_t.match_stage = 0; ret = -1; } break; case 2: if(ch == 0x20){ _no_carrier_t.match_stage++; }else{ _no_carrier_t.match_stage = 0; ret = -1; } break; case 3: if(ch == 0x43){ _no_carrier_t.match_stage++; }else{ _no_carrier_t.match_stage = 0; ret = -1; } break; case 4: if(ch == 0x41){ _no_carrier_t.match_stage++; }else{ _no_carrier_t.match_stage = 0; ret = -1; } break; case 5: if(ch == 0x52){ _no_carrier_t.match_stage++; }else{ _no_carrier_t.match_stage = 0; ret = -1; } break; case 6: if(ch == 0x52){ _no_carrier_t.match_stage++; }else{ _no_carrier_t.match_stage = 0; ret = -1; } break; case 7: if(ch == 0x49){ _no_carrier_t.match_stage++; }else{ _no_carrier_t.match_stage = 0; ret = -1; } break; case 8: if(ch == 0x45){ _no_carrier_t.match_stage++; }else{ _no_carrier_t.match_stage = 0; ret = -1; } break; case 9: if(ch == 0x52){ ret = 1; _no_carrier_t.match_stage = 0; }else{ _no_carrier_t.match_stage = 0; ret = -1; } break; } return ret; } static void no_carrier_match(uint8_t * at_buf,rt_size_t len){ for(int i = 0;i < len;i++){ if(no_carrier_char_parser(at_buf[i]) == 1){ _no_carrier_t.match_flag = COMPLETE_MATCH; } } } static const char *disconnect_reason_name(lte_disconnect_reason_t reason) { switch (reason) { case LTE_DISC_CLOSED: return "CLOSED"; case LTE_DISC_NO_CARRIER: return "NO_CARRIER"; case LTE_DISC_NO_CARRIER_SPLIT: return "NO_CARRIER_SPLIT"; case LTE_DISC_AT_TIMEOUT: return "AT_TIMEOUT"; case LTE_DISC_QIOPEN_FAILED: return "QIOPEN_FAILED"; case LTE_DISC_MODULE_RESET: return "MODULE_RESET"; default: return "UNKNOWN"; } } static rt_tick_t diag_age(rt_tick_t now, rt_tick_t tick) { return tick == 0 ? 0 : now - tick; } void lte_diag_disconnect(lte_disconnect_reason_t reason) { rt_tick_t now = rt_tick_get(); rt_size_t heap_total = 0; rt_size_t heap_used = 0; rt_size_t heap_max = 0; rt_memory_info(&heap_total, &heap_used, &heap_max); lte_diag.disconnect_count++; lte_diag.last_disconnect_reason = reason; lte_diag.last_disconnect_tick = now; LOG_I("[DISC] reason=%s count=%u connected_ticks=%u", disconnect_reason_name(reason), lte_diag.disconnect_count, lte_diag.connect_tick == 0 ? 0 : now - lte_diag.connect_tick); LOG_I("[DISC] uart2_rx=%u uart2_tx=%u events=%u write_fail=%u errors=%u/%u last_err=0x%X", lte_diag.uart2_rx_bytes, lte_diag.uart2_tx_bytes, 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] age_uart2_rx=%u age_uart2_tx=%u age_fmu_rx=%u age_server_rx=%u", diag_age(now, lte_diag.last_uart2_rx_tick), diag_age(now, lte_diag.last_uart2_tx_tick), diag_age(now, lte_diag.last_fmu_rx_tick), diag_age(now, lte_diag.last_server_rx_tick)); LOG_I("[DISC] at_cmd=%s result=%d elapsed_ticks=%u timeouts=%u errors=%u", lte_diag.last_at_cmd, lte_diag.last_at_result, lte_diag.last_at_elapsed, lte_diag.at_timeouts, lte_diag.at_errors); 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); lte_dev.client1->connect_sta = false; } /*将EC800K软件复位*/ int16_t EC800K_Reset(void) { int16_t rst = -1; lte_diag_module_reset(); BSP_LTE_SetDataTxPaused(true); lte_dev.config_sta = false; lte_dev.reset_flag = DTU_CF_NEED_RESET; lte_dev.client1->connect_sta = false; //lte_dev.client2->connect_sta = false; rt_thread_mdelay(3000); BSP_LTE_SendData((uint8_t *)"+++", 3); rt_thread_mdelay(2000); BSP_LTE_SendData((uint8_t *)"+++", 3); rt_thread_mdelay(2000); uint8_t try_count = 5; do { rt_thread_mdelay(1000); rst = BSP_LTE_SendCmd(SOFT_RESET, DEFAULT_EXPECT, DEFAULT_ERROR, LTE_CMD_WAIT_LONG); if (0 == rst) return 0; try_count--; } while (try_count > 0); return rst; } int16_t client_tcp_connect(Cclient_t *client) { int cmd_len; int16_t rtn = 0; if (lte_dev.config_sta == false) return rtn; if (client->connect_sta == true) return rtn; lte_diag_connect_attempt(); if (lte_dev.reset_flag == DTU_CF_NEED_RESET) { /*查询PDP场景*/ if (0 != BSP_LTE_SendCmd(AT_QIACT, "+QIACT: 1,1,1,", DEFAULT_ERROR, LTE_CMD_WAIT_QIACT)) { /*如果查询PDP场景未设置成功,则激活PDP场景模式*/ if (0 != BSP_LTE_SendCmd(AT_QIACT1, DEFAULT_EXPECT, DEFAULT_ERROR, LTE_CMD_WAIT_QIACT)) { BSP_LTE_SendCmd(AT_QIDEACT, NETCLOSE_SUCCESS, NETCLOSE_FAILURE, LTE_CMD_WAIT_QIDEACT); // client->error_cnt++; return -1; } } /* Query once after PDP is available, so network time has had a chance to sync. */ BSP_LTE_InitLogClock(); // BSP_LTE_SendCmd(AT_CFG_TRANS_SIZE, DEFAULT_EXPECT, DEFAULT_ERROR, LTE_CMD_WAIT_NORMAL); BSP_LTE_SendCmd(AT_CFG_TRANS_WAITTM, DEFAULT_EXPECT, DEFAULT_ERROR, LTE_CMD_WAIT_NORMAL); BSP_LTE_SendCmd(AT_CFG_PASSIVE_CLOSED, DEFAULT_EXPECT, DEFAULT_ERROR, LTE_CMD_WAIT_NORMAL); BSP_LTE_SendCmd(AT_CFG_TCP_KEEPALIVE, DEFAULT_EXPECT, DEFAULT_ERROR, LTE_CMD_WAIT_NORMAL); // } // 1. 检查网络信号 lte_dev.csq = BSP_LTE_GetCSQ(); // 2, 打开链接 memset(cmd_cmd, 0, sizeof(cmd_cmd)); cmd_len = rt_snprintf(cmd_cmd, sizeof(cmd_cmd), AT_QIOPEN_TRANS, client->connect_ID, client->mode, client->ip, client->port); if (cmd_len < 0 || cmd_len >= (int)sizeof(cmd_cmd)) { LOG_E("QIOPEN command is too long"); lte_diag.qioopen_failures++; return -1; } /* 透传模式成功返回 CONNECT;一次尝试只发送一次 QIOPEN。 */ while (0 != BSP_LTE_SendCmd(cmd_cmd, CONNECTE_OK, DEFAULT_ERROR, LTE_CMD_WAIT_QIOPEN)) { lte_diag.qioopen_failures++; client_tcp_close(client); #ifdef debug_mode EC800K_Reset(); client->error_cnt = 0; return 0; #else client->error_cnt++; if (client->error_cnt > 5) { lte_diag_disconnect(LTE_DISC_QIOPEN_FAILED); EC800K_Reset(); client->error_cnt = 0; return 0; } rt_thread_mdelay((client->error_cnt < 5 ? client->error_cnt : 5) * 1000); #endif } client->connect_sta = true; BSP_LTE_SetDataTxPaused(false); lte_diag_connect_success(); client->error_cnt = 0; lte_dev.reset_flag = DTU_CF_NO_NEED_RESET; #ifdef EDU_TRAINING mavlink_message_t msg = {0}; uint8_t mav_buf[MAVLINK_MAX_PACKET_LEN] = {0}; uint16_t mav_len = 0; mavlink_dtu_status_t _status_t = {0}; _status_t.csq = lte_dev.csq; rt_memcpy(_status_t.sn, lte_dev.iccid, sizeof(_status_t.sn)); rt_memcpy(_status_t.imei,lte_dev.imei,sizeof(_status_t.imei)); mavlink_msg_dtu_status_encode(1, MAV_COMP_ID_TELEMETRY_RADIO, &msg, &_status_t); mav_len = mavlink_msg_to_send_buffer(mav_buf, &msg); for (int i = 0; i < 3; i++) { BSP_LTE_SendData(mav_buf, mav_len); } rt_device_t fmu_com = fmu_com_get(); if (fmu_com != RT_NULL) { rt_device_write(fmu_com, 0, mav_buf, mav_len); } #else char buf[128] = {0}; rt_sprintf(buf, "{\"sn\":\"%s\",\"client_id\":\"%s\",\"csq\":\"%d\"}\r\n", lte_dev.iccid, lte_dev.imei, lte_dev.csq); BSP_LTE_SendData((uint8_t *)buf, sizeof(buf)); BSP_LTE_SendData((uint8_t *)buf, sizeof(buf)); BSP_LTE_SendData((uint8_t *)buf, sizeof(buf)); //hw_printf(buf); #endif return rtn; } #if LTE_SERVER_SILENCE_TIMEOUT_SEC > 0 static rt_tick_t last_rx_tick = 0; #endif /* Leave transparent mode only after the UART has been quiet for the * required guard time. The caller keeps data_tx_paused asserted until the * next successful QIOPEN. */ static bool client_exit_transparent_mode(CLte_dev_t *pLte_dev) { rt_tick_t deadline; rt_ssize_t len; BSP_LTE_SetDataTxPaused(true); rt_thread_mdelay(1000); BSP_LTE_SendData((uint8_t *)"+++", 3); rt_thread_mdelay(1000); deadline = rt_tick_get() + 2000; while ((rt_int32_t)(rt_tick_get() - deadline) < 0) { if (pLte_dev->com_dev_rx_sem != RT_NULL) { rt_sem_take(pLte_dev->com_dev_rx_sem, 100); } rt_memset(pLte_dev->at_buf, 0, sizeof(pLte_dev->at_buf)); len = rt_device_read(pLte_dev->com_dev, 0, pLte_dev->at_buf, sizeof(pLte_dev->at_buf) - 1); if (len > 0) { lte_diag_uart2_rx((rt_size_t)len); pLte_dev->at_buf[len] = '\0'; if (rt_strstr((const char *)pLte_dev->at_buf, DEFAULT_EXPECT) != RT_NULL) { return true; } } } return false; } void client_yield(CLte_dev_t *pLte_dev) { while (1) { if (pLte_dev->client1->connect_sta == true) { rt_err_t ret = rt_sem_take(pLte_dev->com_dev_rx_sem, 1000); #if LTE_SERVER_SILENCE_TIMEOUT_SEC > 0 if (ret != RT_EOK && rt_tick_get() - last_rx_tick > RT_TICK_PER_SECOND * LTE_SERVER_SILENCE_TIMEOUT_SEC) { lte_diag.server_silence_timeout_count++; LOG_W("server silence timeout, reconnect\n"); if (client_exit_transparent_mode(pLte_dev)) { pLte_dev->client1->connect_sta = false; client_tcp_close(pLte_dev->client1); } else { lte_diag_disconnect(LTE_DISC_AT_TIMEOUT); EC800K_Reset(); } continue; } #endif if (RT_EOK == ret) { rt_ssize_t len = 0; while (1) { rt_memset(pLte_dev->at_buf, 0, sizeof(pLte_dev->at_buf)); len = rt_device_read(pLte_dev->com_dev, 0, pLte_dev->at_buf, sizeof(pLte_dev->at_buf)); if (len > 0) { lte_diag_uart2_rx((rt_size_t)len); /*收到TCP关闭的消息*/ if (strstr((const char *)pLte_dev->at_buf, CLOSED)) { LOG_W("[URC] closed received"); lte_diag_disconnect(LTE_DISC_CLOSED); BSP_LTE_SetDataTxPaused(true); client_tcp_close(pLte_dev->client1); break; } else if (strstr((const char *)lte_dev.at_buf, "NO CARRIER")) { lte_diag_disconnect(LTE_DISC_NO_CARRIER); BSP_LTE_SetDataTxPaused(true); client_tcp_close(pLte_dev->client1); _no_carrier_t.match_flag = NO_MATCH; break; } else if(strstr((const char *)lte_dev.at_buf, "\r\n")) { _no_carrier_t.match_flag = HALF_MATCH; } if (_no_carrier_t.match_flag == HALF_MATCH) { no_carrier_match(pLte_dev->at_buf, len); if (_no_carrier_t.match_flag == COMPLETE_MATCH) { lte_diag_disconnect(LTE_DISC_NO_CARRIER_SPLIT); BSP_LTE_SetDataTxPaused(true); client_tcp_close(pLte_dev->client1); _no_carrier_t.match_flag = NO_MATCH; break; } } 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(); if (fmu_com) { rt_ssize_t written = rt_device_write(fmu_com, 0, pLte_dev->at_buf, len); if (written > 0) { lte_diag_fmu_tx((rt_size_t)written); } } }else{ break; } #if LTE_SERVER_SILENCE_TIMEOUT_SEC > 0 last_rx_tick = rt_tick_get(); #endif } } } else { if(pLte_dev->reset_flag == DTU_CF_NEED_RESET){ BSP_LTE_Config(); } client_tcp_connect(pLte_dev->client1); #if LTE_SERVER_SILENCE_TIMEOUT_SEC > 0 last_rx_tick = rt_tick_get(); #endif } } } void client_task(void) { client_yield(<e_dev); } //------------------End of File----------------------------