/* =============================================================================
 * lwipopts.h - LwIP 설정 (STM32F407 + LAN8720 RMII + FreeRTOS)
 *
 * 타깃: Cortex-M4F @168MHz, 192KB SRAM(+64KB CCM). RAM 이 빠듯하므로
 *       풀/버퍼 크기를 보수적으로 잡되 HTTPS(mbedTLS over TCP) 1 커넥션 +
 *       DHCP/DNS/SNTP(UDP) 가 동작하도록 충분히 둔다.
 *
 * 동작 모드: NO_SYS=0 (RTOS). LwIP 의 tcpip 스레드가 모든 코어 처리를
 *           직렬화하고, 애플리케이션은 sockets/netconn API 로 접근한다.
 *           ethernetif.c 의 RX 는 별도 FreeRTOS 태스크에서 tcpip_input() 으로
 *           pbuf 를 밀어 넣는다.
 *
 * 빌드: 이 헤더는 third_party/lwip(vendored) 의 헤더보다 먼저 include 경로상
 *       발견되어야 한다(컴파일러 -I config 우선). 폐쇄망 빌드: 외부 fetch 없음.
 * ===========================================================================*/
#ifndef LWIPOPTS_H
#define LWIPOPTS_H

#include <stdint.h>   /* SNTP_SET_SYSTEM_TIME 캐스팅용 */

/* ── OS / 스레딩 ─────────────────────────────────────────────────────────── */
/* NO_SYS=0 : FreeRTOS 위에서 동작 (sys_arch.c 가 sys_* 를 제공해야 함). */
#define NO_SYS                          0
#define SYS_LIGHTWEIGHT_PROT            1
#define LWIP_TCPIP_CORE_LOCKING         1
#define LWIP_TCPIP_CORE_LOCKING_INPUT   0

/* sys_now()/sys_jiffies() 는 sys_arch.c(또는 cc.h) 에서 FreeRTOS 틱 기반 제공.
 * LWIP_TIMEVAL_PRIVATE=0 으로 newlib 의 struct timeval 사용. */
#define LWIP_TIMEVAL_PRIVATE            0

/* ── 메모리 모델 ─────────────────────────────────────────────────────────── */
/* 4바이트 정렬(Cortex-M4 DMA/워드 접근 안정). */
#define MEM_ALIGNMENT                   4U
/* C 라이브러리 malloc 대신 LwIP 내부 힙 사용(결정적, 단편화 회피). */
#define MEM_LIBC_MALLOC                 0
#define MEMP_MEM_MALLOC                 0

/* 핵심 힙: pbuf PBUF_RAM, TCP 송신 큐 등에서 사용. 16KB. */
#define MEM_SIZE                        (16 * 1024)

/* ── 메모리 풀(memp) ─────────────────────────────────────────────────────── */
#define MEMP_NUM_PBUF                   16   /* PBUF_ROM/REF 용 헤더 */
#define MEMP_NUM_UDP_PCB                6    /* DHCP + DNS + SNTP + 여유 */
#define MEMP_NUM_TCP_PCB                5    /* 동시 TCP 연결(HTTPS 1 + 여유) */
#define MEMP_NUM_TCP_PCB_LISTEN         2
#define MEMP_NUM_TCP_SEG                16
#define MEMP_NUM_REASSDATA              4
#define MEMP_NUM_FRAG_PBUF              8
#define MEMP_NUM_ARP_QUEUE              6
#define MEMP_NUM_NETBUF                 4
#define MEMP_NUM_NETCONN                6
#define MEMP_NUM_TCPIP_MSG_API          8
#define MEMP_NUM_TCPIP_MSG_INPKT        12
#define MEMP_NUM_SYS_TIMEOUT            (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 4)

/* ── PBUF 풀(수신 경로) ──────────────────────────────────────────────────── */
/* DMA 수신 디스크립터/재조립용. PBUF_POOL_SIZE * PBUF_POOL_BUFSIZE 만큼 RAM 점유. */
#define PBUF_POOL_SIZE                  12
/* 이더넷 프레임(1500 MTU + 14 헤더) 한 조각에 담기도록. 4바이트 정렬은 LwIP 가 처리. */
#define PBUF_POOL_BUFSIZE               LWIP_MEM_ALIGN_SIZE(1524)
/* TCP/IP/이더넷 헤더 선두 여유(송신 시 헤더 prepend 용). */
#define PBUF_LINK_HLEN                  (14 + ETH_PAD_SIZE)
#define PBUF_LINK_ENCAPSULATION_HLEN    0
/* RMII/HAL_ETH 는 보통 패딩 불필요(2바이트 정렬 트릭 미사용). */
#define ETH_PAD_SIZE                    0

/* ── ARP ─────────────────────────────────────────────────────────────────── */
#define LWIP_ARP                        1
#define ARP_TABLE_SIZE                  10
#define ARP_QUEUEING                    1

/* ── IP / ICMP ───────────────────────────────────────────────────────────── */
#define LWIP_IPV4                       1
#define LWIP_IPV6                       0
#define IP_FORWARD                      0
#define IP_REASSEMBLY                   1
#define IP_FRAG                         1
#define LWIP_ICMP                       1
#define LWIP_RAW                        0
#define LWIP_BROADCAST_PING             0

/* ── DHCP ────────────────────────────────────────────────────────────────── */
#define LWIP_DHCP                       1
/* DHCP 후 gratuitous ARP 로 IP 충돌 점검. */
#define LWIP_DHCP_DOES_ACD_CHECK        0

/* ── AUTOIP (사용 안 함) ─────────────────────────────────────────────────── */
#define LWIP_AUTOIP                     0

/* ── DNS ─────────────────────────────────────────────────────────────────── */
#define LWIP_DNS                        1
#define DNS_TABLE_SIZE                  4
#define DNS_MAX_NAME_LENGTH             256
#define DNS_MAX_SERVERS                 2

/* ── UDP ─────────────────────────────────────────────────────────────────── */
#define LWIP_UDP                        1
#define LWIP_UDPLITE                    0

/* ── TCP ─────────────────────────────────────────────────────────────────── */
#define LWIP_TCP                        1
#define TCP_TTL                         255
/* MSS = MTU(1500) - IP(20) - TCP(20). */
#define TCP_MSS                         1460
/* 송신 버퍼: TLS 레코드(최대 ~16KB)를 한 번에 큐잉할 필요는 없고, mbedTLS 가
 * 작은 청크로 write 하므로 4*MSS 면 충분. RAM 절약. */
#define TCP_SND_BUF                     (4 * TCP_MSS)
#define TCP_SND_QUEUELEN                ((4 * TCP_SND_BUF) / TCP_MSS)
/* 수신 윈도우: HTTPS 응답(JSON 짧음) 위주라 4*MSS. */
#define TCP_WND                         (4 * TCP_MSS)
#define TCP_QUEUE_OOSEQ                 1
#define LWIP_TCP_SACK_OUT               0
#define TCP_LISTEN_BACKLOG              0

/* ── Netconn / Socket API (mbedTLS 가 BSD 소켓 사용) ─────────────────────── */
#define LWIP_NETCONN                    1
#define LWIP_SOCKET                     1
/* mbedTLS net_sockets.c 와의 식별자 충돌 방지: read/write/close 등은 lwip_ 접두. */
#define LWIP_COMPAT_SOCKETS             0
#define LWIP_POSIX_SOCKETS_IO_NAMES     0
#define LWIP_SOCKET_SELECT              1
#define LWIP_SO_RCVTIMEO                1   /* recv 타임아웃(HTTP_TIMEOUT) */
#define LWIP_SO_SNDTIMEO                1
#define LWIP_SO_RCVBUF                  1
#define SO_REUSE                        1
#define LWIP_TCP_KEEPALIVE              1

/* ── 콜백 / 상태 ─────────────────────────────────────────────────────────── */
#define LWIP_NETIF_STATUS_CALLBACK      1   /* IP 할당 감지(net_wait_up) */
#define LWIP_NETIF_LINK_CALLBACK        1   /* 케이블 링크 업/다운 감지 */
#define LWIP_NETIF_HOSTNAME             1
#define LWIP_NETIF_API                  1

/* ── 체크섬 (HAL_ETH 가 하드웨어 체크섬 오프로드 가능; 여기선 SW 로 안전하게) ─ */
/* 일부 STM32 ETH 는 RX 하드웨어 체크섬을 지원하나, 디스크립터 설정과 결합되므로
 * 이식성/안정성 위해 LwIP 의 SW 체크섬을 사용한다. 필요 시 ethernetif.c 의
 * DMA 설정과 함께 CHECKSUM_GEN/CHECK_* 를 0 으로 내려 오프로드할 수 있다.
 * TODO(hw): 하드웨어 오프로드로 CPU 절감 시 아래를 0 으로 내리고 DMA 설정 동기화. */
#define CHECKSUM_GEN_IP                 1
#define CHECKSUM_GEN_UDP                1
#define CHECKSUM_GEN_TCP                1
#define CHECKSUM_GEN_ICMP               1
#define CHECKSUM_CHECK_IP               1
#define CHECKSUM_CHECK_UDP              1
#define CHECKSUM_CHECK_TCP              1
#define CHECKSUM_CHECK_ICMP             1

/* ── 스레드 우선순위/스택 (FreeRTOS) ─────────────────────────────────────── */
/* LwIP 우선순위는 FreeRTOS 절대 우선순위. 애플리케이션 태스크보다 약간 높게 둬서
 * 네트워크 처리가 굶지 않도록 한다. configMAX_PRIORITIES 가 7 이라고 가정.
 * TODO(hw): FreeRTOSConfig.h 의 configMAX_PRIORITIES 와 정합 확인. */
#define TCPIP_THREAD_NAME               "tcpip"
#define TCPIP_THREAD_STACKSIZE          1024            /* 워드 단위(StackType_t) */
#define TCPIP_THREAD_PRIO               (5)
#define TCPIP_MBOX_SIZE                 12

#define DEFAULT_THREAD_NAME             "lwip_def"
#define DEFAULT_THREAD_STACKSIZE        512
#define DEFAULT_THREAD_PRIO             (3)

#define DEFAULT_UDP_RECVMBOX_SIZE       8
#define DEFAULT_TCP_RECVMBOX_SIZE       12
#define DEFAULT_RAW_RECVMBOX_SIZE       8
#define DEFAULT_ACCEPTMBOX_SIZE         8

/* ethernetif RX 태스크가 사용할 우선순위/스택(ethernetif.c 에서 참조). */
#define ETHIF_RX_THREAD_NAME            "eth_rx"
#define ETHIF_RX_THREAD_STACKSIZE       512
#define ETHIF_RX_THREAD_PRIO            (6)             /* tcpip 보다 약간 높게 */

/* ── SNTP 애플리케이션 (apps/sntp) ───────────────────────────────────────── */
/* timesync.c 가 sntp_init() 호출. 시스템 시간 콜백으로 RTC 반영. */
extern void timesync_apply_epoch(uint32_t unix_seconds);

#define SNTP_SERVER_DNS                 1   /* pool.ntp.org 등 호스트명 사용 */
#define SNTP_SUPPORT                    1
#define SNTP_CHECK_RESPONSE             1   /* 응답 무결성(원본 타임스탬프) 검증 */
#define SNTP_COMP_ROUNDTRIP             0
#define SNTP_STARTUP_DELAY              0   /* 부팅 후 즉시 첫 요청 */
#define SNTP_RECV_TIMEOUT               6000
/* 폴 주기: 동기 후엔 자주 갱신 불필요. 1시간(서버 보고 주기와 동일 수준). */
#define SNTP_UPDATE_DELAY               (60u * 60u * 1000u)
/* 시스템 시간 설정 훅: LwIP 가 획득한 초 단위 Unix 시간을 RTC 로 반영. */
#define SNTP_SET_SYSTEM_TIME(sec)       do { timesync_apply_epoch((uint32_t)(sec)); } while (0)
/* 마이크로초 정밀도는 불필요(_US 버전 미정의). */

/* ── 통계 / 디버그 ───────────────────────────────────────────────────────── */
#define LWIP_STATS                      0
#define LWIP_STATS_DISPLAY              0

/* 운영 빌드에서는 디버그 끔. 필요 시 개별 *_DEBUG 를 LWIP_DBG_ON 으로. */
#define LWIP_DEBUG                      0
#define LWIP_NOASSERT                   0   /* assert 유지(개발 단계 안전) */

/* ── 기타 ────────────────────────────────────────────────────────────────── */
#define LWIP_PROVIDE_ERRNO              1   /* newlib errno 와 분리(독립 errno 제공) */
#define LWIP_NETIF_TX_SINGLE_PBUF       1   /* 송신 시 단일 pbuf 선호(HAL_ETH 단순화) */
#define LWIP_RAND()                     ((u32_t)bsp_rand32())

/* LWIP_RAND 용: 하드웨어 RNG 기반 32비트 난수(bsp/별도 모듈 제공).
 * TODO(hw): bsp.c 또는 rng.c 에서 bsp_rand32() 를 RNG 페리페럴로 구현.
 *           (현재 net.c 에 약한 대체 구현이 있을 수 있음) */
uint32_t bsp_rand32(void);

#endif /* LWIPOPTS_H */
