#ifndef SOCK_H #define SOCK_H /* gbos socket API - the kernel owns SLIP/IP/ICMP/UDP/TCP; programs just do socket()/connect()/send()/recv()/close(). Header-only: one copy per program. The netreq layout must match include/gbos.inc (NR_* / NET_* / SOCK_*). */ #include "gbos.h" #define SOCK_ICMP 1 #define SOCK_UDP 2 #define SOCK_TCP 3 struct netreq { unsigned char op; unsigned char sock; unsigned char *buf; unsigned char len; unsigned char ip[4]; unsigned char port_hi, port_lo; }; static struct netreq _nr; /* -> socket id, or 0xFF if the table is full */ static unsigned char net_socket(unsigned char type) { _nr.op = 0; _nr.sock = type; return sys_net(&_nr); } /* set the remote address/port for send()/recv() */ static unsigned char net_connect(unsigned char s, const unsigned char *ip, unsigned int port) { unsigned char i; _nr.op = 1; _nr.sock = s; for (i = 0; i < 4; i++) _nr.ip[i] = ip[i]; _nr.port_hi = (unsigned char)(port >> 8); _nr.port_lo = (unsigned char)port; return sys_net(&_nr); } /* send 'len' payload bytes to the connected peer -> 0 ok / 0xFF error */ static unsigned char net_send(unsigned char s, void *buf, unsigned char len) { _nr.op = 2; _nr.sock = s; _nr.buf = (unsigned char *)buf; _nr.len = len; return sys_net(&_nr); } /* receive up to 'max' payload bytes -> length, or 0xFF on timeout */ static unsigned char net_recv(unsigned char s, void *buf, unsigned char max) { _nr.op = 3; _nr.sock = s; _nr.buf = (unsigned char *)buf; _nr.len = max; return sys_net(&_nr); } static void net_close(unsigned char s) { _nr.op = 4; _nr.sock = s; sys_net(&_nr); } /* pump the RX path once (answers inbound pings) without blocking */ static void net_poll(void) { _nr.op = 6; sys_net(&_nr); } #endif