*/
/*
- * Kernel-level ICMP ping test using lwIP raw API.
- * Sends ICMP echo requests to 10.0.2.2 (QEMU user-mode gateway)
- * and logs results to the serial console.
+ * Kernel-level ICMP ping test — REMOVED.
*
- * All raw API calls are executed inside the tcpip thread via
- * tcpip_callback(), as required by lwIP's threading model.
+ * net_ping_test() was a boot-time kernel ping test that sent ICMP echo
+ * requests to 10.0.2.2 (QEMU gateway). It has been superseded by the
+ * userspace ICMP ping test in fulltest (I7b) which uses SOCK_RAW +
+ * IPPROTO_ICMP via the standard socket API.
+ *
+ * This file is kept as a placeholder to avoid breaking the build
+ * system's wildcard source enumeration in the Makefile.
*/
-#include "lwip/opt.h"
-#include "lwip/raw.h"
-#include "lwip/ip_addr.h"
-#include "lwip/pbuf.h"
-#include "lwip/inet_chksum.h"
-#include "lwip/tcpip.h"
-#include "lwip/prot/icmp.h"
-#include "lwip/def.h"
-
-#include "sync.h"
-#include "console.h"
-#include "process.h"
-#include "net.h"
-#include "e1000.h"
-#include "timer.h"
-
-#include <stdint.h>
-#include <stddef.h>
-
-#define PING_ID 0xAD05
-#define PING_COUNT 3
-#define PING_TIMEOUT_MS 3000
-
-extern uint32_t get_tick_count(void);
-
-/* ---- Shared state between ping thread and tcpip callbacks ---- */
-
-static struct raw_pcb *g_ping_pcb;
-static ksem_t ping_reply_sem;
-static ksem_t ping_setup_sem;
-static volatile int ping_got_reply;
-static volatile uint16_t ping_reply_seqno;
-
-/* ---- Raw receive callback (runs in tcpip thread) ---- */
-
-static u8_t ping_recv_cb(void *arg, struct raw_pcb *pcb,
- struct pbuf *p, const ip_addr_t *addr) {
- (void)arg; (void)pcb; (void)addr;
-
- /* Minimum: IP header (≥20) + ICMP echo header (8) */
- if (p->tot_len < 28)
- return 0;
-
- /* Read IP header first byte to determine IHL */
- uint8_t ihl_byte;
- if (pbuf_copy_partial(p, &ihl_byte, 1, 0) != 1)
- return 0;
- u16_t ip_hdr_len = (u16_t)((ihl_byte & 0x0F) * 4);
-
- struct icmp_echo_hdr echo;
- if (pbuf_copy_partial(p, &echo, sizeof(echo), ip_hdr_len) != sizeof(echo))
- return 0;
-
- if (echo.type == ICMP_ER && echo.id == PP_HTONS(PING_ID)) {
- ping_reply_seqno = lwip_ntohs(echo.seqno);
- ping_got_reply = 1;
- ksem_signal(&ping_reply_sem);
- pbuf_free(p);
- return 1; /* consumed */
- }
-
- return 0; /* not ours */
-}
-
-/* ---- tcpip_callback helpers ---- */
-
-static void ping_setup_tcpip(void *arg) {
- (void)arg;
- g_ping_pcb = raw_new(IP_PROTO_ICMP);
- if (g_ping_pcb) {
- raw_recv(g_ping_pcb, ping_recv_cb, NULL);
- raw_bind(g_ping_pcb, IP_ADDR_ANY);
- }
- ksem_signal(&ping_setup_sem);
-}
-
-static void ping_cleanup_tcpip(void *arg) {
- (void)arg;
- if (g_ping_pcb) {
- raw_remove(g_ping_pcb);
- g_ping_pcb = NULL;
- }
- ksem_signal(&ping_setup_sem);
-}
-
-struct ping_send_ctx {
- ip_addr_t target;
- uint16_t seq;
-};
-
-static struct ping_send_ctx g_send_ctx;
-
-static void ping_send_tcpip(void *arg) {
- struct ping_send_ctx *ctx = (struct ping_send_ctx *)arg;
-
- struct pbuf *p = pbuf_alloc(PBUF_IP, (u16_t)sizeof(struct icmp_echo_hdr),
- PBUF_RAM);
- if (!p) return;
-
- struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)p->payload;
- iecho->type = ICMP_ECHO;
- iecho->code = 0;
- iecho->chksum = 0;
- iecho->id = PP_HTONS(PING_ID);
- iecho->seqno = lwip_htons(ctx->seq);
- iecho->chksum = inet_chksum(iecho, (u16_t)sizeof(*iecho));
-
- raw_sendto(g_ping_pcb, p, &ctx->target);
- pbuf_free(p);
-}
-
-/* ---- Public API ---- */
-
-void net_ping_test(void) {
- if (!net_get_netif()) return;
-
- ksem_init(&ping_reply_sem, 0);
- ksem_init(&ping_setup_sem, 0);
-
- /* Create raw PCB in tcpip thread, wait for completion */
- g_ping_pcb = NULL;
- tcpip_callback(ping_setup_tcpip, NULL);
- ksem_wait(&ping_setup_sem);
-
- if (!g_ping_pcb) {
- kprintf("[PING] failed to create raw PCB\n");
- return;
- }
-
- /* Wait for the E1000 link to stabilize in QEMU */
- process_sleep(TIMER_HZ / 2); /* ~500ms — plenty for QEMU virtual NIC */
-
- ip_addr_t target;
- ip_addr_set_zero_ip4(&target);
- IP4_ADDR(ip_2_ip4(&target), 10, 0, 2, 2);
-
- int ok = 0;
- for (int i = 0; i < PING_COUNT; i++) {
- ping_got_reply = 0;
-
- g_send_ctx.target = target;
- g_send_ctx.seq = (uint16_t)(i + 1);
-
- uint32_t t0 = get_tick_count();
- tcpip_callback(ping_send_tcpip, &g_send_ctx);
-
- /* Active poll: call e1000_recv + feed lwIP from this thread
- * while waiting for the reply. This avoids depending on
- * the rx_thread being scheduled in time. */
- uint32_t deadline = t0 + (PING_TIMEOUT_MS + 19) / 20;
- while (!ping_got_reply && get_tick_count() < deadline) {
- static uint8_t ping_rx_buf[2048];
- int len = e1000_recv(ping_rx_buf, sizeof(ping_rx_buf));
- if (len > 0) {
- struct pbuf* p = pbuf_alloc(PBUF_RAW, (u16_t)len, PBUF_POOL);
- if (p) {
- pbuf_take(p, ping_rx_buf, (u16_t)len);
- if (net_get_netif()->input(p, net_get_netif()) != ERR_OK)
- pbuf_free(p);
- }
- }
- process_sleep(1); /* yield for 1 tick */
- }
-
- uint32_t dt = (get_tick_count() - t0) * TIMER_MS_PER_TICK;
-
- if (ping_got_reply) {
- kprintf("[PING] reply from 10.0.2.2: seq=%d time=%dms\n",
- i + 1, dt);
- ok++;
- } else {
- kprintf("[PING] timeout seq=%d\n", i + 1);
- }
-
- if (i + 1 < PING_COUNT)
- process_sleep(TIMER_HZ / 4); /* ~250ms between pings */
- }
-
- /* Cleanup in tcpip thread */
- tcpip_callback(ping_cleanup_tcpip, NULL);
- ksem_wait(&ping_setup_sem);
-
- if (ok > 0) {
- kprintf("[PING] %d/%d received — network OK\n", ok, PING_COUNT);
- } else {
- kprintf("[PING] all packets lost — network FAIL\n");
- }
-}