Use std::expected for socket return types, enum class sock_error

This commit is contained in:
Ian Gulliver
2026-04-05 08:38:16 +09:00
parent 0b81ca6139
commit 7f7055cec5
2 changed files with 116 additions and 114 deletions
+84 -83
View File
@@ -1285,17 +1285,18 @@ static uint16_t sock_is_sending = 0;
static uint16_t sock_remained_size[_SOCK_COUNT_] = {0,}; static uint16_t sock_remained_size[_SOCK_COUNT_] = {0,};
uint8_t sock_pack_info[_SOCK_COUNT_] = {0,}; uint8_t sock_pack_info[_SOCK_COUNT_] = {0,};
#define CHECK_SOCKNUM() do { if(sn >= _SOCK_COUNT_) return SOCKERR_SOCKNUM; } while(0) #define FAIL(e) return std::unexpected(sock_error::e)
#define CHECK_SOCKMODE(mode) do { if((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; } while(0) #define CHECK_SOCKNUM() do { if(sn >= _SOCK_COUNT_) FAIL(sock_num); } while(0)
#define CHECK_TCPMODE() do { if((getSn_MR(sn) & 0x03) != 0x01) return SOCKERR_SOCKMODE; } while(0) #define CHECK_SOCKMODE(mode) do { if((getSn_MR(sn) & 0x0F) != mode) FAIL(sock_mode); } while(0)
#define CHECK_UDPMODE() do { if((getSn_MR(sn) & 0x03) != 0x02) return SOCKERR_SOCKMODE; } while(0) #define CHECK_TCPMODE() do { if((getSn_MR(sn) & 0x03) != 0x01) FAIL(sock_mode); } while(0)
#define CHECK_IPMODE() do { if((getSn_MR(sn) & 0x07) != 0x03) return SOCKERR_SOCKMODE; } while(0) #define CHECK_UDPMODE() do { if((getSn_MR(sn) & 0x03) != 0x02) FAIL(sock_mode); } while(0)
#define CHECK_DGRAMMODE() do { if(getSn_MR(sn) == Sn_MR_CLOSED) return SOCKERR_SOCKMODE; if((getSn_MR(sn) & 0x03) == 0x01) return SOCKERR_SOCKMODE; } while(0) #define CHECK_IPMODE() do { if((getSn_MR(sn) & 0x07) != 0x03) FAIL(sock_mode); } while(0)
#define CHECK_SOCKINIT() do { if((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; } while(0) #define CHECK_DGRAMMODE() do { if(getSn_MR(sn) == Sn_MR_CLOSED) FAIL(sock_mode); if((getSn_MR(sn) & 0x03) == 0x01) FAIL(sock_mode); } while(0)
#define CHECK_SOCKDATA() do { if(len == 0) return SOCKERR_DATALEN; } while(0) #define CHECK_SOCKINIT() do { if((getSn_SR(sn) != SOCK_INIT)) FAIL(sock_init); } while(0)
#define CHECK_IPZERO(addr, addrlen) do { uint16_t ipzero=0; for(uint8_t i=0; i<addrlen; i++) ipzero += (uint16_t)addr[i]; if(ipzero == 0) return SOCKERR_IPINVALID; } while(0) #define CHECK_SOCKDATA() do { if(len == 0) FAIL(data_len); } while(0)
#define CHECK_IPZERO(addr, addrlen) do { uint16_t ipzero=0; for(uint8_t i=0; i<addrlen; i++) ipzero += (uint16_t)addr[i]; if(ipzero == 0) FAIL(ip_invalid); } while(0)
int8_t open_socket(socket_id sid, protocol proto, port_num port, sock_flag flag) { std::expected<socket_id, sock_error> open_socket(socket_id sid, protocol proto, port_num port, sock_flag flag) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
uint16_t p = static_cast<uint16_t>(port); uint16_t p = static_cast<uint16_t>(port);
uint8_t pr = static_cast<uint8_t>(proto); uint8_t pr = static_cast<uint8_t>(proto);
@@ -1325,23 +1326,23 @@ int8_t open_socket(socket_id sid, protocol proto, port_num port, sock_flag flag)
case Sn_MR_IPRAW6: case Sn_MR_IPRAW6:
break; break;
default: default:
return SOCKERR_SOCKMODE; FAIL(sock_mode);
} }
if ((fl & 0x04) != 0) return SOCKERR_SOCKFLAG; if ((fl & 0x04) != 0) FAIL(sock_flag);
if (fl != 0) { if (fl != 0) {
switch (pr) { switch (pr) {
case Sn_MR_MACRAW: case Sn_MR_MACRAW:
if ((fl & (Sn_MR2_DHAM | Sn_MR2_FARP)) != 0) return SOCKERR_SOCKFLAG; if ((fl & (Sn_MR2_DHAM | Sn_MR2_FARP)) != 0) FAIL(sock_flag);
break; break;
case Sn_MR_TCP4: case Sn_MR_TCP4:
case Sn_MR_TCP6: case Sn_MR_TCP6:
case Sn_MR_TCPD: case Sn_MR_TCPD:
if ((fl & (Sn_MR_MULTI | Sn_MR_UNIB)) != 0) return SOCKERR_SOCKFLAG; if ((fl & (Sn_MR_MULTI | Sn_MR_UNIB)) != 0) FAIL(sock_flag);
break; break;
case Sn_MR_IPRAW4: case Sn_MR_IPRAW4:
case Sn_MR_IPRAW6: case Sn_MR_IPRAW6:
if (fl != 0) return SOCKERR_SOCKFLAG; if (fl != 0) FAIL(sock_flag);
break; break;
default: default:
break; break;
@@ -1363,10 +1364,10 @@ int8_t open_socket(socket_id sid, protocol proto, port_num port, sock_flag flag)
sock_remained_size[sn] = 0; sock_remained_size[sn] = 0;
sock_pack_info[sn] = static_cast<uint8_t>(pack_info::completed); sock_pack_info[sn] = static_cast<uint8_t>(pack_info::completed);
while (getSn_SR(sn) == SOCK_CLOSED); while (getSn_SR(sn) == SOCK_CLOSED);
return (int8_t)sn; return sid;
} }
int8_t close(socket_id sid) { std::expected<void, sock_error> close(socket_id sid) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
CHECK_SOCKNUM(); CHECK_SOCKNUM();
setSn_CR(sn, Sn_CR_CLOSE); setSn_CR(sn, Sn_CR_CLOSE);
@@ -1377,10 +1378,10 @@ int8_t close(socket_id sid) {
sock_remained_size[sn] = 0; sock_remained_size[sn] = 0;
sock_pack_info[sn] = PACK_NONE; sock_pack_info[sn] = PACK_NONE;
while (getSn_SR(sn) != SOCK_CLOSED); while (getSn_SR(sn) != SOCK_CLOSED);
return SOCK_OK; return {};
} }
int8_t listen(socket_id sid) { std::expected<void, sock_error> listen(socket_id sid) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
CHECK_SOCKNUM(); CHECK_SOCKNUM();
CHECK_TCPMODE(); CHECK_TCPMODE();
@@ -1389,19 +1390,19 @@ int8_t listen(socket_id sid) {
while (getSn_CR(sn)); while (getSn_CR(sn));
while (getSn_SR(sn) != SOCK_LISTEN) { while (getSn_SR(sn) != SOCK_LISTEN) {
close(sid); close(sid);
return SOCKERR_SOCKCLOSED; FAIL(sock_closed);
} }
return SOCK_OK; return {};
} }
int8_t connect(socket_id sid, uint8_t * addr, port_num port, uint8_t addrlen) { std::expected<void, sock_error> connect(socket_id sid, uint8_t * addr, port_num port, uint8_t addrlen) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
uint16_t p = static_cast<uint16_t>(port); uint16_t p = static_cast<uint16_t>(port);
CHECK_SOCKNUM(); CHECK_SOCKNUM();
CHECK_TCPMODE(); CHECK_TCPMODE();
CHECK_SOCKINIT(); CHECK_SOCKINIT();
CHECK_IPZERO(addr, addrlen); CHECK_IPZERO(addr, addrlen);
if (p == 0) return SOCKERR_PORTZERO; if (p == 0) FAIL(port_zero);
setSn_DPORTR(sn, p); setSn_DPORTR(sn, p);
if (addrlen == 16) { if (addrlen == 16) {
@@ -1409,26 +1410,26 @@ int8_t connect(socket_id sid, uint8_t * addr, port_num port, uint8_t addrlen) {
setSn_DIP6R(sn, addr); setSn_DIP6R(sn, addr);
setSn_CR(sn, Sn_CR_CONNECT6); setSn_CR(sn, Sn_CR_CONNECT6);
} else { } else {
return SOCKERR_SOCKMODE; FAIL(sock_mode);
} }
} else { } else {
if (getSn_MR(sn) == Sn_MR_TCP6) return SOCKERR_SOCKMODE; if (getSn_MR(sn) == Sn_MR_TCP6) FAIL(sock_mode);
setSn_DIPR(sn, addr); setSn_DIPR(sn, addr);
setSn_CR(sn, Sn_CR_CONNECT); setSn_CR(sn, Sn_CR_CONNECT);
} }
while (getSn_CR(sn)); while (getSn_CR(sn));
if (sock_io_mode & (1 << sn)) return SOCK_BUSY; if (sock_io_mode & (1 << sn)) FAIL(busy);
while (getSn_SR(sn) != SOCK_ESTABLISHED) { while (getSn_SR(sn) != SOCK_ESTABLISHED) {
if (getSn_IR(sn) & Sn_IR_TIMEOUT) { if (getSn_IR(sn) & Sn_IR_TIMEOUT) {
setSn_IR(sn, Sn_IR_TIMEOUT); setSn_IR(sn, Sn_IR_TIMEOUT);
return SOCKERR_TIMEOUT; FAIL(timeout);
} }
if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; if (getSn_SR(sn) == SOCK_CLOSED) FAIL(sock_closed);
} }
return SOCK_OK; return {};
} }
int8_t disconnect(socket_id sid) { std::expected<void, sock_error> disconnect(socket_id sid) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
CHECK_SOCKNUM(); CHECK_SOCKNUM();
CHECK_TCPMODE(); CHECK_TCPMODE();
@@ -1436,18 +1437,18 @@ int8_t disconnect(socket_id sid) {
setSn_CR(sn, Sn_CR_DISCON); setSn_CR(sn, Sn_CR_DISCON);
while (getSn_CR(sn)); while (getSn_CR(sn));
sock_is_sending &= ~(1 << sn); sock_is_sending &= ~(1 << sn);
if (sock_io_mode & (1 << sn)) return SOCK_BUSY; if (sock_io_mode & (1 << sn)) FAIL(busy);
while (getSn_SR(sn) != SOCK_CLOSED) { while (getSn_SR(sn) != SOCK_CLOSED) {
if (getSn_IR(sn) & Sn_IR_TIMEOUT) { if (getSn_IR(sn) & Sn_IR_TIMEOUT) {
close(sid); close(sid);
return SOCKERR_TIMEOUT; FAIL(timeout);
} }
} }
} }
return SOCK_OK; return {};
} }
int32_t send(socket_id sid, uint8_t * buf, uint16_t len) { std::expected<uint16_t, sock_error> send(socket_id sid, uint8_t * buf, uint16_t len) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
uint8_t tmp = 0; uint8_t tmp = 0;
uint16_t freesize = 0; uint16_t freesize = 0;
@@ -1459,9 +1460,9 @@ int32_t send(socket_id sid, uint8_t * buf, uint16_t len) {
tmp = getSn_SR(sn); tmp = getSn_SR(sn);
if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) { if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) {
if (tmp == SOCK_CLOSED) close(sid); if (tmp == SOCK_CLOSED) close(sid);
return SOCKERR_SOCKSTATUS; FAIL(sock_status);
} }
if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; if ((sock_io_mode & (1 << sn)) && (len > freesize)) FAIL(busy);
if (len <= freesize) break; if (len <= freesize) break;
} }
wiz_send_data(sn, buf, len); wiz_send_data(sn, buf, len);
@@ -1470,9 +1471,9 @@ int32_t send(socket_id sid, uint8_t * buf, uint16_t len) {
tmp = getSn_SR(sn); tmp = getSn_SR(sn);
if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) { if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) {
if ((tmp == SOCK_CLOSED) || (getSn_IR(sn) & Sn_IR_TIMEOUT)) close(sid); if ((tmp == SOCK_CLOSED) || (getSn_IR(sn) & Sn_IR_TIMEOUT)) close(sid);
return SOCKERR_SOCKSTATUS; FAIL(sock_status);
} }
if (sock_io_mode & (1 << sn)) return SOCK_BUSY; if (sock_io_mode & (1 << sn)) FAIL(busy);
} }
setSn_IR(sn, Sn_IR_SENDOK); setSn_IR(sn, Sn_IR_SENDOK);
} }
@@ -1482,7 +1483,7 @@ int32_t send(socket_id sid, uint8_t * buf, uint16_t len) {
return len; return len;
} }
int32_t recv(socket_id sid, uint8_t * buf, uint16_t len) { std::expected<uint16_t, sock_error> recv(socket_id sid, uint8_t * buf, uint16_t len) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
uint8_t tmp = 0; uint8_t tmp = 0;
uint16_t recvsize = 0; uint16_t recvsize = 0;
@@ -1502,25 +1503,25 @@ int32_t recv(socket_id sid, uint8_t * buf, uint16_t len) {
if (recvsize != 0) break; if (recvsize != 0) break;
else if (getSn_TX_FSR(sn) == getSn_TxMAX(sn)) { else if (getSn_TX_FSR(sn) == getSn_TxMAX(sn)) {
close(sid); close(sid);
return SOCKERR_SOCKSTATUS; FAIL(sock_status);
} }
} else { } else {
close(sid); close(sid);
return SOCKERR_SOCKSTATUS; FAIL(sock_status);
} }
} }
if (recvsize != 0) break; if (recvsize != 0) break;
if (sock_io_mode & (1 << sn)) return SOCK_BUSY; if (sock_io_mode & (1 << sn)) FAIL(busy);
}; };
if (recvsize < len) len = recvsize; if (recvsize < len) len = recvsize;
wiz_recv_data(sn, buf, len); wiz_recv_data(sn, buf, len);
setSn_CR(sn, Sn_CR_RECV); setSn_CR(sn, Sn_CR_RECV);
while (getSn_CR(sn)); while (getSn_CR(sn));
return (int32_t)len; return len;
} }
int32_t sendto(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, port_num port, uint8_t addrlen) { std::expected<uint16_t, sock_error> sendto(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, port_num port, uint8_t addrlen) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
uint16_t p = static_cast<uint16_t>(port); uint16_t p = static_cast<uint16_t>(port);
uint8_t tmp = 0; uint8_t tmp = 0;
@@ -1535,7 +1536,7 @@ int32_t sendto(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, port_
case Sn_MR_IPRAW6: case Sn_MR_IPRAW6:
break; break;
default: default:
return SOCKERR_SOCKMODE; FAIL(sock_mode);
} }
tmp = getSn_MR(sn); tmp = getSn_MR(sn);
if (tmp != Sn_MR_MACRAW) { if (tmp != Sn_MR_MACRAW) {
@@ -1544,21 +1545,21 @@ int32_t sendto(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, port_
setSn_DIP6R(sn, addr); setSn_DIP6R(sn, addr);
tcmd = Sn_CR_SEND6; tcmd = Sn_CR_SEND6;
} else { } else {
return SOCKERR_SOCKMODE; FAIL(sock_mode);
} }
} else if (addrlen == 4) { } else if (addrlen == 4) {
if (tmp == Sn_MR_UDP6 || tmp == Sn_MR_IPRAW6) return SOCKERR_SOCKMODE; if (tmp == Sn_MR_UDP6 || tmp == Sn_MR_IPRAW6) FAIL(sock_mode);
setSn_DIPR(sn, addr); setSn_DIPR(sn, addr);
tcmd = Sn_CR_SEND; tcmd = Sn_CR_SEND;
} else { } else {
return SOCKERR_IPINVALID; FAIL(ip_invalid);
} }
} }
if ((tmp & 0x03) == 0x02) { if ((tmp & 0x03) == 0x02) {
if (p) { if (p) {
setSn_DPORTR(sn, p); setSn_DPORTR(sn, p);
} else { } else {
return SOCKERR_PORTZERO; FAIL(port_zero);
} }
} }
@@ -1566,8 +1567,8 @@ int32_t sendto(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, port_
if (len > freesize) len = freesize; if (len > freesize) len = freesize;
while (1) { while (1) {
freesize = getSn_TX_FSR(sn); freesize = getSn_TX_FSR(sn);
if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; if (getSn_SR(sn) == SOCK_CLOSED) FAIL(sock_closed);
if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; if ((sock_io_mode & (1 << sn)) && (len > freesize)) FAIL(busy);
if (len <= freesize) break; if (len <= freesize) break;
}; };
wiz_send_data(sn, buf, len); wiz_send_data(sn, buf, len);
@@ -1580,13 +1581,13 @@ int32_t sendto(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, port_
break; break;
} else if (tmp & Sn_IR_TIMEOUT) { } else if (tmp & Sn_IR_TIMEOUT) {
setSn_IR(sn, Sn_IR_TIMEOUT); setSn_IR(sn, Sn_IR_TIMEOUT);
return SOCKERR_TIMEOUT; FAIL(timeout);
} }
} }
return (int32_t)len; return len;
} }
int32_t recvfrom(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, port_num *port, uint8_t *addrlen) { std::expected<uint16_t, sock_error> recvfrom(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, port_num *port, uint8_t *addrlen) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
uint8_t mr; uint8_t mr;
uint8_t head[8]; uint8_t head[8];
@@ -1602,18 +1603,18 @@ int32_t recvfrom(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, por
case Sn_MR_MACRAW: case Sn_MR_MACRAW:
break; break;
default: default:
return SOCKERR_SOCKMODE; FAIL(sock_mode);
} }
if (sock_remained_size[sn] == 0) { if (sock_remained_size[sn] == 0) {
while (1) { while (1) {
pack_len = getSn_RX_RSR(sn); pack_len = getSn_RX_RSR(sn);
if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; if (getSn_SR(sn) == SOCK_CLOSED) FAIL(sock_closed);
if (pack_len != 0) { if (pack_len != 0) {
sock_pack_info[sn] = PACK_NONE; sock_pack_info[sn] = PACK_NONE;
break; break;
} }
if (sock_io_mode & (1 << sn)) return SOCK_BUSY; if (sock_io_mode & (1 << sn)) FAIL(busy);
}; };
} }
@@ -1627,7 +1628,7 @@ int32_t recvfrom(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, por
case Sn_MR_UDP4: case Sn_MR_UDP4:
case Sn_MR_UDP6: case Sn_MR_UDP6:
case Sn_MR_UDPD: case Sn_MR_UDPD:
if (addr == 0) return SOCKERR_ARG; if (addr == 0) FAIL(arg);
sock_pack_info[sn] = head[0] & 0xF8; sock_pack_info[sn] = head[0] & 0xF8;
if (sock_pack_info[sn] & PACK_IPv6) *addrlen = 16; if (sock_pack_info[sn] & PACK_IPv6) *addrlen = 16;
else *addrlen = 4; else *addrlen = 4;
@@ -1641,7 +1642,7 @@ int32_t recvfrom(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, por
sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[1] - 2; sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[1] - 2;
if (sock_remained_size[sn] > 1514) { if (sock_remained_size[sn] > 1514) {
close(sid); close(sid);
return SOCKFATAL_PACKLEN; FAIL(fatal_packlen);
} }
sock_pack_info[sn] = PACK_FIRST; sock_pack_info[sn] = PACK_FIRST;
} }
@@ -1652,7 +1653,7 @@ int32_t recvfrom(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, por
case Sn_MR_IPRAW6: case Sn_MR_IPRAW6:
case Sn_MR_IPRAW4: case Sn_MR_IPRAW4:
if (sock_remained_size[sn] == 0) { if (sock_remained_size[sn] == 0) {
if (*addr == 0) return SOCKERR_ARG; if (*addr == 0) FAIL(arg);
sock_pack_info[sn] = head[0] & 0xF8; sock_pack_info[sn] = head[0] & 0xF8;
if (sock_pack_info[sn] & PACK_IPv6) *addrlen = 16; if (sock_pack_info[sn] & PACK_IPv6) *addrlen = 16;
else *addrlen = 4; else *addrlen = 4;
@@ -1670,7 +1671,7 @@ int32_t recvfrom(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, por
sock_remained_size[sn] = pack_len; sock_remained_size[sn] = pack_len;
sock_pack_info[sn] |= PACK_FIRST; sock_pack_info[sn] |= PACK_FIRST;
if ((getSn_MR(sn) & 0x03) == 0x02) { if ((getSn_MR(sn) & 0x03) == 0x02) {
if (port == 0) return SOCKERR_ARG; if (port == 0) FAIL(arg);
wiz_recv_data(sn, head, 2); wiz_recv_data(sn, head, 2);
*port = static_cast<port_num>((((uint16_t)head[0]) << 8) + head[1]); *port = static_cast<port_num>((((uint16_t)head[0]) << 8) + head[1]);
setSn_CR(sn, Sn_CR_RECV); setSn_CR(sn, Sn_CR_RECV);
@@ -1687,10 +1688,10 @@ int32_t recvfrom(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, por
if (sock_remained_size[sn] != 0) sock_pack_info[sn] |= PACK_REMAINED; if (sock_remained_size[sn] != 0) sock_pack_info[sn] |= PACK_REMAINED;
else sock_pack_info[sn] |= PACK_COMPLETED; else sock_pack_info[sn] |= PACK_COMPLETED;
return (int32_t)pack_len; return pack_len;
} }
int8_t ctl_socket(socket_id sid, sock_ctl cstype, void* arg) { std::expected<void, sock_error> ctl_socket(socket_id sid, sock_ctl cstype, void* arg) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
uint8_t tmp = 0; uint8_t tmp = 0;
CHECK_SOCKNUM(); CHECK_SOCKNUM();
@@ -1699,7 +1700,7 @@ int8_t ctl_socket(socket_id sid, sock_ctl cstype, void* arg) {
case CS_SET_IOMODE: case CS_SET_IOMODE:
if (tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1 << sn); if (tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1 << sn);
else if (tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1 << sn); else if (tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1 << sn);
else return SOCKERR_ARG; else FAIL(arg);
break; break;
case CS_GET_IOMODE: case CS_GET_IOMODE:
*((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001);
@@ -1711,33 +1712,33 @@ int8_t ctl_socket(socket_id sid, sock_ctl cstype, void* arg) {
*((uint16_t*)arg) = getSn_RxMAX(sn); *((uint16_t*)arg) = getSn_RxMAX(sn);
break; break;
case CS_CLR_INTERRUPT: case CS_CLR_INTERRUPT:
if (tmp > SIK_ALL) return SOCKERR_ARG; if (tmp > SIK_ALL) FAIL(arg);
setSn_IR(sn, tmp); setSn_IR(sn, tmp);
break; break;
case CS_GET_INTERRUPT: case CS_GET_INTERRUPT:
*((uint8_t*)arg) = getSn_IR(sn); *((uint8_t*)arg) = getSn_IR(sn);
break; break;
case CS_SET_INTMASK: case CS_SET_INTMASK:
if (tmp > SIK_ALL) return SOCKERR_ARG; if (tmp > SIK_ALL) FAIL(arg);
setSn_IMR(sn, tmp); setSn_IMR(sn, tmp);
break; break;
case CS_GET_INTMASK: case CS_GET_INTMASK:
*((uint8_t*)arg) = getSn_IMR(sn); *((uint8_t*)arg) = getSn_IMR(sn);
break; break;
case CS_SET_PREFER: case CS_SET_PREFER:
if ((tmp & 0x03) == 0x01) return SOCKERR_ARG; if ((tmp & 0x03) == 0x01) FAIL(arg);
setSn_PSR(sn, tmp); setSn_PSR(sn, tmp);
break; break;
case CS_GET_PREFER: case CS_GET_PREFER:
*(uint8_t*)arg = getSn_PSR(sn); *(uint8_t*)arg = getSn_PSR(sn);
break; break;
default: default:
return SOCKERR_ARG; FAIL(arg);
} }
return SOCK_OK; return {};
} }
int8_t set_sockopt(socket_id sid, sockopt_type sotype, void* arg) { std::expected<void, sock_error> set_sockopt(socket_id sid, sockopt_type sotype, void* arg) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
CHECK_SOCKNUM(); CHECK_SOCKNUM();
switch (sotype) { switch (sotype) {
@@ -1759,12 +1760,12 @@ int8_t set_sockopt(socket_id sid, sockopt_type sotype, void* arg) {
break; break;
case SO_KEEPALIVESEND: case SO_KEEPALIVESEND:
CHECK_TCPMODE(); CHECK_TCPMODE();
if (getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; if (getSn_KPALVTR(sn) != 0) FAIL(sock_opt);
setSn_CR(sn, Sn_CR_SEND_KEEP); setSn_CR(sn, Sn_CR_SEND_KEEP);
while (getSn_CR(sn) != 0) { while (getSn_CR(sn) != 0) {
if (getSn_IR(sn) & Sn_IR_TIMEOUT) { if (getSn_IR(sn) & Sn_IR_TIMEOUT) {
setSn_IR(sn, Sn_IR_TIMEOUT); setSn_IR(sn, Sn_IR_TIMEOUT);
return SOCKERR_TIMEOUT; FAIL(timeout);
} }
} }
break; break;
@@ -1773,12 +1774,12 @@ int8_t set_sockopt(socket_id sid, sockopt_type sotype, void* arg) {
setSn_KPALVTR(sn, *(uint8_t*)arg); setSn_KPALVTR(sn, *(uint8_t*)arg);
break; break;
default: default:
return SOCKERR_ARG; FAIL(arg);
} }
return SOCK_OK; return {};
} }
int8_t get_sockopt(socket_id sid, sockopt_type sotype, void* arg) { std::expected<void, sock_error> get_sockopt(socket_id sid, sockopt_type sotype, void* arg) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
CHECK_SOCKNUM(); CHECK_SOCKNUM();
switch (sotype) { switch (sotype) {
@@ -1825,25 +1826,25 @@ int8_t get_sockopt(socket_id sid, sockopt_type sotype, void* arg) {
*(uint8_t*)arg = getSn_ESR(sn) & 0x07; *(uint8_t*)arg = getSn_ESR(sn) & 0x07;
break; break;
case SO_REMAINSIZE: case SO_REMAINSIZE:
if (getSn_MR(sn) == SOCK_CLOSED) return SOCKERR_SOCKSTATUS; if (getSn_MR(sn) == SOCK_CLOSED) FAIL(sock_status);
if (getSn_MR(sn) & 0x01) *(uint16_t*)arg = getSn_RX_RSR(sn); if (getSn_MR(sn) & 0x01) *(uint16_t*)arg = getSn_RX_RSR(sn);
else *(uint16_t*)arg = sock_remained_size[sn]; else *(uint16_t*)arg = sock_remained_size[sn];
break; break;
case SO_PACKINFO: case SO_PACKINFO:
if (getSn_MR(sn) == SOCK_CLOSED) return SOCKERR_SOCKSTATUS; if (getSn_MR(sn) == SOCK_CLOSED) FAIL(sock_status);
if (getSn_MR(sn) & 0x01) return SOCKERR_SOCKMODE; if (getSn_MR(sn) & 0x01) FAIL(sock_mode);
else *(uint8_t*)arg = sock_pack_info[sn]; else *(uint8_t*)arg = sock_pack_info[sn];
break; break;
case SO_MODE: case SO_MODE:
*(uint8_t*)arg = 0x0F & getSn_MR(sn); *(uint8_t*)arg = 0x0F & getSn_MR(sn);
break; break;
default: default:
return SOCKERR_SOCKOPT; FAIL(sock_opt);
} }
return SOCK_OK; return {};
} }
int16_t peek_socket_msg(socket_id sid, uint8_t* submsg, uint16_t subsize) { std::optional<uint16_t> peek_socket_msg(socket_id sid, uint8_t* submsg, uint16_t subsize) {
uint8_t sn = static_cast<uint8_t>(sid); uint8_t sn = static_cast<uint8_t>(sid);
uint32_t rx_ptr = 0; uint32_t rx_ptr = 0;
uint16_t i = 0, sub_idx = 0; uint16_t i = 0, sub_idx = 0;
@@ -1853,14 +1854,14 @@ int16_t peek_socket_msg(socket_id sid, uint8_t* submsg, uint16_t subsize) {
for (i = 0; i < getSn_RX_RSR(sn); i++) { for (i = 0; i < getSn_RX_RSR(sn); i++) {
if (WIZCHIP_READ(rx_ptr) == submsg[sub_idx]) { if (WIZCHIP_READ(rx_ptr) == submsg[sub_idx]) {
sub_idx++; sub_idx++;
if (sub_idx == subsize) return (i + 1 - sub_idx); if (sub_idx == subsize) return static_cast<uint16_t>(i + 1 - sub_idx);
} else { } else {
sub_idx = 0; sub_idx = 0;
} }
rx_ptr = WIZCHIP_OFFSET_INC(rx_ptr, 1); rx_ptr = WIZCHIP_OFFSET_INC(rx_ptr, 1);
} }
} }
return -1; return std::nullopt;
} }
void reset() { void reset() {
+32 -31
View File
@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <expected>
#include <optional>
namespace w6300 { namespace w6300 {
@@ -152,24 +154,23 @@ void init();
bool check(); bool check();
void init_net(net_info info); void init_net(net_info info);
constexpr int16_t SOCK_OK = 1; enum class sock_error : int16_t {
constexpr int16_t SOCK_BUSY = 0; busy = 0,
constexpr int16_t SOCK_FATAL = -1000; sock_num = -1,
constexpr int16_t SOCK_ERROR = 0; sock_opt = -2,
constexpr int16_t SOCKERR_SOCKNUM = SOCK_ERROR - 1; sock_init = -3,
constexpr int16_t SOCKERR_SOCKOPT = SOCK_ERROR - 2; sock_closed = -4,
constexpr int16_t SOCKERR_SOCKINIT = SOCK_ERROR - 3; sock_mode = -5,
constexpr int16_t SOCKERR_SOCKCLOSED = SOCK_ERROR - 4; sock_flag = -6,
constexpr int16_t SOCKERR_SOCKMODE = SOCK_ERROR - 5; sock_status = -7,
constexpr int16_t SOCKERR_SOCKFLAG = SOCK_ERROR - 6; arg = -10,
constexpr int16_t SOCKERR_SOCKSTATUS = SOCK_ERROR - 7; port_zero = -11,
constexpr int16_t SOCKERR_ARG = SOCK_ERROR - 10; ip_invalid = -12,
constexpr int16_t SOCKERR_PORTZERO = SOCK_ERROR - 11; timeout = -13,
constexpr int16_t SOCKERR_IPINVALID = SOCK_ERROR - 12; data_len = -14,
constexpr int16_t SOCKERR_TIMEOUT = SOCK_ERROR - 13; buffer = -15,
constexpr int16_t SOCKERR_DATALEN = SOCK_ERROR - 14; fatal_packlen = -1001,
constexpr int16_t SOCKERR_BUFFER = SOCK_ERROR - 15; };
constexpr int16_t SOCKFATAL_PACKLEN = SOCK_FATAL - 1;
enum class protocol : uint8_t { enum class protocol : uint8_t {
tcp = 0x01, tcp = 0x01,
@@ -240,12 +241,12 @@ enum class sock_io_mode : uint8_t {
nonblock = 1, nonblock = 1,
}; };
int8_t open_socket(socket_id sn, protocol proto, port_num port, sock_flag flag); std::expected<socket_id, sock_error> open_socket(socket_id sn, protocol proto, port_num port, sock_flag flag);
int8_t close(socket_id sn); std::expected<void, sock_error> close(socket_id sn);
int8_t listen(socket_id sn); std::expected<void, sock_error> listen(socket_id sn);
int8_t disconnect(socket_id sn); std::expected<void, sock_error> disconnect(socket_id sn);
int32_t send(socket_id sn, uint8_t* buf, uint16_t len); std::expected<uint16_t, sock_error> send(socket_id sn, uint8_t* buf, uint16_t len);
int32_t recv(socket_id sn, uint8_t* buf, uint16_t len); std::expected<uint16_t, sock_error> recv(socket_id sn, uint8_t* buf, uint16_t len);
enum sockint_kind { enum sockint_kind {
SIK_CONNECTED = (1 << 0), SIK_CONNECTED = (1 << 0),
@@ -287,13 +288,13 @@ enum sockopt_type {
SO_PACKINFO SO_PACKINFO
}; };
int8_t ctl_socket(socket_id sn, sock_ctl type, void* arg); std::expected<void, sock_error> ctl_socket(socket_id sn, sock_ctl type, void* arg);
int8_t set_sockopt(socket_id sn, sockopt_type type, void* arg); std::expected<void, sock_error> set_sockopt(socket_id sn, sockopt_type type, void* arg);
int8_t get_sockopt(socket_id sn, sockopt_type type, void* arg); std::expected<void, sock_error> get_sockopt(socket_id sn, sockopt_type type, void* arg);
int16_t peek_socket_msg(socket_id sn, uint8_t* submsg, uint16_t subsize); std::optional<uint16_t> peek_socket_msg(socket_id sn, uint8_t* submsg, uint16_t subsize);
int8_t connect(socket_id sn, uint8_t* addr, port_num port, uint8_t addrlen); std::expected<void, sock_error> connect(socket_id sn, uint8_t* addr, port_num port, uint8_t addrlen);
int32_t sendto(socket_id sn, uint8_t* buf, uint16_t len, uint8_t* addr, port_num port, uint8_t addrlen); std::expected<uint16_t, sock_error> sendto(socket_id sn, uint8_t* buf, uint16_t len, uint8_t* addr, port_num port, uint8_t addrlen);
int32_t recvfrom(socket_id sn, uint8_t* buf, uint16_t len, uint8_t* addr, port_num* port, uint8_t* addrlen); std::expected<uint16_t, sock_error> recvfrom(socket_id sn, uint8_t* buf, uint16_t len, uint8_t* addr, port_num* port, uint8_t* addrlen);
} // namespace w6300 } // namespace w6300