aboutsummaryrefslogtreecommitdiffstats
path: root/c/sock.h
blob: 876e85cd2d90b55fff5860a27b6dabeabbf48514 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#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);
}
/* non-blocking recv: one RX pump -> length, 0xFE if nothing buffered yet,
   0 on TCP EOF. Loop it with msleep() to own your timeout (see ping). */
static unsigned char net_recv_nb(unsigned char s, void *buf, unsigned char max) {
    _nr.op = 8; _nr.sock = s; _nr.buf = (unsigned char *)buf; _nr.len = max;
    return sys_net(&_nr);
}
/* set the local (source) port - needed so UDP replies demux back to us */
static unsigned char net_bind(unsigned char s, unsigned int port) {
    _nr.op = 5; _nr.sock = s;
    _nr.port_hi = (unsigned char)(port >> 8); _nr.port_lo = (unsigned char)port;
    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);
}
/* set our IPv4 address (the DHCP client calls this once it has a lease) */
static void net_setip(const unsigned char *ip) {
    unsigned char i;
    _nr.op = 7;
    for (i = 0; i < 4; i++) _nr.ip[i] = ip[i];
    sys_net(&_nr);
}
#endif