#include "ohos_init.h"
#include "los_task.h"
#include "lz_hardware.h"
#include "config_network.h"
#include "lwip/tcp.h"
#include "lwip/ip_addr.h"
#include <stdio.h>
#include <string.h>
#define SERVER_IP "192.168.111.61"
#define SERVER_PORT 20108
#define RECV_BUFFER_SIZE 512
static struct tcp_pcb *g_tpcb = NULL;
static int g_send_cnt = 0;
static int is_connected = 0;
// 接收回调:pbuf链式拼接
static err_t tcp_raw_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
if (p == NULL) { tcp_close(tpcb); is_connected = 0; return ERR_OK; }
char recv_buf[RECV_BUFFER_SIZE] = {0};
int offset = 0;
struct pbuf *q;
for (q = p; q && offset < RECV_BUFFER_SIZE - 1; q = q->next) {
int copy_len = q->len < (RECV_BUFFER_SIZE - 1 - offset) ? q->len : (RECV_BUFFER_SIZE - 1 - offset);
memcpy(recv_buf + offset, q->payload, copy_len);
offset += copy_len;
}
printf("[RAW RECV] %s\r\n", recv_buf);
tcp_recved(tpcb, p->tot_len); // 滑动窗口上报
pbuf_free(p);
return ERR_OK;
}
static void tcp_raw_err(void *arg, err_t err)
{
printf("[ERROR] TCP异常\r\n");
g_tpcb = NULL;
is_connected = 0;
}
static err_t tcp_raw_connected(void *arg, struct tcp_pcb *tpcb, err_t err)
{
if (err != ERR_OK) { tcp_close(tpcb); is_connected = 0; return err; }
g_tpcb = tpcb;
tcp_recv(tpcb, tcp_raw_recv);
tcp_err(tpcb, tcp_raw_err);
tcp_nagle_disable(tpcb);
is_connected = 2;
printf("[SUCCESS] TCP连接成功\r\n");
return ERR_OK;
}
static void tcp_raw_connect(void)
{
ip_addr_t server_ip;
server_ip.addr = inet_addr(SERVER_IP);
struct tcp_pcb *pcb = tcp_new();
tcp_connect(pcb, &server_ip, SERVER_PORT, tcp_raw_connected);
is_connected = 1;
}
static err_t tcp_raw_safe_send(const char *data, u16_t len)
{
if (!g_tpcb || !data || !len) return ERR_CONN;
if (tcp_sndbuf(g_tpcb) < len) return ERR_MEM;
err_t ret = tcp_write(g_tpcb, data, len, TCP_WRITE_FLAG_COPY);
if (ret == ERR_OK) tcp_output(g_tpcb);
return ret;
}
void tcp_raw_single_task(unsigned long arg)
{
WifiLinkedInfo info;
while (1) {
if (GetLinkedInfo(&info) != WIFI_SUCCESS || info.connState != WIFI_CONNECTED) {
LOS_Msleep(1000); continue;
}
if (is_connected == 0) tcp_raw_connect();
if (is_connected == 2) {
char buf[64];
snprintf(buf, sizeof(buf), "RK2206 Raw TCP Test:%d\r\n", g_send_cnt++);
tcp_raw_safe_send(buf, strlen(buf));
}
LOS_Msleep(1000);
}
}
void tcp_client_raw_demo_init(void)
{
unsigned int task_id;
TSK_INIT_PARAM_S param = {0};
param.pfnTaskEntry = (TSK_ENTRY_FUNC)tcp_raw_single_task;
param.uwStackSize = 10240;
param.usTaskPrio = 24;
param.pcName = "tcp_raw_task";
LOS_TaskCreate(&task_id, ¶m);
}
APP_FEATURE_INIT(tcp_client_raw_demo_init);