2020-07-12 03:32:58 +02:00
|
|
|
// Copyright 2020 yuzu emulator team
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
|
|
#include "common/assert.h"
|
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "core/hle/service/sockets/sockets.h"
|
|
|
|
#include "core/hle/service/sockets/sockets_translate.h"
|
|
|
|
#include "core/network/network.h"
|
|
|
|
|
|
|
|
namespace Service::Sockets {
|
|
|
|
|
|
|
|
Errno Translate(Network::Errno value) {
|
|
|
|
switch (value) {
|
|
|
|
case Network::Errno::SUCCESS:
|
|
|
|
return Errno::SUCCESS;
|
|
|
|
case Network::Errno::BADF:
|
|
|
|
return Errno::BADF;
|
|
|
|
case Network::Errno::AGAIN:
|
|
|
|
return Errno::AGAIN;
|
|
|
|
case Network::Errno::INVAL:
|
|
|
|
return Errno::INVAL;
|
|
|
|
case Network::Errno::MFILE:
|
|
|
|
return Errno::MFILE;
|
|
|
|
case Network::Errno::NOTCONN:
|
|
|
|
return Errno::NOTCONN;
|
|
|
|
default:
|
2020-12-08 04:00:34 +01:00
|
|
|
UNIMPLEMENTED_MSG("Unimplemented errno={}", value);
|
2020-07-12 03:32:58 +02:00
|
|
|
return Errno::SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<s32, Errno> Translate(std::pair<s32, Network::Errno> value) {
|
|
|
|
return {value.first, Translate(value.second)};
|
|
|
|
}
|
|
|
|
|
|
|
|
Network::Domain Translate(Domain domain) {
|
|
|
|
switch (domain) {
|
|
|
|
case Domain::INET:
|
|
|
|
return Network::Domain::INET;
|
|
|
|
default:
|
2020-12-08 04:00:34 +01:00
|
|
|
UNIMPLEMENTED_MSG("Unimplemented domain={}", domain);
|
2020-07-12 03:32:58 +02:00
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Domain Translate(Network::Domain domain) {
|
|
|
|
switch (domain) {
|
|
|
|
case Network::Domain::INET:
|
|
|
|
return Domain::INET;
|
|
|
|
default:
|
2020-12-08 04:00:34 +01:00
|
|
|
UNIMPLEMENTED_MSG("Unimplemented domain={}", domain);
|
2020-07-12 03:32:58 +02:00
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Network::Type Translate(Type type) {
|
|
|
|
switch (type) {
|
|
|
|
case Type::STREAM:
|
|
|
|
return Network::Type::STREAM;
|
|
|
|
case Type::DGRAM:
|
|
|
|
return Network::Type::DGRAM;
|
|
|
|
default:
|
2020-12-08 04:00:34 +01:00
|
|
|
UNIMPLEMENTED_MSG("Unimplemented type={}", type);
|
2021-01-05 08:18:16 +01:00
|
|
|
return Network::Type{};
|
2020-07-12 03:32:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Network::Protocol Translate(Type type, Protocol protocol) {
|
|
|
|
switch (protocol) {
|
|
|
|
case Protocol::UNSPECIFIED:
|
|
|
|
LOG_WARNING(Service, "Unspecified protocol, assuming protocol from type");
|
|
|
|
switch (type) {
|
|
|
|
case Type::DGRAM:
|
|
|
|
return Network::Protocol::UDP;
|
|
|
|
case Type::STREAM:
|
|
|
|
return Network::Protocol::TCP;
|
|
|
|
default:
|
|
|
|
return Network::Protocol::TCP;
|
|
|
|
}
|
|
|
|
case Protocol::TCP:
|
|
|
|
return Network::Protocol::TCP;
|
|
|
|
case Protocol::UDP:
|
|
|
|
return Network::Protocol::UDP;
|
|
|
|
default:
|
2020-12-08 04:00:34 +01:00
|
|
|
UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol);
|
2020-07-12 03:32:58 +02:00
|
|
|
return Network::Protocol::TCP;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
network, sockets: Replace `POLL_IN`, `POLL_OUT`, etc. constants with an `enum class PollEvents`
Actually, two enum classes, since for some reason there are two separate
yet identical `PollFD` types used in the codebase. I get that one is
ABI-compatible with the Switch while the other is an abstract type used
for the host, but why not use `WSAPOLLFD` directly for the latter?
Anyway, why make this change? Because on Apple platforms, `POLL_IN`,
`POLL_OUT`, etc. (with an underscore) are defined as macros in
<sys/signal.h>. (This is inherited from FreeBSD.) So defining
a variable with the same name causes a compile error.
I could just rename the variables, but while I was at it I thought I
might as well switch to an enum for stronger typing.
Also, change the type used for values copied directly to/from the
`events` and `revents` fields of the host *native*
`pollfd`/`WSASPOLLFD`, from `u32` to `short`, as `short` is the correct
canonical type on both Unix and Windows.
2020-08-31 16:20:44 +02:00
|
|
|
Network::PollEvents TranslatePollEventsToHost(PollEvents flags) {
|
|
|
|
Network::PollEvents result{};
|
|
|
|
const auto translate = [&result, &flags](PollEvents from, Network::PollEvents to) {
|
|
|
|
if (True(flags & from)) {
|
2020-07-12 03:32:58 +02:00
|
|
|
flags &= ~from;
|
|
|
|
result |= to;
|
|
|
|
}
|
|
|
|
};
|
network, sockets: Replace `POLL_IN`, `POLL_OUT`, etc. constants with an `enum class PollEvents`
Actually, two enum classes, since for some reason there are two separate
yet identical `PollFD` types used in the codebase. I get that one is
ABI-compatible with the Switch while the other is an abstract type used
for the host, but why not use `WSAPOLLFD` directly for the latter?
Anyway, why make this change? Because on Apple platforms, `POLL_IN`,
`POLL_OUT`, etc. (with an underscore) are defined as macros in
<sys/signal.h>. (This is inherited from FreeBSD.) So defining
a variable with the same name causes a compile error.
I could just rename the variables, but while I was at it I thought I
might as well switch to an enum for stronger typing.
Also, change the type used for values copied directly to/from the
`events` and `revents` fields of the host *native*
`pollfd`/`WSASPOLLFD`, from `u32` to `short`, as `short` is the correct
canonical type on both Unix and Windows.
2020-08-31 16:20:44 +02:00
|
|
|
translate(PollEvents::In, Network::PollEvents::In);
|
|
|
|
translate(PollEvents::Pri, Network::PollEvents::Pri);
|
|
|
|
translate(PollEvents::Out, Network::PollEvents::Out);
|
|
|
|
translate(PollEvents::Err, Network::PollEvents::Err);
|
|
|
|
translate(PollEvents::Hup, Network::PollEvents::Hup);
|
|
|
|
translate(PollEvents::Nval, Network::PollEvents::Nval);
|
|
|
|
|
|
|
|
UNIMPLEMENTED_IF_MSG((u16)flags != 0, "Unimplemented flags={}", (u16)flags);
|
|
|
|
return result;
|
2020-07-12 03:32:58 +02:00
|
|
|
}
|
|
|
|
|
network, sockets: Replace `POLL_IN`, `POLL_OUT`, etc. constants with an `enum class PollEvents`
Actually, two enum classes, since for some reason there are two separate
yet identical `PollFD` types used in the codebase. I get that one is
ABI-compatible with the Switch while the other is an abstract type used
for the host, but why not use `WSAPOLLFD` directly for the latter?
Anyway, why make this change? Because on Apple platforms, `POLL_IN`,
`POLL_OUT`, etc. (with an underscore) are defined as macros in
<sys/signal.h>. (This is inherited from FreeBSD.) So defining
a variable with the same name causes a compile error.
I could just rename the variables, but while I was at it I thought I
might as well switch to an enum for stronger typing.
Also, change the type used for values copied directly to/from the
`events` and `revents` fields of the host *native*
`pollfd`/`WSASPOLLFD`, from `u32` to `short`, as `short` is the correct
canonical type on both Unix and Windows.
2020-08-31 16:20:44 +02:00
|
|
|
PollEvents TranslatePollEventsToGuest(Network::PollEvents flags) {
|
|
|
|
PollEvents result{};
|
|
|
|
const auto translate = [&result, &flags](Network::PollEvents from, PollEvents to) {
|
|
|
|
if (True(flags & from)) {
|
2020-07-12 03:32:58 +02:00
|
|
|
flags &= ~from;
|
|
|
|
result |= to;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
network, sockets: Replace `POLL_IN`, `POLL_OUT`, etc. constants with an `enum class PollEvents`
Actually, two enum classes, since for some reason there are two separate
yet identical `PollFD` types used in the codebase. I get that one is
ABI-compatible with the Switch while the other is an abstract type used
for the host, but why not use `WSAPOLLFD` directly for the latter?
Anyway, why make this change? Because on Apple platforms, `POLL_IN`,
`POLL_OUT`, etc. (with an underscore) are defined as macros in
<sys/signal.h>. (This is inherited from FreeBSD.) So defining
a variable with the same name causes a compile error.
I could just rename the variables, but while I was at it I thought I
might as well switch to an enum for stronger typing.
Also, change the type used for values copied directly to/from the
`events` and `revents` fields of the host *native*
`pollfd`/`WSASPOLLFD`, from `u32` to `short`, as `short` is the correct
canonical type on both Unix and Windows.
2020-08-31 16:20:44 +02:00
|
|
|
translate(Network::PollEvents::In, PollEvents::In);
|
|
|
|
translate(Network::PollEvents::Pri, PollEvents::Pri);
|
|
|
|
translate(Network::PollEvents::Out, PollEvents::Out);
|
|
|
|
translate(Network::PollEvents::Err, PollEvents::Err);
|
|
|
|
translate(Network::PollEvents::Hup, PollEvents::Hup);
|
|
|
|
translate(Network::PollEvents::Nval, PollEvents::Nval);
|
2020-07-12 03:32:58 +02:00
|
|
|
|
network, sockets: Replace `POLL_IN`, `POLL_OUT`, etc. constants with an `enum class PollEvents`
Actually, two enum classes, since for some reason there are two separate
yet identical `PollFD` types used in the codebase. I get that one is
ABI-compatible with the Switch while the other is an abstract type used
for the host, but why not use `WSAPOLLFD` directly for the latter?
Anyway, why make this change? Because on Apple platforms, `POLL_IN`,
`POLL_OUT`, etc. (with an underscore) are defined as macros in
<sys/signal.h>. (This is inherited from FreeBSD.) So defining
a variable with the same name causes a compile error.
I could just rename the variables, but while I was at it I thought I
might as well switch to an enum for stronger typing.
Also, change the type used for values copied directly to/from the
`events` and `revents` fields of the host *native*
`pollfd`/`WSASPOLLFD`, from `u32` to `short`, as `short` is the correct
canonical type on both Unix and Windows.
2020-08-31 16:20:44 +02:00
|
|
|
UNIMPLEMENTED_IF_MSG((u16)flags != 0, "Unimplemented flags={}", (u16)flags);
|
|
|
|
return result;
|
2020-07-12 03:32:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Network::SockAddrIn Translate(SockAddrIn value) {
|
|
|
|
ASSERT(value.len == 0 || value.len == sizeof(value));
|
|
|
|
|
2020-09-07 06:53:08 +02:00
|
|
|
return {
|
|
|
|
.family = Translate(static_cast<Domain>(value.family)),
|
|
|
|
.ip = value.ip,
|
|
|
|
.portno = static_cast<u16>(value.portno >> 8 | value.portno << 8),
|
|
|
|
};
|
2020-07-12 03:32:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
SockAddrIn Translate(Network::SockAddrIn value) {
|
2020-09-07 06:53:08 +02:00
|
|
|
return {
|
|
|
|
.len = sizeof(SockAddrIn),
|
|
|
|
.family = static_cast<u8>(Translate(value.family)),
|
|
|
|
.portno = static_cast<u16>(value.portno >> 8 | value.portno << 8),
|
|
|
|
.ip = value.ip,
|
|
|
|
.zeroes = {},
|
|
|
|
};
|
2020-07-12 03:32:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Network::ShutdownHow Translate(ShutdownHow how) {
|
|
|
|
switch (how) {
|
|
|
|
case ShutdownHow::RD:
|
|
|
|
return Network::ShutdownHow::RD;
|
|
|
|
case ShutdownHow::WR:
|
|
|
|
return Network::ShutdownHow::WR;
|
|
|
|
case ShutdownHow::RDWR:
|
|
|
|
return Network::ShutdownHow::RDWR;
|
|
|
|
default:
|
2020-12-08 04:00:34 +01:00
|
|
|
UNIMPLEMENTED_MSG("Unimplemented how={}", how);
|
2020-07-12 03:32:58 +02:00
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Service::Sockets
|