Files
STM32F4-Base/Drivers/BSP/CH395F/ch395f_test.c
2026-07-19 13:09:06 +08:00

665 lines
20 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* 模块名称CH395F Driver Test Suite
* 模块功能CH395F 驱动各功能模块的测试入口,分阶段组织测试用例
* 适用平台STM32F4 系列CH395F 以太网芯片)
* 作者:王建锋
* 创建日期2026-07-19
* 修改记录:
* 2026-07-19 Phase 1/2/3 implemented
*/
/* 头文件包含区 */
#include "ch395f_test.h"
#include "ch395f.h"
#include "net_socket.h"
#define DBG_TAG "[CH395T]"
#include "dbg_log.h"
#include <string.h>
#include <stdio.h>
test_stats_t g_test_stats;
/*
* Phase 2 配置默认值
*/
#ifndef PHASE2_REMOTE_IP
#define PHASE2_REMOTE_IP "192.168.1.2"
#endif
#ifndef PHASE2_REMOTE_PORT
#define PHASE2_REMOTE_PORT 8081
#endif
#ifndef PHASE2_LOCAL_PORT
#define PHASE2_LOCAL_PORT 50000
#endif
#ifndef PHASE2_LOOP_COUNT
#define PHASE2_LOOP_COUNT 3
#endif
#ifndef PHASE2_TIMEOUT_MS
#define PHASE2_TIMEOUT_MS 10000
#endif
/*
* Phase 3 配置默认值
*/
#ifndef PHASE3_REMOTE_IP
#define PHASE3_REMOTE_IP "192.168.1.2"
#endif
#ifndef PHASE3_REMOTE_PORT
#define PHASE3_REMOTE_PORT 8082
#endif
#ifndef PHASE3_LOCAL_PORT
#define PHASE3_LOCAL_PORT 60000
#endif
#ifndef PHASE3_ECHO_COUNT
#define PHASE3_ECHO_COUNT 30
#endif
#ifndef PHASE3_TIMEOUT_MS
#define PHASE3_TIMEOUT_MS 30000
#endif
/*
* 恢复 TCP Server 多连接模式的数据 Socket 配置
*/
static void restore_data_sockets(uint16_t port)
{
int i;
for (i = NET_TCP_SERVER_DATA_SOCK_START; i < NET_MAX_SOCKETS; i++)
{
ch395f_set_proto_type((uint8_t)i, CH395F_PROTO_TYPE_TCP);
ch395f_set_sour_port((uint8_t)i, port);
}
DBG_INFO("data socks restored (port %d)", port);
}
/*
* ============================ Phase 1 ============================
*/
void ch395f_phase1_tests(void)
{
uint8_t i;
int ver;
DBG_INFO("=== CH395F Phase 1 Tests ===");
/* Test 1: GET_VERSION */
ver = ch395f_get_version();
TEST_CHECK(ver > 0, "GET_VERSION: 0x%02X (ver=%d)", ver, ver & 0x3F);
/* Test 2: GET_CMD_STATUS */
uint8_t cmd_st = ch395f_get_cmd_status();
TEST_CHECK(cmd_st == CH395F_ERR_SUCCESS,
"GET_CMD_STATUS: 0x%02X (%s)", cmd_st,
cmd_st == CH395F_ERR_SUCCESS ? "SUCCESS" :
cmd_st == CH395F_ERR_BUSY ? "BUSY" : "OTHER");
/* Test 3: GET_IP_INF */
uint8_t ip_info[20];
ch395f_get_ip_inf(ip_info);
DBG_INFO("GET_IP_INF:");
DBG_INFO(" IP: %d.%d.%d.%d", ip_info[0], ip_info[1], ip_info[2], ip_info[3]);
DBG_INFO(" GW: %d.%d.%d.%d", ip_info[4], ip_info[5], ip_info[6], ip_info[7]);
DBG_INFO(" MASK: %d.%d.%d.%d", ip_info[8], ip_info[9], ip_info[10], ip_info[11]);
DBG_INFO(" DNS1: %d.%d.%d.%d", ip_info[12], ip_info[13], ip_info[14], ip_info[15]);
DBG_INFO(" DNS2: %d.%d.%d.%d", ip_info[16], ip_info[17], ip_info[18], ip_info[19]);
TEST_CHECK(ip_info[0]==192 && ip_info[1]==168 && ip_info[2]==1 && ip_info[3]==100,
"IP match");
TEST_CHECK(ip_info[4]==192 && ip_info[5]==168 && ip_info[6]==1 && ip_info[7]==1,
"GW match");
TEST_CHECK(ip_info[8]==255 && ip_info[9]==255 && ip_info[10]==255 && ip_info[11]==0,
"MASK match");
/* Test 4: GINT_STATUS_ALL (2-byte version) */
uint16_t gint_all = ch395f_get_glob_int_status_all();
TEST_CHECK((gint_all & 0xFF) == 0x04 || (gint_all & 0xFF) == 0x00,
"GINT_STATUS_ALL: 0x%04X (lo=0x%02X hi=0x%02X)",
gint_all, gint_all & 0xFF, (gint_all >> 8) & 0xFF);
/* Test 5: GINT_STATUS (1-byte version) — read-clear check */
uint8_t gint_1b = ch395f_get_glob_int_status();
TEST_CHECK(gint_1b == 0x00,
"GINT_STATUS_1byte: 0x%02X (expect 0x00 after read-clear)", gint_1b);
/* Test 6: SOCK_STATUS(0) */
{
uint8_t st[2];
ch395f_get_socket_status(0, st);
TEST_CHECK(st[0] == 0x05 && st[1] == 0x01,
"SOCK_STATUS(0): sock=0x%02X(LISTEN), tcp=0x%02X(LISTEN)", st[0], st[1]);
}
/* Test 7: SET_ARP */
ch395f_set_arp(10, 5);
TEST_CHECK(1, "SET_ARP(period=10*100ms, cnt=5): OK");
/* Test 8: SET_TTL */
ch395f_set_ttl(0, 64);
TEST_CHECK(1, "SET_TTL(sock=0, ttl=64): OK");
/* Test 9: CLEAR_RECV_BUF + SOCK_INT poll */
ch395f_clear_recv_buf(0);
TEST_CHECK(1, "CLEAR_RECV_BUF(sock=0): OK");
for (i = 0; i < 8; i++)
{
uint8_t si = ch395f_get_sock_int_status(i);
TEST_CHECK(si == 0x00, "SOCK_INT(%d): 0x%02X", i, si);
}
TEST_REPORT("Phase 1");
}
/*
* ============================ Phase 2 ============================
*/
void ch395f_phase2_tests(void)
{
uint8_t sock;
uint8_t sock_int;
uint8_t rx_buf[300];
int i;
uint32_t tick;
uint16_t int_st;
int iter_pass;
DBG_INFO("=== CH395F Phase 2 Tests (TCP Client - Direct Driver) ===");
/* 解析目标 IP */
uint8_t ip_arr[4];
{
uint32_t a[4];
sscanf(PHASE2_REMOTE_IP, "%lu.%lu.%lu.%lu", &a[0], &a[1], &a[2], &a[3]);
ip_arr[0] = (uint8_t)a[0];
ip_arr[1] = (uint8_t)a[1];
ip_arr[2] = (uint8_t)a[2];
ip_arr[3] = (uint8_t)a[3];
}
DBG_INFO("Target: %s:%d", PHASE2_REMOTE_IP, PHASE2_REMOTE_PORT);
sock = (uint8_t)(NET_MAX_SOCKETS - 1);
/* 一次性配置 */
ch395f_set_proto_type(sock, CH395F_PROTO_TYPE_TCP);
ch395f_set_send_buf(sock, 28, 2);
ch395f_set_recv_buf(sock, 30, 2);
ch395f_set_des_ip(sock, ip_arr);
ch395f_set_des_port(sock, PHASE2_REMOTE_PORT);
for (i = 0; i < PHASE2_LOOP_COUNT; i++)
{
DBG_INFO("--- Iteration %d/%d ---", i + 1, PHASE2_LOOP_COUNT);
iter_pass = 1;
ch395f_set_sour_port(sock, PHASE2_LOCAL_PORT + i);
if (ch395f_open_socket(sock) != CH395F_ERR_SUCCESS) { TEST_CHECK(0, "open socket"); iter_pass = 0; goto phase2_iter_done; }
if (ch395f_tcp_connect(sock) != CH395F_ERR_SUCCESS) { TEST_CHECK(0, "tcp connect"); iter_pass = 0; ch395f_close_socket(sock); goto phase2_iter_done; }
/* 等待 CONNECT */
tick = HAL_GetTick();
while (HAL_GetTick() - tick < PHASE2_TIMEOUT_MS)
{
int_st = ch395f_get_glob_int_status_all();
if (int_st & (1U << (sock + 4)))
{
sock_int = ch395f_get_sock_int_status(sock);
if (sock_int & CH395F_SINT_STAT_CONNECT) break;
}
HAL_Delay(10);
}
if (HAL_GetTick() - tick >= PHASE2_TIMEOUT_MS) { TEST_CHECK(0, "connect timeout"); iter_pass = 0; ch395f_close_socket(sock); goto phase2_iter_done; }
HAL_Delay(100);
/* 发送测试数据 */
{
uint8_t test_buf[64];
const char *msg = "HelloFromCH395F_TCP_Client! This is a 64-byte test message.";
int p, mlen = (int)strlen(msg);
memcpy(test_buf, msg, mlen);
for (p = mlen; p < 64; p++) test_buf[p] = (uint8_t)('0' + (p - mlen) % 10);
ch395f_write_send_buf(sock, test_buf, 64);
}
/* Echo 循环:收数据 → 回发 */
{
int got_echo = 0;
tick = HAL_GetTick();
while (HAL_GetTick() - tick < 10000)
{
uint16_t rlen = ch395f_get_recv_len(sock);
if (rlen > 0)
{
uint16_t read_len = (rlen > sizeof(rx_buf)) ? (uint16_t)sizeof(rx_buf) : rlen;
memset(rx_buf, 0, sizeof(rx_buf));
ch395f_read_recv_buf(sock, rx_buf, read_len);
DBG_INFO("recv: %d bytes [%.30s]", read_len, (char *)rx_buf);
ch395f_write_send_buf(sock, rx_buf, read_len);
got_echo = 1;
break;
}
int_st = ch395f_get_glob_int_status_all();
if (int_st & (1U << (sock + 4)))
{
sock_int = ch395f_get_sock_int_status(sock);
if (sock_int & CH395F_SINT_STAT_DISCONNECT) { DBG_INFO("DISCONNECT"); break; }
if (sock_int & CH395F_SINT_STAT_SOCK_TIMEOUT) { DBG_INFO("SOCK_TIMEOUT"); break; }
}
HAL_Delay(50);
}
if (!got_echo) { TEST_CHECK(0, "echo recv (iter %d)", i + 1); iter_pass = 0; }
}
phase2_iter_done:
if (iter_pass) TEST_CHECK(1, "Iteration %d PASS", i + 1);
/* 关闭 socket */
ch395f_close_socket(sock);
{
uint8_t st[2];
uint32_t wait = HAL_GetTick();
while (HAL_GetTick() - wait < 5000)
{
ch395f_get_socket_status(sock, st);
if (st[0] == CH395F_SOCKET_CLOSED) break;
HAL_Delay(50);
}
DBG_INFO("closed: sock=0x%02X tcp=0x%02X", st[0], st[1]);
}
HAL_Delay(200);
}
restore_data_sockets(8080);
TEST_REPORT("Phase 2");
}
/*
* ============================ Phase 3 ============================
*/
void ch395f_phase3_tests(void)
{
uint8_t sock;
uint8_t rx_buf[300];
uint32_t tick;
int i;
int echo_ok;
DBG_INFO("=== CH395F Phase 3 Tests (UDP) ===");
sock = (uint8_t)(NET_MAX_SOCKETS - 1);
/* UDP Server 模式DesIP=0xFFFFFFFF → 接受任意来源 */
ch395f_set_proto_type(sock, CH395F_PROTO_TYPE_UDP);
ch395f_set_send_buf(sock, 28, 2);
ch395f_set_recv_buf(sock, 30, 2);
ch395f_set_sour_port(sock, PHASE3_LOCAL_PORT);
{
uint8_t zero_ip[4] = {0xFF, 0xFF, 0xFF, 0xFF};
ch395f_set_des_ip(sock, zero_ip);
}
ch395f_set_des_port(sock, 0);
TEST_CHECK(ch395f_open_socket(sock) == CH395F_ERR_SUCCESS,
"UDP socket %d opened (port=%d)", sock, PHASE3_LOCAL_PORT);
HAL_Delay(200);
/* Echo 循环:收到 → 解析来源 → 回显 */
for (i = 0; i < PHASE3_ECHO_COUNT; i++)
{
tick = HAL_GetTick();
echo_ok = 0;
while (HAL_GetTick() - tick < PHASE3_TIMEOUT_MS)
{
uint16_t rlen = ch395f_get_recv_len(sock);
if (rlen > 8)
{
memset(rx_buf, 0, sizeof(rx_buf));
ch395f_read_recv_buf(sock, rx_buf, rlen);
uint16_t payload_len = rlen - 8;
uint16_t src_port = (uint16_t)rx_buf[2] | ((uint16_t)rx_buf[3] << 8);
uint8_t *src_ip = &rx_buf[4];
uint8_t *payload = &rx_buf[8];
DBG_INFO("UDP #%d: %dB from %d.%d.%d.%d:%d [%.32s]",
i + 1, payload_len,
src_ip[0], src_ip[1], src_ip[2], src_ip[3], src_port,
payload_len > 0 ? (char *)payload : "");
ch395f_set_des_ip(sock, src_ip);
ch395f_set_des_port(sock, src_port);
ch395f_write_send_buf(sock, payload, payload_len);
{
uint32_t swait = HAL_GetTick();
while (HAL_GetTick() - swait < 2000)
{
uint16_t gs = ch395f_get_glob_int_status_all();
if (gs & (1U << (sock + 4)))
{
if (ch395f_get_sock_int_status(sock) & CH395F_SINT_STAT_SENBUF_FREE)
break;
}
HAL_Delay(10);
}
}
echo_ok = 1;
break;
}
HAL_Delay(50);
}
TEST_CHECK(echo_ok, "UDP echo #%d/%d", i + 1, PHASE3_ECHO_COUNT);
if (!echo_ok) break;
}
ch395f_close_socket(sock);
TEST_CHECK(1, "UDP socket closed");
restore_data_sockets(8080);
TEST_REPORT("Phase 3");
}
/*
* ============================ Phase 4 ============================
* NET 层 TCP Echo在主循环中调用用 net_recv + net_send 回显
*/
#ifdef ENABLE_PHASE4_TESTS
static char s_phase4_buf[2048];
#endif
void ch395f_phase4_tests(void)
{
#ifdef ENABLE_PHASE4_TESTS
for (int i = NET_TCP_SERVER_DATA_SOCK_START; i < NET_MAX_SOCKETS; i++)
{
net_sock_t *sk = net_get_sock(i);
if (sk == NULL || !sk->in_use || sk->state != NET_SOCK_STATE_ESTABLISHED)
{
continue;
}
int n = net_recv(i, s_phase4_buf, sizeof(s_phase4_buf), NET_MSG_DONTWAIT);
if (n > 0)
{
net_send(i, s_phase4_buf, n, 0);
}
}
#endif
}
/*
* ============================ Phase 5 ============================
* NET 层 UDP EchonetTask 中运行,用 net_recvfrom + net_sendto 回显
*/
#ifndef PHASE5_LOCAL_PORT
#define PHASE5_LOCAL_PORT 60000
#endif
#ifdef ENABLE_PHASE5_TESTS
static int s_phase5_sock = -1;
static char s_phase5_buf[2048];
static uint32_t s_phase5_count = 0;
#endif
void ch395f_phase5_init(void)
{
#ifdef ENABLE_PHASE5_TESTS
struct net_sockaddr_in addr;
s_phase5_sock = net_socket(NET_AF_INET, NET_SOCK_DGRAM, 0);
if (s_phase5_sock < 0)
{
DBG_ERROR("Phase5: net_socket failed");
return;
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = NET_AF_INET;
addr.sin_port = net_htons(PHASE5_LOCAL_PORT);
if (net_bind(s_phase5_sock, (struct net_sockaddr *)&addr, sizeof(addr)) < 0)
{
DBG_ERROR("Phase5: net_bind failed");
net_close(s_phase5_sock);
s_phase5_sock = -1;
return;
}
s_phase5_count = 0;
DBG_INFO("Phase5: UDP socket %d bound to port %d", s_phase5_sock, PHASE5_LOCAL_PORT);
#endif
}
void ch395f_phase5_tests(void)
{
#ifdef ENABLE_PHASE5_TESTS
if (s_phase5_sock < 0) return;
struct net_sockaddr_in src;
int addrlen = sizeof(src);
int n = net_recvfrom(s_phase5_sock, s_phase5_buf, sizeof(s_phase5_buf),
NET_MSG_DONTWAIT,
(struct net_sockaddr *)&src, &addrlen);
if (n > 0)
{
net_sendto(s_phase5_sock, s_phase5_buf, n, 0,
(struct net_sockaddr *)&src, sizeof(src));
s_phase5_count++;
TEST_CHECK(1, "Phase5: UDP echo #%lu (%d bytes)", s_phase5_count, n);
}
#endif
}
/*
* Phase 6 配置默认值
*/
#ifndef PHASE6_ANNOUNCE_PORT
#define PHASE6_ANNOUNCE_PORT 60001
#endif
#ifndef PHASE6_ANNOUNCE_SOCK
#define PHASE6_ANNOUNCE_SOCK 6
#endif
/*
* ============================ Phase 6 ============================
* DHCP 自动获取 IP 测试
*/
void ch395f_phase6_tests(void)
{
#ifdef ENABLE_PHASE6_TESTS
uint8_t status;
uint8_t ip_info[20];
uint32_t tick;
DBG_INFO("=== CH395F Phase 6 Tests (DHCP) ===");
/* 1. 启用 DHCP */
ch395f_set_dhcp(1);
TEST_CHECK(1, "DHCP enabled, waiting for IP...");
/* 2. 轮询等待 DHCP 完成 */
HAL_Delay(500);
tick = HAL_GetTick();
while (HAL_GetTick() - tick < 30000)
{
uint16_t gint = ch395f_get_glob_int_status_all();
if (gint & CH395F_GINT_STAT_DHCP)
{
DBG_INFO("DHCP interrupt");
}
status = ch395f_get_dhcp_status();
if (status == 0x00)
{
TEST_CHECK(1, "DHCP: SUCCESS");
break;
}
HAL_Delay(500);
}
TEST_CHECK(HAL_GetTick() - tick < 30000,
"DHCP completed within 30s (status=0x%02X)", status);
if (HAL_GetTick() - tick >= 30000)
{
goto phase6_end;
}
/* 3. 读取获取的 IP */
ch395f_get_ip_inf(ip_info);
DBG_INFO(" IP: %d.%d.%d.%d", ip_info[0], ip_info[1], ip_info[2], ip_info[3]);
DBG_INFO(" GW: %d.%d.%d.%d", ip_info[4], ip_info[5], ip_info[6], ip_info[7]);
DBG_INFO(" MASK: %d.%d.%d.%d", ip_info[8], ip_info[9], ip_info[10], ip_info[11]);
DBG_INFO(" DNS1: %d.%d.%d.%d", ip_info[12], ip_info[13], ip_info[14], ip_info[15]);
TEST_CHECK(ip_info[0] != 0 || ip_info[1] != 0 || ip_info[2] != 0 || ip_info[3] != 0,
"IP = %d.%d.%d.%d (non-zero)", ip_info[0], ip_info[1], ip_info[2], ip_info[3]);
/* 4. 广播宣告 + 等待 PC HELLO 确认 */
{
#define PHASE6_HELLO_PORT 60000
uint8_t anno_sock = PHASE6_ANNOUNCE_SOCK;
uint8_t bcast_ip[4] = {0xFF, 0xFF, 0xFF, 0xFF};
uint8_t rx_buf[64];
/* UDP Server 模式:本地端口 60000接收 HELLODesIP=0xFFFFFFFF */
ch395f_set_proto_type(anno_sock, CH395F_PROTO_TYPE_UDP);
ch395f_set_send_buf(anno_sock, 24, 2);
ch395f_set_recv_buf(anno_sock, 26, 2);
ch395f_set_sour_port(anno_sock, PHASE6_HELLO_PORT);
ch395f_set_des_ip(anno_sock, bcast_ip);
ch395f_set_des_port(anno_sock, 0);
if (ch395f_open_socket(anno_sock) == CH395F_ERR_SUCCESS)
{
/* 发送广播宣告(宣告端口 = 60001来源端口 = 60000 */
ch395f_set_des_ip(anno_sock, bcast_ip);
ch395f_set_des_port(anno_sock, PHASE6_ANNOUNCE_PORT);
ch395f_write_send_buf(anno_sock, ip_info, 4);
/* 等待 SENDBUF_FREE手册要求每次 write_send_buf 后必须等待) */
{
uint32_t swait = HAL_GetTick();
while (HAL_GetTick() - swait < 2000)
{
uint16_t gs = ch395f_get_glob_int_status_all();
if (gs & (1U << (anno_sock + 4)))
{
if (ch395f_get_sock_int_status(anno_sock) & CH395F_SINT_STAT_SENBUF_FREE)
break;
}
HAL_Delay(10);
}
}
DBG_INFO("DHCP announcement: IP=%d.%d.%d.%d (port %d->%d)",
ip_info[0], ip_info[1], ip_info[2], ip_info[3],
PHASE6_HELLO_PORT, PHASE6_ANNOUNCE_PORT);
TEST_CHECK(1, "DHCP announcement sent");
/* 重置 Server 模式,等待 PC 发送 HELLO */
ch395f_set_des_ip(anno_sock, bcast_ip);
ch395f_set_des_port(anno_sock, 0);
uint32_t wait = HAL_GetTick();
uint8_t hello_ok = 0;
while (HAL_GetTick() - wait < 5000)
{
/* 读取全局中断(刷新 socket 中断状态) */
ch395f_get_glob_int_status_all();
uint16_t rlen = ch395f_get_recv_len(anno_sock);
if (rlen > 8)
{
memset(rx_buf, 0, sizeof(rx_buf));
ch395f_read_recv_buf(anno_sock, rx_buf, rlen);
uint16_t payload_len = rlen - 8;
uint8_t *payload = &rx_buf[8];
if (payload_len == 5 && memcmp(payload, "HELLO", 5) == 0)
{
uint8_t *src_ip = &rx_buf[4];
uint16_t src_port = (uint16_t)rx_buf[2] | ((uint16_t)rx_buf[3] << 8);
ch395f_set_des_ip(anno_sock, src_ip);
ch395f_set_des_port(anno_sock, src_port);
ch395f_write_send_buf(anno_sock, payload, payload_len);
HAL_Delay(100);
DBG_INFO("HELLO response sent to %d.%d.%d.%d:%d",
src_ip[0], src_ip[1], src_ip[2], src_ip[3], src_port);
TEST_CHECK(1, "HELLO echo OK");
hello_ok = 1;
break;
}
}
HAL_Delay(50);
}
TEST_CHECK(hello_ok, "HELLO echo within 5s");
ch395f_close_socket(anno_sock);
}
else
{
TEST_CHECK(0, "DHCP announcement: open socket failed");
}
}
phase6_end:
TEST_REPORT("Phase 6");
#endif
}
/*
* ============================ Phase 7 ============================
* Select/Poll I/O 多路复用测试 — net_select() + net_recv/send echo
*/
#include "net_select.h"
#ifdef ENABLE_PHASE7_TESTS
static char s_phase7_buf[2048];
#endif
void ch395f_phase7_tests(void)
{
#ifdef ENABLE_PHASE7_TESTS
static uint32_t s_phase7_count = 0;
net_fd_set readfds;
net_timeval tv;
NET_FD_ZERO(&readfds);
for (int i = NET_TCP_SERVER_DATA_SOCK_START; i < NET_MAX_SOCKETS; i++)
{
net_sock_t *sk = net_get_sock(i);
if (sk && sk->in_use && sk->state == NET_SOCK_STATE_ESTABLISHED)
{
NET_FD_SET(i, &readfds);
}
}
tv.tv_sec = 0;
tv.tv_usec = 50000;
int n = net_select(NET_MAX_SOCKETS, &readfds, NULL, NULL, &tv);
if (n <= 0) return;
for (int i = 0; i < NET_MAX_SOCKETS; i++)
{
if (!NET_FD_ISSET(i, &readfds)) continue;
int len = net_recv(i, s_phase7_buf, sizeof(s_phase7_buf), NET_MSG_DONTWAIT);
if (len > 0)
{
net_send(i, s_phase7_buf, len, 0);
s_phase7_count++;
TEST_CHECK(1, "Phase7: select echo #%lu (sock=%d, %d bytes)", s_phase7_count, i, len);
}
}
#endif
}