#include "tcp_client.h" #include "FreeRTOS.h" #include "task.h" #include "queue.h" #include "lwip/api.h" #include "lwip/ip_addr.h" #include "app_runtime.h" #include "config.h" #include "route_msg.h" static void tcp_client_worker(struct netconn *conn, uint8_t link_index) { struct netbuf *buf; const device_config_t *cfg = config_get(); uint8_t uart_endpoint = config_uart_index_to_endpoint(cfg->links[link_index].uart); uint8_t src_endpoint = config_link_index_to_endpoint(link_index); err_t err; route_msg_t *tx_msg; netconn_set_recvtimeout(conn, 10); for (;;) { err = netconn_recv(conn, &buf); if (err == ERR_OK) { do { void *data; uint16_t len; netbuf_data(buf, &data, &len); (void)route_send(xTcpRxQueue, src_endpoint, uart_endpoint, (link_index == CONFIG_LINK_C1) ? ROUTE_CONN_C1 : ROUTE_CONN_C2, (const uint8_t *)data, len, pdMS_TO_TICKS(10)); } while (netbuf_next(buf) >= 0); netbuf_delete(buf); } else if (err != ERR_TIMEOUT) { break; } while (xQueueReceive(xLinkTxQueues[link_index], &tx_msg, 0) == pdPASS) { err = netconn_write(conn, tx_msg->data, tx_msg->len, NETCONN_COPY); route_msg_free(tx_msg); if (err != ERR_OK) { return; } } } } static void tcp_client_task(uint8_t link_index) { const device_config_t *cfg; struct netconn *conn; ip_addr_t remote_ip; uint32_t delay_ms; for (;;) { while (g_netif_ready == pdFALSE) { vTaskDelay(pdMS_TO_TICKS(100)); } cfg = config_get(); if (cfg->links[link_index].enabled == 0u) { vTaskDelay(pdMS_TO_TICKS(500)); continue; } delay_ms = (cfg->reconnect_interval_ms == 0u) ? 3000u : cfg->reconnect_interval_ms; conn = netconn_new(NETCONN_TCP); if (conn == NULL) { vTaskDelay(pdMS_TO_TICKS(delay_ms)); continue; } if (cfg->links[link_index].local_port != 0u) { (void)netconn_bind(conn, IP_ADDR_ANY, cfg->links[link_index].local_port); } IP_ADDR4(&remote_ip, cfg->links[link_index].remote_ip[0], cfg->links[link_index].remote_ip[1], cfg->links[link_index].remote_ip[2], cfg->links[link_index].remote_ip[3]); if (netconn_connect(conn, &remote_ip, cfg->links[link_index].remote_port) == ERR_OK) { tcp_client_worker(conn, link_index); } netconn_close(conn); netconn_delete(conn); vTaskDelay(pdMS_TO_TICKS(delay_ms)); } } void TcpCliTask_C1(void *argument) { (void)argument; tcp_client_task(CONFIG_LINK_C1); } void TcpCliTask_C2(void *argument) { (void)argument; tcp_client_task(CONFIG_LINK_C2); }