A TempleOS distro for heretics
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

148 lines
2.9 KiB

// vim: set ft=cpp:
#include "::/Doc/Comm"
#define CMD_SOCKET 1
#define CMD_CLOSE 2
#define CMD_CONNECT_TCP 3
#define CMD_SEND 4
#define CMD_RECV 5
#define CMD_HELLO 0xAA
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_RAW 3
#define AF_UNSPEC 0
#define AF_INET 2
#define AF_INET6 10
#define SNAIL_COM 3
#define SNAIL_TIMEOUT 500
#define SNAIL_FRAME_SIZE 112
static CComm* snail_comm;
static U8 ReadByte() {
U8 chr;
while (1) {
if (FifoU8Rem(snail_comm->RX_fifo, &chr))
return chr;
else
Yield;
}
}
static I8 ReadI8() {
I8 chr;
while (1) {
if (FifoU8Rem(snail_comm->RX_fifo, &chr))
return chr;
else
Yield;
}
}
static U0 ReadBlock(U8* buf, I64 count) {
while (count) {
if (FifoU8Rem(snail_comm->RX_fifo, buf)) {
buf++;
count--;
}
else Yield;
}
}
I64 SocketInit() {
U8 chr;
snail_comm = CommInit8n1(SNAIL_COM, 9600);
while (FifoU8Rem(snail_comm->RX_fifo, &chr)) {}
CommPutChar(SNAIL_COM, CMD_HELLO);
I64 max_time = cnts.jiffies + SNAIL_TIMEOUT * JIFFY_FREQ / 1000;
do {
if (FifoU8Rem(snail_comm->RX_fifo, &chr)) {
if (chr == CMD_HELLO) {
return 0;
}
else {
"$FG,6$Failed to initialize Snail -- wrong hello 0x%02X\n", chr;
"Are you using the right version of snail.py?\n$FG$";
throw;
}
return chr;
}
else
Yield;
}
while (cnts.jiffies < max_time);
"$FG,6$Failed to initialize Snail -- make sure COM%d "
"is properly configured & snail.py is running!\n$FG$", SNAIL_COM;
throw;
}
I64 socket(I64 domain, I64 type) {
CommPutChar(SNAIL_COM, CMD_SOCKET);
CommPutChar(SNAIL_COM, domain);
CommPutChar(SNAIL_COM, type);
return ReadI8();
}
I64 close(I64 sockfd) {
CommPutChar(SNAIL_COM, CMD_CLOSE);
CommPutChar(SNAIL_COM, sockfd);
return ReadI8();
}
I64 create_connection(U8* addr, U16 port) {
I64 sockfd = socket(AF_INET, SOCK_STREAM);
if (sockfd < 0)
return sockfd;
CommPutChar(SNAIL_COM, CMD_CONNECT_TCP);
CommPutChar(SNAIL_COM, sockfd);
CommPutChar(SNAIL_COM, StrLen(addr));
CommPutS(SNAIL_COM, addr);
CommPutChar(SNAIL_COM, port & 0xff);
CommPutChar(SNAIL_COM, port >> 8);
I64 error = ReadI8();
if (error < 0) {
close(sockfd);
return error;
}
return sockfd;
}
I64 recv(I64 sockfd, U8* buf, I64 len, I64 flags) {
// This will be problematic for UDP
if (len > SNAIL_FRAME_SIZE)
len = SNAIL_FRAME_SIZE;
CommPutChar(SNAIL_COM, CMD_RECV);
CommPutChar(SNAIL_COM, sockfd);
CommPutChar(SNAIL_COM, len);
CommPutChar(SNAIL_COM, flags);
I64 got = ReadI8();
if (got > 0)
ReadBlock(buf, got);
return got;
}
I64 send(I64 sockfd, U8* buf, I64 len, I64 flags) {
// FIXME: use frames
CommPutChar(SNAIL_COM, CMD_SEND);
CommPutChar(SNAIL_COM, sockfd);
CommPutChar(SNAIL_COM, len);
CommPutChar(SNAIL_COM, flags);
CommPutBlk(SNAIL_COM, buf, len);
return ReadI8();
}