diff --git a/picomap.cpp b/picomap.cpp index 2801fc2..bf94e4f 100644 --- a/picomap.cpp +++ b/picomap.cpp @@ -71,7 +71,7 @@ int main() { std::copy(uid.id, uid.id + 8, resp.board_id.begin()); w6300::net_info info; w6300::get_net_info(&info); - std::copy(info.mac, info.mac + 6, resp.mac.begin()); + resp.mac = info.mac; send_bytes(encode_response(msg->message_id, resp)); break; } diff --git a/w6300/w6300.cpp b/w6300/w6300.cpp index 4bcd349..91fc28f 100644 --- a/w6300/w6300.cpp +++ b/w6300/w6300.cpp @@ -260,6 +260,40 @@ constexpr uint8_t PACK_REMAINED = static_cast(pack_info::remained); constexpr uint8_t PACK_COMPLETED = static_cast(pack_info::completed); constexpr uint8_t PACK_IPv6 = static_cast(pack_info::ipv6); +enum chip_ctl { + CW_SYS_LOCK, CW_SYS_UNLOCK, CW_GET_SYSLOCK, + CW_RESET_WIZCHIP, CW_INIT_WIZCHIP, + CW_GET_INTERRUPT, CW_CLR_INTERRUPT, CW_SET_INTRMASK, CW_GET_INTRMASK, + CW_SET_INTRTIME, CW_GET_INTRTIME, CW_SET_IEN, CW_GET_IEN, + CW_GET_ID, CW_GET_VER, CW_SET_SYSCLK, CW_GET_SYSCLK, + CW_RESET_PHY, CW_SET_PHYCONF, CW_GET_PHYCONF, CW_GET_PHYSTATUS, + CW_SET_PHYPOWMODE, CW_GET_PHYPOWMODE, CW_GET_PHYLINK +}; + +enum net_ctl { + CN_SET_NETINFO, CN_GET_NETINFO, CN_SET_NETMODE, CN_GET_NETMODE, + CN_SET_TIMEOUT, CN_GET_TIMEOUT, CN_SET_PREFER, CN_GET_PREFER, +}; + +enum net_service_ctl { + CNS_ARP, CNS_PING, CNS_DAD, CNS_SLAAC, CNS_UNSOL_NA, CNS_GET_PREFIX +}; + +enum sock_ctl { + CS_SET_IOMODE, CS_GET_IOMODE, CS_GET_MAXTXBUF, CS_GET_MAXRXBUF, + CS_CLR_INTERRUPT, CS_GET_INTERRUPT, CS_SET_PREFER, CS_GET_PREFER, + CS_SET_INTMASK, CS_GET_INTMASK +}; + +enum sockopt_type { + SO_FLAG, SO_TTL, SO_TOS, SO_MSS, SO_DESTIP, SO_DESTPORT, + SO_KEEPALIVESEND, SO_KEEPALIVEAUTO, SO_SENDBUF, SO_RECVBUF, + SO_STATUS, SO_EXTSTATUS, SO_MODE, SO_REMAINSIZE, SO_PACKINFO +}; + +enum sockint_kind { SIK_CONNECTED = 1, SIK_DISCONNECTED = 2, SIK_RECEIVED = 4, SIK_TIMEOUT = 8, SIK_SENT = 16, SIK_ALL = 0x1F }; + + constexpr uint8_t SOCK_IO_BLOCK = static_cast(sock_io_mode::block); constexpr uint8_t SOCK_IO_NONBLOCK = static_cast(sock_io_mode::nonblock); @@ -1169,18 +1203,18 @@ void set_phy_power_mode(uint8_t pmode) { } void set_net_info(net_info* p) { - setSHAR(p->mac); setGAR(p->gw); setSUBR(p->sn); setSIPR(p->ip); - setGA6R(p->gw6); setSUB6R(p->sn6); setLLAR(p->lla); setGUAR(p->gua); - memcpy(dns_, p->dns, 4); - memcpy(dns6_, p->dns6, 16); + setSHAR(p->mac.data()); setGAR(p->gw.data()); setSUBR(p->sn.data()); setSIPR(p->ip.data()); + setGA6R(p->gw6.data()); setSUB6R(p->sn6.data()); setLLAR(p->lla.data()); setGUAR(p->gua.data()); + memcpy(dns_, p->dns.data(), 4); + memcpy(dns6_, p->dns6.data(), 16); ipmode_ = p->ipmode; } void get_net_info(net_info* p) { - getSHAR(p->mac); getGAR(p->gw); getSUBR(p->sn); getSIPR(p->ip); - getGA6R(p->gw6); getSUB6R(p->sn6); getLLAR(p->lla); getGUAR(p->gua); - memcpy(p->dns, dns_, 4); - memcpy(p->dns6, dns6_, 16); + getSHAR(p->mac.data()); getGAR(p->gw.data()); getSUBR(p->sn.data()); getSIPR(p->ip.data()); + getGA6R(p->gw6.data()); getSUB6R(p->sn6.data()); getLLAR(p->lla.data()); getGUAR(p->gua.data()); + memcpy(p->dns.data(), dns_, 4); + memcpy(p->dns6.data(), dns6_, 16); p->ipmode = ipmode_; } @@ -1212,20 +1246,20 @@ void get_timeout(net_timeout* t) { int8_t send_arp(arp_request* arp) { uint8_t tmp; - if (arp->destinfo.len == 16) { setSLDIP6R(arp->destinfo.ip); setSLCR(SLCR_ARP6); } - else { setSLDIP4R(arp->destinfo.ip); setSLCR(SLCR_ARP4); } + if (arp->destinfo.len == 16) { setSLDIP6R(arp->destinfo.ip.data()); setSLCR(SLCR_ARP6); } + else { setSLDIP4R(arp->destinfo.ip.data()); setSLCR(SLCR_ARP4); } while (getSLCR()); while ((tmp = getSLIR()) == 0x00); setSLIRCLR(~SLIR_RA); - if (tmp & (SLIR_ARP4 | SLIR_ARP6)) { getSLDHAR(arp->dha); return 0; } + if (tmp & (SLIR_ARP4 | SLIR_ARP6)) { getSLDHAR(arp->dha.data()); return 0; } return -1; } int8_t send_ping(ping_request* ping) { uint8_t tmp; setPINGIDR(ping->id); setPINGSEQR(ping->seq); - if (ping->destinfo.len == 16) { setSLDIP6R(ping->destinfo.ip); setSLCR(SLCR_PING6); } - else { setSLDIP4R(ping->destinfo.ip); setSLCR(SLCR_PING4); } + if (ping->destinfo.len == 16) { setSLDIP6R(ping->destinfo.ip.data()); setSLCR(SLCR_PING6); } + else { setSLDIP4R(ping->destinfo.ip.data()); setSLCR(SLCR_PING4); } while (getSLCR()); while ((tmp = getSLIR()) == 0x00); setSLIRCLR(~SLIR_RA); @@ -1252,7 +1286,7 @@ int8_t send_slaac(prefix* prefix) { if (tmp & SLIR_RS) { prefix->len = getPLR(); prefix->flag = getPFR(); prefix->valid_lifetime = getVLTR(); prefix->preferred_lifetime = getPLTR(); - getPAR(prefix->prefix); + getPAR(prefix->prefix.data()); return 0; } return -1; @@ -1272,7 +1306,7 @@ int8_t get_prefix(prefix* prefix) { if (getSLIR() & SLIR_RA) { prefix->len = getPLR(); prefix->flag = getPFR(); prefix->valid_lifetime = getVLTR(); prefix->preferred_lifetime = getPLTR(); - getPAR(prefix->prefix); + getPAR(prefix->prefix.data()); setSLIRCLR(SLIR_RA); } return -1; @@ -1280,7 +1314,7 @@ int8_t get_prefix(prefix* prefix) { constexpr uint16_t SOCK_ANY_PORT_NUM = 0xC000; static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; -static uint16_t sock_io_mode = 0; +static uint16_t sock_io_mode_bits = 0; static uint16_t sock_is_sending = 0; static uint16_t sock_remained_size[_SOCK_COUNT_] = {0,}; uint8_t sock_pack_info[_SOCK_COUNT_] = {0,}; @@ -1358,8 +1392,8 @@ std::expected open_socket(socket_id sid, protocol proto, setSn_PORTR(sn, p); setSn_CR(sn, Sn_CR_OPEN); while (getSn_CR(sn)); - sock_io_mode &= ~(1 << sn); - sock_io_mode |= ((fl & (static_cast(sock_flag::io_nonblock) >> 3)) << sn); + sock_io_mode_bits &= ~(1 << sn); + sock_io_mode_bits |= ((fl & (static_cast(sock_flag::io_nonblock) >> 3)) << sn); sock_is_sending &= ~(1 << sn); sock_remained_size[sn] = 0; sock_pack_info[sn] = static_cast(pack_info::completed); @@ -1373,7 +1407,7 @@ std::expected close(socket_id sid) { setSn_CR(sn, Sn_CR_CLOSE); while (getSn_CR(sn)); setSn_IR(sn, 0xFF); - sock_io_mode &= ~(1 << sn); + sock_io_mode_bits &= ~(1 << sn); sock_is_sending &= ~(1 << sn); sock_remained_size[sn] = 0; sock_pack_info[sn] = PACK_NONE; @@ -1418,7 +1452,7 @@ std::expected connect(socket_id sid, uint8_t * addr, port_num setSn_CR(sn, Sn_CR_CONNECT); } while (getSn_CR(sn)); - if (sock_io_mode & (1 << sn)) FAIL(busy); + if (sock_io_mode_bits & (1 << sn)) FAIL(busy); while (getSn_SR(sn) != SOCK_ESTABLISHED) { if (getSn_IR(sn) & Sn_IR_TIMEOUT) { setSn_IR(sn, Sn_IR_TIMEOUT); @@ -1437,7 +1471,7 @@ std::expected disconnect(socket_id sid) { setSn_CR(sn, Sn_CR_DISCON); while (getSn_CR(sn)); sock_is_sending &= ~(1 << sn); - if (sock_io_mode & (1 << sn)) FAIL(busy); + if (sock_io_mode_bits & (1 << sn)) FAIL(busy); while (getSn_SR(sn) != SOCK_CLOSED) { if (getSn_IR(sn) & Sn_IR_TIMEOUT) { close(sid); @@ -1448,10 +1482,11 @@ std::expected disconnect(socket_id sid) { return {}; } -std::expected send(socket_id sid, uint8_t * buf, uint16_t len) { +std::expected send(socket_id sid, std::span buf) { uint8_t sn = static_cast(sid); uint8_t tmp = 0; uint16_t freesize = 0; + uint16_t len = buf.size(); freesize = getSn_TxMAX(sn); if (len > freesize) len = freesize; @@ -1462,10 +1497,10 @@ std::expected send(socket_id sid, uint8_t * buf, uint16_t if (tmp == SOCK_CLOSED) close(sid); FAIL(sock_status); } - if ((sock_io_mode & (1 << sn)) && (len > freesize)) FAIL(busy); + if ((sock_io_mode_bits & (1 << sn)) && (len > freesize)) FAIL(busy); if (len <= freesize) break; } - wiz_send_data(sn, buf, len); + wiz_send_data(sn, const_cast(buf.data()), len); if (sock_is_sending & (1 << sn)) { while (!(getSn_IR(sn) & Sn_IR_SENDOK)) { tmp = getSn_SR(sn); @@ -1473,7 +1508,7 @@ std::expected send(socket_id sid, uint8_t * buf, uint16_t if ((tmp == SOCK_CLOSED) || (getSn_IR(sn) & Sn_IR_TIMEOUT)) close(sid); FAIL(sock_status); } - if (sock_io_mode & (1 << sn)) FAIL(busy); + if (sock_io_mode_bits & (1 << sn)) FAIL(busy); } setSn_IR(sn, Sn_IR_SENDOK); } @@ -1483,8 +1518,9 @@ std::expected send(socket_id sid, uint8_t * buf, uint16_t return len; } -std::expected recv(socket_id sid, uint8_t * buf, uint16_t len) { +std::expected recv(socket_id sid, std::span buf) { uint8_t sn = static_cast(sid); + uint16_t len = buf.size(); uint8_t tmp = 0; uint16_t recvsize = 0; @@ -1511,19 +1547,20 @@ std::expected recv(socket_id sid, uint8_t * buf, uint16_t } } if (recvsize != 0) break; - if (sock_io_mode & (1 << sn)) FAIL(busy); + if (sock_io_mode_bits & (1 << sn)) FAIL(busy); }; if (recvsize < len) len = recvsize; - wiz_recv_data(sn, buf, len); + wiz_recv_data(sn, buf.data(), len); setSn_CR(sn, Sn_CR_RECV); while (getSn_CR(sn)); return len; } -std::expected sendto(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, port_num port, uint8_t addrlen) { +std::expected sendto(socket_id sid, std::span buf, uint8_t * addr, port_num port, uint8_t addrlen) { uint8_t sn = static_cast(sid); uint16_t p = static_cast(port); + uint16_t len = buf.size(); uint8_t tmp = 0; uint8_t tcmd = Sn_CR_SEND; uint16_t freesize = 0; @@ -1568,10 +1605,10 @@ std::expected sendto(socket_id sid, uint8_t * buf, uint16_ while (1) { freesize = getSn_TX_FSR(sn); if (getSn_SR(sn) == SOCK_CLOSED) FAIL(sock_closed); - if ((sock_io_mode & (1 << sn)) && (len > freesize)) FAIL(busy); + if ((sock_io_mode_bits & (1 << sn)) && (len > freesize)) FAIL(busy); if (len <= freesize) break; }; - wiz_send_data(sn, buf, len); + wiz_send_data(sn, const_cast(buf.data()), len); setSn_CR(sn, tcmd); while (getSn_CR(sn)); while (1) { @@ -1587,8 +1624,9 @@ std::expected sendto(socket_id sid, uint8_t * buf, uint16_ return len; } -std::expected recvfrom(socket_id sid, uint8_t * buf, uint16_t len, uint8_t * addr, port_num *port, uint8_t *addrlen) { +std::expected recvfrom(socket_id sid, std::span buf, uint8_t * addr, port_num *port, uint8_t *addrlen) { uint8_t sn = static_cast(sid); + uint16_t len = buf.size(); uint8_t mr; uint8_t head[8]; uint16_t pack_len = 0; @@ -1614,7 +1652,7 @@ std::expected recvfrom(socket_id sid, uint8_t * buf, uint1 sock_pack_info[sn] = PACK_NONE; break; } - if (sock_io_mode & (1 << sn)) FAIL(busy); + if (sock_io_mode_bits & (1 << sn)) FAIL(busy); }; } @@ -1648,7 +1686,7 @@ std::expected recvfrom(socket_id sid, uint8_t * buf, uint1 } if (len < sock_remained_size[sn]) pack_len = len; else pack_len = sock_remained_size[sn]; - wiz_recv_data(sn, buf, pack_len); + wiz_recv_data(sn, buf.data(), pack_len); break; case Sn_MR_IPRAW6: case Sn_MR_IPRAW4: @@ -1680,7 +1718,7 @@ std::expected recvfrom(socket_id sid, uint8_t * buf, uint1 if (len < sock_remained_size[sn]) pack_len = len; else pack_len = sock_remained_size[sn]; - wiz_recv_data(sn, buf, pack_len); + wiz_recv_data(sn, buf.data(), pack_len); setSn_CR(sn, Sn_CR_RECV); while (getSn_CR(sn)); @@ -1698,12 +1736,12 @@ std::expected ctl_socket(socket_id sid, sock_ctl cstype, void* tmp = *((uint8_t*)arg); switch (cstype) { case CS_SET_IOMODE: - if (tmp == SOCK_IO_NONBLOCK) sock_io_mode |= (1 << sn); - else if (tmp == SOCK_IO_BLOCK) sock_io_mode &= ~(1 << sn); + if (tmp == SOCK_IO_NONBLOCK) sock_io_mode_bits |= (1 << sn); + else if (tmp == SOCK_IO_BLOCK) sock_io_mode_bits &= ~(1 << sn); else FAIL(arg); break; case CS_GET_IOMODE: - *((uint8_t*)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + *((uint8_t*)arg) = (uint8_t)((sock_io_mode_bits >> sn) & 0x0001); break; case CS_GET_MAXTXBUF: *((uint16_t*)arg) = getSn_TxMAX(sn); @@ -1752,7 +1790,7 @@ std::expected set_sockopt(socket_id sid, sockopt_type sotype, setSn_MSSR(sn, *(uint16_t*)arg); break; case SO_DESTIP: - if (((ip_address *)arg)->len == 16) setSn_DIP6R(sn, ((ip_address*)arg)->ip); + if (((ip_address *)arg)->len == 16) setSn_DIP6R(sn, ((ip_address*)arg)->ip.data()); else setSn_DIPR(sn, (uint8_t*)arg); break; case SO_DESTPORT: @@ -1784,7 +1822,7 @@ std::expected get_sockopt(socket_id sid, sockopt_type sotype, CHECK_SOCKNUM(); switch (sotype) { case SO_FLAG: - *(uint8_t*)arg = (getSn_MR(sn) & 0xF0) | (getSn_MR2(sn)) | ((uint8_t)(((sock_io_mode >> sn) & 0x0001) << 3)); + *(uint8_t*)arg = (getSn_MR(sn) & 0xF0) | (getSn_MR2(sn)) | ((uint8_t)(((sock_io_mode_bits >> sn) & 0x0001) << 3)); break; case SO_TTL: *(uint8_t*)arg = getSn_TTL(sn); @@ -1798,10 +1836,10 @@ std::expected get_sockopt(socket_id sid, sockopt_type sotype, case SO_DESTIP: CHECK_TCPMODE(); if (getSn_ESR(sn) & TCPSOCK_MODE) { - getSn_DIP6R(sn, ((ip_address*)arg)->ip); + getSn_DIP6R(sn, ((ip_address*)arg)->ip.data()); ((ip_address*)arg)->len = 16; } else { - getSn_DIPR(sn, ((ip_address*)arg)->ip); + getSn_DIPR(sn, ((ip_address*)arg)->ip.data()); ((ip_address*)arg)->len = 4; } break; @@ -1844,7 +1882,8 @@ std::expected get_sockopt(socket_id sid, sockopt_type sotype, return {}; } -std::optional peek_socket_msg(socket_id sid, uint8_t* submsg, uint16_t subsize) { +std::optional peek_socket_msg(socket_id sid, std::span submsg) { + uint16_t subsize = submsg.size(); uint8_t sn = static_cast(sid); uint32_t rx_ptr = 0; uint16_t i = 0, sub_idx = 0; @@ -1897,4 +1936,166 @@ void init_net(net_info net_info) { ctl_net(CN_SET_NETINFO, (void *)&net_info); } +std::expected set_socket_io_mode(socket_id sid, sock_io_mode mode) { + uint8_t sn = static_cast(sid); + if (sn >= _SOCK_COUNT_) FAIL(sock_num); + if (mode == sock_io_mode::nonblock) sock_io_mode_bits |= (1 << sn); + else if (mode == sock_io_mode::block) sock_io_mode_bits &= ~(1 << sn); + else FAIL(arg); + return {}; +} + +sock_io_mode get_socket_io_mode(socket_id sid) { + uint8_t sn = static_cast(sid); + return static_cast((sock_io_mode_bits >> sn) & 0x01); +} + +uint16_t get_socket_max_tx(socket_id sid) { + return getSn_TxMAX(static_cast(sid)); +} + +uint16_t get_socket_max_rx(socket_id sid) { + return getSn_RxMAX(static_cast(sid)); +} + +std::expected clear_socket_interrupt(socket_id sid, uint8_t flags) { + uint8_t sn = static_cast(sid); + if (sn >= _SOCK_COUNT_) FAIL(sock_num); + if (flags > SIK_ALL) FAIL(arg); + setSn_IR(sn, flags); + return {}; +} + +uint8_t get_socket_interrupt(socket_id sid) { + return getSn_IR(static_cast(sid)); +} + +std::expected set_socket_interrupt_mask(socket_id sid, uint8_t mask) { + uint8_t sn = static_cast(sid); + if (sn >= _SOCK_COUNT_) FAIL(sock_num); + if (mask > SIK_ALL) FAIL(arg); + setSn_IMR(sn, mask); + return {}; +} + +uint8_t get_socket_interrupt_mask(socket_id sid) { + return getSn_IMR(static_cast(sid)); +} + +std::expected set_socket_prefer(socket_id sid, srcv6_prefer pref) { + uint8_t sn = static_cast(sid); + if (sn >= _SOCK_COUNT_) FAIL(sock_num); + uint8_t v = static_cast(pref); + if ((v & 0x03) == 0x01) FAIL(arg); + setSn_PSR(sn, v); + return {}; +} + +srcv6_prefer get_socket_prefer(socket_id sid) { + return static_cast(getSn_PSR(static_cast(sid))); +} + +void set_socket_ttl(socket_id sid, uint8_t ttl) { + setSn_TTL(static_cast(sid), ttl); +} + +uint8_t get_socket_ttl(socket_id sid) { + return getSn_TTL(static_cast(sid)); +} + +void set_socket_tos(socket_id sid, uint8_t tos) { + setSn_TOS(static_cast(sid), tos); +} + +uint8_t get_socket_tos(socket_id sid) { + return getSn_TOS(static_cast(sid)); +} + +void set_socket_mss(socket_id sid, uint16_t mss) { + setSn_MSSR(static_cast(sid), mss); +} + +uint16_t get_socket_mss(socket_id sid) { + return getSn_MSSR(static_cast(sid)); +} + +void set_socket_dest_ip(socket_id sid, const ip_address& addr) { + uint8_t sn = static_cast(sid); + if (addr.len == 16) setSn_DIP6R(sn, const_cast(addr.ip.data())); + else setSn_DIPR(sn, const_cast(addr.ip.data())); +} + +ip_address get_socket_dest_ip(socket_id sid) { + uint8_t sn = static_cast(sid); + ip_address addr = {}; + if (getSn_ESR(sn) & TCPSOCK_MODE) { + getSn_DIP6R(sn, addr.ip.data()); + addr.len = 16; + } else { + getSn_DIPR(sn, addr.ip.data()); + addr.len = 4; + } + return addr; +} + +void set_socket_dest_port(socket_id sid, port_num port) { + setSn_DPORTR(static_cast(sid), static_cast(port)); +} + +port_num get_socket_dest_port(socket_id sid) { + return static_cast(getSn_DPORTR(static_cast(sid))); +} + +std::expected send_keepalive(socket_id sid) { + uint8_t sn = static_cast(sid); + if ((getSn_MR(sn) & 0x03) != 0x01) FAIL(sock_mode); + if (getSn_KPALVTR(sn) != 0) FAIL(sock_opt); + setSn_CR(sn, Sn_CR_SEND_KEEP); + while (getSn_CR(sn) != 0) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + FAIL(timeout); + } + } + return {}; +} + +void set_socket_keepalive_auto(socket_id sid, uint8_t interval) { + setSn_KPALVTR(static_cast(sid), interval); +} + +uint8_t get_socket_keepalive_auto(socket_id sid) { + return getSn_KPALVTR(static_cast(sid)); +} + +uint16_t get_socket_send_buf(socket_id sid) { + return getSn_TX_FSR(static_cast(sid)); +} + +uint16_t get_socket_recv_buf(socket_id sid) { + return getSn_RX_RSR(static_cast(sid)); +} + +uint8_t get_socket_status(socket_id sid) { + return getSn_SR(static_cast(sid)); +} + +uint8_t get_socket_ext_status(socket_id sid) { + return getSn_ESR(static_cast(sid)) & 0x07; +} + +uint8_t get_socket_mode(socket_id sid) { + return getSn_MR(static_cast(sid)) & 0x0F; +} + +uint16_t get_socket_remain_size(socket_id sid) { + uint8_t sn = static_cast(sid); + if (getSn_MR(sn) & 0x01) return getSn_RX_RSR(sn); + return sock_remained_size[sn]; +} + +pack_info get_socket_pack_info(socket_id sid) { + return static_cast(sock_pack_info[static_cast(sid)]); +} + } // namespace w6300 diff --git a/w6300/w6300.h b/w6300/w6300.h index 2cc9996..ccbd61f 100644 --- a/w6300/w6300.h +++ b/w6300/w6300.h @@ -1,7 +1,9 @@ #pragma once +#include #include #include #include +#include namespace w6300 { @@ -10,150 +12,6 @@ constexpr int SOCK_COUNT = 8; enum class socket_id : uint8_t {}; enum class port_num : uint16_t {}; -enum chip_ctl { - CW_SYS_LOCK, CW_SYS_UNLOCK, CW_GET_SYSLOCK, - CW_RESET_WIZCHIP, CW_INIT_WIZCHIP, - CW_GET_INTERRUPT, CW_CLR_INTERRUPT, CW_SET_INTRMASK, CW_GET_INTRMASK, - CW_SET_INTRTIME, CW_GET_INTRTIME, CW_SET_IEN, CW_GET_IEN, - CW_GET_ID, CW_GET_VER, CW_SET_SYSCLK, CW_GET_SYSCLK, - CW_RESET_PHY, CW_SET_PHYCONF, CW_GET_PHYCONF, CW_GET_PHYSTATUS, - CW_SET_PHYPOWMODE, CW_GET_PHYPOWMODE, CW_GET_PHYLINK -}; - -enum net_ctl { - CN_SET_NETINFO, CN_GET_NETINFO, CN_SET_NETMODE, CN_GET_NETMODE, - CN_SET_TIMEOUT, CN_GET_TIMEOUT, CN_SET_PREFER, CN_GET_PREFER, -}; - -enum net_service_ctl { - CNS_ARP, CNS_PING, CNS_DAD, CNS_SLAAC, CNS_UNSOL_NA, CNS_GET_PREFIX -}; - -enum intr_kind : uint32_t { - IK_PPPOE_TERMINATED = (1 << 0), IK_DEST_UNREACH = (1 << 1), IK_IP_CONFLICT = (1 << 2), - IK_DEST_UNREACH6 = (1 << 4), IK_WOL = (1 << 7), IK_NET_ALL = 0x97, - IK_SOCK_0 = (1 << 8), IK_SOCK_1 = (1 << 9), IK_SOCK_2 = (1 << 10), IK_SOCK_3 = (1 << 11), - IK_SOCK_4 = (1 << 12), IK_SOCK_5 = (1 << 13), IK_SOCK_6 = (1 << 14), IK_SOCK_7 = (1 << 15), - IK_SOCK_ALL = (0xFF << 8), - IK_SOCKL_TOUT = (1 << 16), IK_SOCKL_ARP4 = (1 << 17), IK_SOCKL_PING4 = (1 << 18), - IK_SOCKL_ARP6 = (1 << 19), IK_SOCKL_PING6 = (1 << 20), IK_SOCKL_NS = (1 << 21), - IK_SOCKL_RS = (1 << 22), IK_SOCKL_RA = (1 << 23), IK_SOCKL_ALL = (0xFF << 16), - IK_INT_ALL = 0x00FFFF97 -}; - - -struct phy_conf { - uint8_t by; - uint8_t mode; - uint8_t speed; - uint8_t duplex; -}; - -enum ipconf_mode : uint8_t { - NETINFO_NONE = 0x00, NETINFO_STATIC_V4 = 0x01, NETINFO_STATIC_V6 = 0x02, - NETINFO_STATIC_ALL = 0x03, NETINFO_SLAAC_V6 = 0x04, - NETINFO_DHCP_V4 = 0x10, NETINFO_DHCP_V6 = 0x20, NETINFO_DHCP_ALL = 0x30 -}; - -enum dhcp_mode : uint8_t { NETINFO_STATIC = 1, NETINFO_DHCP }; - -struct net_info { - uint8_t mac[6]; - uint8_t ip[4]; - uint8_t sn[4]; - uint8_t gw[4]; - uint8_t lla[16]; - uint8_t gua[16]; - uint8_t sn6[16]; - uint8_t gw6[16]; - uint8_t dns[4]; - uint8_t dns6[16]; - ipconf_mode ipmode; - dhcp_mode dhcp; -}; - -enum netmode_type : uint32_t { - NM_IPB_V4 = (1 << 0), NM_IPB_V6 = (1 << 1), NM_WOL = (1 << 2), - NM_PB6_MULTI = (1 << 4), NM_PB6_ALLNODE = (1 << 5), NM_MR_MASK = 0x37, - NM_PPPoE = (1 << 8), NM_DHA_SELECT = (1 << 15), NM_MR2_MASK = (0x09 << 8), - NM_PB4_ALL = (1 << 16), NM_TRSTB_V4 = (1 << 17), NM_PARP_V4 = (1 << 18), - NM_UNRB_V4 = (1 << 19), NM_NET4_MASK = (0x0F << 16), - NM_PB6_ALL = (1 << 24), NM_TRSTB_V6 = (1 << 25), NM_PARP_V6 = (1 << 26), - NM_UNRB_V6 = (1 << 27), NM_NET6_MASK = (0x0F << 24), - NM_MASK_ALL = 0x0F0F0937 -}; - -struct net_timeout { - uint8_t s_retry_cnt; - uint16_t s_time_100us; - uint8_t sl_retry_cnt; - uint16_t sl_time_100us; -}; - -struct ip_address { - uint8_t ip[16]; - uint8_t len; -}; - -struct prefix { - uint8_t len; - uint8_t flag; - uint32_t valid_lifetime; - uint32_t preferred_lifetime; - uint8_t prefix[16]; -}; - -struct arp_request { - ip_address destinfo; - uint8_t dha[6]; -}; - -struct ping_request { - uint16_t id; - uint16_t seq; - ip_address destinfo; -}; - -int8_t ctl_chip(chip_ctl type, void* arg); -int8_t ctl_net(net_ctl type, void* arg); -int8_t ctl_net_service(net_service_ctl type, void* arg); - -void soft_reset(); -int8_t init_buffers(uint8_t* txsize, uint8_t* rxsize); -void clear_interrupt(intr_kind intr); -intr_kind get_interrupt(); -void set_interrupt_mask(intr_kind intr); -intr_kind get_interrupt_mask(); - -int8_t get_phy_link(); -int8_t get_phy_power_mode(); -void reset_phy(); -void set_phy_conf(phy_conf* conf); -void get_phy_conf(phy_conf* conf); -void get_phy_status(phy_conf* conf); -void set_phy_power_mode(uint8_t pmode); - -void set_net_info(net_info* info); -void get_net_info(net_info* info); -void set_net_mode(netmode_type mode); -netmode_type get_net_mode(); -void set_timeout(net_timeout* timeout); -void get_timeout(net_timeout* timeout); - -int8_t send_arp(arp_request* arp); -int8_t send_ping(ping_request* ping); -int8_t send_dad(uint8_t* ipv6); -int8_t send_slaac(prefix* pfx); -int8_t send_unsolicited(); -int8_t get_prefix(prefix* pfx); - -void init_spi(); -void init_critical_section(); -void reset(); -void init(); -bool check(); -void init_net(net_info info); - enum class sock_error : int16_t { busy = 0, sock_num = -1, @@ -241,60 +99,169 @@ enum class sock_io_mode : uint8_t { nonblock = 1, }; +enum intr_kind : uint32_t { + IK_PPPOE_TERMINATED = (1 << 0), IK_DEST_UNREACH = (1 << 1), IK_IP_CONFLICT = (1 << 2), + IK_DEST_UNREACH6 = (1 << 4), IK_WOL = (1 << 7), IK_NET_ALL = 0x97, + IK_SOCK_0 = (1 << 8), IK_SOCK_1 = (1 << 9), IK_SOCK_2 = (1 << 10), IK_SOCK_3 = (1 << 11), + IK_SOCK_4 = (1 << 12), IK_SOCK_5 = (1 << 13), IK_SOCK_6 = (1 << 14), IK_SOCK_7 = (1 << 15), + IK_SOCK_ALL = (0xFF << 8), + IK_SOCKL_TOUT = (1 << 16), IK_SOCKL_ARP4 = (1 << 17), IK_SOCKL_PING4 = (1 << 18), + IK_SOCKL_ARP6 = (1 << 19), IK_SOCKL_PING6 = (1 << 20), IK_SOCKL_NS = (1 << 21), + IK_SOCKL_RS = (1 << 22), IK_SOCKL_RA = (1 << 23), IK_SOCKL_ALL = (0xFF << 16), + IK_INT_ALL = 0x00FFFF97 +}; + +struct phy_conf { + uint8_t by; + uint8_t mode; + uint8_t speed; + uint8_t duplex; +}; + +enum ipconf_mode : uint8_t { + NETINFO_NONE = 0x00, NETINFO_STATIC_V4 = 0x01, NETINFO_STATIC_V6 = 0x02, + NETINFO_STATIC_ALL = 0x03, NETINFO_SLAAC_V6 = 0x04, + NETINFO_DHCP_V4 = 0x10, NETINFO_DHCP_V6 = 0x20, NETINFO_DHCP_ALL = 0x30 +}; + +enum dhcp_mode : uint8_t { NETINFO_STATIC = 1, NETINFO_DHCP }; + +struct net_info { + std::array mac; + std::array ip; + std::array sn; + std::array gw; + std::array lla; + std::array gua; + std::array sn6; + std::array gw6; + std::array dns; + std::array dns6; + ipconf_mode ipmode; + dhcp_mode dhcp; +}; + +enum netmode_type : uint32_t { + NM_IPB_V4 = (1 << 0), NM_IPB_V6 = (1 << 1), NM_WOL = (1 << 2), + NM_PB6_MULTI = (1 << 4), NM_PB6_ALLNODE = (1 << 5), NM_MR_MASK = 0x37, + NM_PPPoE = (1 << 8), NM_DHA_SELECT = (1 << 15), NM_MR2_MASK = (0x09 << 8), + NM_PB4_ALL = (1 << 16), NM_TRSTB_V4 = (1 << 17), NM_PARP_V4 = (1 << 18), + NM_UNRB_V4 = (1 << 19), NM_NET4_MASK = (0x0F << 16), + NM_PB6_ALL = (1 << 24), NM_TRSTB_V6 = (1 << 25), NM_PARP_V6 = (1 << 26), + NM_UNRB_V6 = (1 << 27), NM_NET6_MASK = (0x0F << 24), + NM_MASK_ALL = 0x0F0F0937 +}; + +struct net_timeout { + uint8_t s_retry_cnt; + uint16_t s_time_100us; + uint8_t sl_retry_cnt; + uint16_t sl_time_100us; +}; + +struct ip_address { + std::array ip; + uint8_t len; +}; + +struct prefix { + uint8_t len; + uint8_t flag; + uint32_t valid_lifetime; + uint32_t preferred_lifetime; + std::array prefix; +}; + +struct arp_request { + ip_address destinfo; + std::array dha; +}; + +struct ping_request { + uint16_t id; + uint16_t seq; + ip_address destinfo; +}; + +void init_spi(); +void init_critical_section(); +void reset(); +void init(); +bool check(); +void init_net(net_info info); + +void soft_reset(); +int8_t init_buffers(uint8_t* txsize, uint8_t* rxsize); +void clear_interrupt(intr_kind intr); +intr_kind get_interrupt(); +void set_interrupt_mask(intr_kind intr); +intr_kind get_interrupt_mask(); + +int8_t get_phy_link(); +int8_t get_phy_power_mode(); +void reset_phy(); +void set_phy_conf(phy_conf* conf); +void get_phy_conf(phy_conf* conf); +void get_phy_status(phy_conf* conf); +void set_phy_power_mode(uint8_t pmode); + +void set_net_info(net_info* info); +void get_net_info(net_info* info); +void set_net_mode(netmode_type mode); +netmode_type get_net_mode(); +void set_timeout(net_timeout* timeout); +void get_timeout(net_timeout* timeout); + +int8_t send_arp(arp_request* arp); +int8_t send_ping(ping_request* ping); +int8_t send_dad(uint8_t* ipv6); +int8_t send_slaac(prefix* pfx); +int8_t send_unsolicited(); +int8_t get_prefix(prefix* pfx); + std::expected open_socket(socket_id sn, protocol proto, port_num port, sock_flag flag); std::expected close(socket_id sn); std::expected listen(socket_id sn); std::expected disconnect(socket_id sn); -std::expected send(socket_id sn, uint8_t* buf, uint16_t len); -std::expected recv(socket_id sn, uint8_t* buf, uint16_t len); - -enum sockint_kind { - SIK_CONNECTED = (1 << 0), - SIK_DISCONNECTED = (1 << 1), - SIK_RECEIVED = (1 << 2), - SIK_TIMEOUT = (1 << 3), - SIK_SENT = (1 << 4), - SIK_ALL = 0x1F -}; - -enum sock_ctl { - CS_SET_IOMODE, - CS_GET_IOMODE, - CS_GET_MAXTXBUF, - CS_GET_MAXRXBUF, - CS_CLR_INTERRUPT, - CS_GET_INTERRUPT, - CS_SET_PREFER, - CS_GET_PREFER, - CS_SET_INTMASK, - CS_GET_INTMASK -}; - -enum sockopt_type { - SO_FLAG, - SO_TTL, - SO_TOS, - SO_MSS, - SO_DESTIP, - SO_DESTPORT, - SO_KEEPALIVESEND, - SO_KEEPALIVEAUTO, - SO_SENDBUF, - SO_RECVBUF, - SO_STATUS, - SO_EXTSTATUS, - SO_MODE, - SO_REMAINSIZE, - SO_PACKINFO -}; - -std::expected ctl_socket(socket_id sn, sock_ctl type, void* arg); -std::expected set_sockopt(socket_id sn, sockopt_type type, void* arg); -std::expected get_sockopt(socket_id sn, sockopt_type type, void* arg); -std::optional peek_socket_msg(socket_id sn, uint8_t* submsg, uint16_t subsize); +std::expected send(socket_id sn, std::span buf); +std::expected recv(socket_id sn, std::span buf); std::expected connect(socket_id sn, uint8_t* addr, port_num port, uint8_t addrlen); -std::expected sendto(socket_id sn, uint8_t* buf, uint16_t len, uint8_t* addr, port_num port, uint8_t addrlen); -std::expected recvfrom(socket_id sn, uint8_t* buf, uint16_t len, uint8_t* addr, port_num* port, uint8_t* addrlen); +std::expected sendto(socket_id sn, std::span buf, uint8_t* addr, port_num port, uint8_t addrlen); +std::expected recvfrom(socket_id sn, std::span buf, uint8_t* addr, port_num* port, uint8_t* addrlen); + +std::expected set_socket_io_mode(socket_id sn, sock_io_mode mode); +sock_io_mode get_socket_io_mode(socket_id sn); +uint16_t get_socket_max_tx(socket_id sn); +uint16_t get_socket_max_rx(socket_id sn); +std::expected clear_socket_interrupt(socket_id sn, uint8_t flags); +uint8_t get_socket_interrupt(socket_id sn); +std::expected set_socket_interrupt_mask(socket_id sn, uint8_t mask); +uint8_t get_socket_interrupt_mask(socket_id sn); +std::expected set_socket_prefer(socket_id sn, srcv6_prefer pref); +srcv6_prefer get_socket_prefer(socket_id sn); + +void set_socket_ttl(socket_id sn, uint8_t ttl); +uint8_t get_socket_ttl(socket_id sn); +void set_socket_tos(socket_id sn, uint8_t tos); +uint8_t get_socket_tos(socket_id sn); +void set_socket_mss(socket_id sn, uint16_t mss); +uint16_t get_socket_mss(socket_id sn); +void set_socket_dest_ip(socket_id sn, const ip_address& addr); +ip_address get_socket_dest_ip(socket_id sn); +void set_socket_dest_port(socket_id sn, port_num port); +port_num get_socket_dest_port(socket_id sn); +std::expected send_keepalive(socket_id sn); +void set_socket_keepalive_auto(socket_id sn, uint8_t interval); +uint8_t get_socket_keepalive_auto(socket_id sn); +uint16_t get_socket_send_buf(socket_id sn); +uint16_t get_socket_recv_buf(socket_id sn); +uint8_t get_socket_status(socket_id sn); +uint8_t get_socket_ext_status(socket_id sn); +uint8_t get_socket_mode(socket_id sn); +uint16_t get_socket_remain_size(socket_id sn); +pack_info get_socket_pack_info(socket_id sn); + +std::optional peek_socket_msg(socket_id sn, std::span submsg); } // namespace w6300