|
|
@ -22,15 +22,19 @@ namespace {
|
|
|
|
|
|
|
|
|
|
|
|
namespace Service::NIFM {
|
|
|
|
namespace Service::NIFM {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is nn::nifm::RequestState
|
|
|
|
enum class RequestState : u32 {
|
|
|
|
enum class RequestState : u32 {
|
|
|
|
NotSubmitted = 1,
|
|
|
|
NotSubmitted = 1,
|
|
|
|
Error = 1, ///< The duplicate 1 is intentional; it means both not submitted and error on HW.
|
|
|
|
Invalid = 1, ///< The duplicate 1 is intentional; it means both not submitted and error on HW.
|
|
|
|
Pending = 2,
|
|
|
|
OnHold = 2,
|
|
|
|
Connected = 3,
|
|
|
|
Accepted = 3,
|
|
|
|
|
|
|
|
Blocking = 4,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
enum class InternetConnectionType : u8 {
|
|
|
|
// This is nn::nifm::NetworkInterfaceType
|
|
|
|
WiFi = 1,
|
|
|
|
enum class NetworkInterfaceType : u32 {
|
|
|
|
|
|
|
|
Invalid = 0,
|
|
|
|
|
|
|
|
WiFi_Ieee80211 = 1,
|
|
|
|
Ethernet = 2,
|
|
|
|
Ethernet = 2,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -42,14 +46,23 @@ enum class InternetConnectionStatus : u8 {
|
|
|
|
Connected,
|
|
|
|
Connected,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is nn::nifm::NetworkProfileType
|
|
|
|
|
|
|
|
enum class NetworkProfileType : u32 {
|
|
|
|
|
|
|
|
User,
|
|
|
|
|
|
|
|
SsidList,
|
|
|
|
|
|
|
|
Temporary,
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is nn::nifm::IpAddressSetting
|
|
|
|
struct IpAddressSetting {
|
|
|
|
struct IpAddressSetting {
|
|
|
|
bool is_automatic{};
|
|
|
|
bool is_automatic{};
|
|
|
|
Network::IPv4Address current_address{};
|
|
|
|
Network::IPv4Address ip_address{};
|
|
|
|
Network::IPv4Address subnet_mask{};
|
|
|
|
Network::IPv4Address subnet_mask{};
|
|
|
|
Network::IPv4Address gateway{};
|
|
|
|
Network::IPv4Address default_gateway{};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
static_assert(sizeof(IpAddressSetting) == 0xD, "IpAddressSetting has incorrect size.");
|
|
|
|
static_assert(sizeof(IpAddressSetting) == 0xD, "IpAddressSetting has incorrect size.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is nn::nifm::DnsSetting
|
|
|
|
struct DnsSetting {
|
|
|
|
struct DnsSetting {
|
|
|
|
bool is_automatic{};
|
|
|
|
bool is_automatic{};
|
|
|
|
Network::IPv4Address primary_dns{};
|
|
|
|
Network::IPv4Address primary_dns{};
|
|
|
@ -57,18 +70,26 @@ struct DnsSetting {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
static_assert(sizeof(DnsSetting) == 0x9, "DnsSetting has incorrect size.");
|
|
|
|
static_assert(sizeof(DnsSetting) == 0x9, "DnsSetting has incorrect size.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is nn::nifm::AuthenticationSetting
|
|
|
|
|
|
|
|
struct AuthenticationSetting {
|
|
|
|
|
|
|
|
bool is_enabled{};
|
|
|
|
|
|
|
|
std::array<char, 0x20> user{};
|
|
|
|
|
|
|
|
std::array<char, 0x20> password{};
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
static_assert(sizeof(AuthenticationSetting) == 0x41, "AuthenticationSetting has incorrect size.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is nn::nifm::ProxySetting
|
|
|
|
struct ProxySetting {
|
|
|
|
struct ProxySetting {
|
|
|
|
bool enabled{};
|
|
|
|
bool is_enabled{};
|
|
|
|
INSERT_PADDING_BYTES(1);
|
|
|
|
INSERT_PADDING_BYTES(1);
|
|
|
|
u16 port{};
|
|
|
|
u16 port{};
|
|
|
|
std::array<char, 0x64> proxy_server{};
|
|
|
|
std::array<char, 0x64> proxy_server{};
|
|
|
|
bool automatic_auth_enabled{};
|
|
|
|
AuthenticationSetting authentication{};
|
|
|
|
std::array<char, 0x20> user{};
|
|
|
|
|
|
|
|
std::array<char, 0x20> password{};
|
|
|
|
|
|
|
|
INSERT_PADDING_BYTES(1);
|
|
|
|
INSERT_PADDING_BYTES(1);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
static_assert(sizeof(ProxySetting) == 0xAA, "ProxySetting has incorrect size.");
|
|
|
|
static_assert(sizeof(ProxySetting) == 0xAA, "ProxySetting has incorrect size.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is nn::nifm::IpSettingData
|
|
|
|
struct IpSettingData {
|
|
|
|
struct IpSettingData {
|
|
|
|
IpAddressSetting ip_address_setting{};
|
|
|
|
IpAddressSetting ip_address_setting{};
|
|
|
|
DnsSetting dns_setting{};
|
|
|
|
DnsSetting dns_setting{};
|
|
|
@ -101,6 +122,7 @@ static_assert(sizeof(NifmWirelessSettingData) == 0x70,
|
|
|
|
"NifmWirelessSettingData has incorrect size.");
|
|
|
|
"NifmWirelessSettingData has incorrect size.");
|
|
|
|
|
|
|
|
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
|
|
|
|
// This is nn::nifm::detail::sf::NetworkProfileData
|
|
|
|
struct SfNetworkProfileData {
|
|
|
|
struct SfNetworkProfileData {
|
|
|
|
IpSettingData ip_setting_data{};
|
|
|
|
IpSettingData ip_setting_data{};
|
|
|
|
u128 uuid{};
|
|
|
|
u128 uuid{};
|
|
|
@ -114,13 +136,14 @@ struct SfNetworkProfileData {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
static_assert(sizeof(SfNetworkProfileData) == 0x17C, "SfNetworkProfileData has incorrect size.");
|
|
|
|
static_assert(sizeof(SfNetworkProfileData) == 0x17C, "SfNetworkProfileData has incorrect size.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This is nn::nifm::NetworkProfileData
|
|
|
|
struct NifmNetworkProfileData {
|
|
|
|
struct NifmNetworkProfileData {
|
|
|
|
u128 uuid{};
|
|
|
|
u128 uuid{};
|
|
|
|
std::array<char, 0x40> network_name{};
|
|
|
|
std::array<char, 0x40> network_name{};
|
|
|
|
u32 unknown_1{};
|
|
|
|
NetworkProfileType network_profile_type{};
|
|
|
|
u32 unknown_2{};
|
|
|
|
NetworkInterfaceType network_interface_type{};
|
|
|
|
u8 unknown_3{};
|
|
|
|
bool is_auto_connect{};
|
|
|
|
u8 unknown_4{};
|
|
|
|
bool is_large_capacity{};
|
|
|
|
INSERT_PADDING_BYTES(2);
|
|
|
|
INSERT_PADDING_BYTES(2);
|
|
|
|
NifmWirelessSettingData wireless_setting_data{};
|
|
|
|
NifmWirelessSettingData wireless_setting_data{};
|
|
|
|
IpSettingData ip_setting_data{};
|
|
|
|
IpSettingData ip_setting_data{};
|
|
|
@ -196,7 +219,7 @@ private:
|
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
|
|
|
|
|
|
|
|
|
|
|
if (state == RequestState::NotSubmitted) {
|
|
|
|
if (state == RequestState::NotSubmitted) {
|
|
|
|
UpdateState(RequestState::Pending);
|
|
|
|
UpdateState(RequestState::OnHold);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
|
IPC::ResponseBuilder rb{ctx, 2};
|
|
|
@ -219,14 +242,14 @@ private:
|
|
|
|
switch (state) {
|
|
|
|
switch (state) {
|
|
|
|
case RequestState::NotSubmitted:
|
|
|
|
case RequestState::NotSubmitted:
|
|
|
|
return has_connection ? ResultSuccess : ResultNetworkCommunicationDisabled;
|
|
|
|
return has_connection ? ResultSuccess : ResultNetworkCommunicationDisabled;
|
|
|
|
case RequestState::Pending:
|
|
|
|
case RequestState::OnHold:
|
|
|
|
if (has_connection) {
|
|
|
|
if (has_connection) {
|
|
|
|
UpdateState(RequestState::Connected);
|
|
|
|
UpdateState(RequestState::Accepted);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
UpdateState(RequestState::Error);
|
|
|
|
UpdateState(RequestState::Invalid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ResultPendingConnection;
|
|
|
|
return ResultPendingConnection;
|
|
|
|
case RequestState::Connected:
|
|
|
|
case RequestState::Accepted:
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
return ResultSuccess;
|
|
|
|
return ResultSuccess;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -338,9 +361,9 @@ void IGeneralService::GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) {
|
|
|
|
.ip_setting_data{
|
|
|
|
.ip_setting_data{
|
|
|
|
.ip_address_setting{
|
|
|
|
.ip_address_setting{
|
|
|
|
.is_automatic{true},
|
|
|
|
.is_automatic{true},
|
|
|
|
.current_address{Network::TranslateIPv4(net_iface->ip_address)},
|
|
|
|
.ip_address{Network::TranslateIPv4(net_iface->ip_address)},
|
|
|
|
.subnet_mask{Network::TranslateIPv4(net_iface->subnet_mask)},
|
|
|
|
.subnet_mask{Network::TranslateIPv4(net_iface->subnet_mask)},
|
|
|
|
.gateway{Network::TranslateIPv4(net_iface->gateway)},
|
|
|
|
.default_gateway{Network::TranslateIPv4(net_iface->gateway)},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
.dns_setting{
|
|
|
|
.dns_setting{
|
|
|
|
.is_automatic{true},
|
|
|
|
.is_automatic{true},
|
|
|
@ -348,12 +371,14 @@ void IGeneralService::GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) {
|
|
|
|
.secondary_dns{1, 0, 0, 1},
|
|
|
|
.secondary_dns{1, 0, 0, 1},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
.proxy_setting{
|
|
|
|
.proxy_setting{
|
|
|
|
.enabled{false},
|
|
|
|
.is_enabled{false},
|
|
|
|
.port{},
|
|
|
|
.port{},
|
|
|
|
.proxy_server{},
|
|
|
|
.proxy_server{},
|
|
|
|
.automatic_auth_enabled{},
|
|
|
|
.authentication{
|
|
|
|
.user{},
|
|
|
|
.is_enabled{},
|
|
|
|
.password{},
|
|
|
|
.user{},
|
|
|
|
|
|
|
|
.password{},
|
|
|
|
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
.mtu{1500},
|
|
|
|
.mtu{1500},
|
|
|
|
},
|
|
|
|
},
|
|
|
@ -370,7 +395,7 @@ void IGeneralService::GetCurrentNetworkProfile(Kernel::HLERequestContext& ctx) {
|
|
|
|
// When we're connected to a room, spoof the hosts IP address
|
|
|
|
// When we're connected to a room, spoof the hosts IP address
|
|
|
|
if (auto room_member = network.GetRoomMember().lock()) {
|
|
|
|
if (auto room_member = network.GetRoomMember().lock()) {
|
|
|
|
if (room_member->IsConnected()) {
|
|
|
|
if (room_member->IsConnected()) {
|
|
|
|
network_profile_data.ip_setting_data.ip_address_setting.current_address =
|
|
|
|
network_profile_data.ip_setting_data.ip_address_setting.ip_address =
|
|
|
|
room_member->GetFakeIpAddress();
|
|
|
|
room_member->GetFakeIpAddress();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -444,9 +469,9 @@ void IGeneralService::GetCurrentIpConfigInfo(Kernel::HLERequestContext& ctx) {
|
|
|
|
return IpConfigInfo{
|
|
|
|
return IpConfigInfo{
|
|
|
|
.ip_address_setting{
|
|
|
|
.ip_address_setting{
|
|
|
|
.is_automatic{true},
|
|
|
|
.is_automatic{true},
|
|
|
|
.current_address{Network::TranslateIPv4(net_iface->ip_address)},
|
|
|
|
.ip_address{Network::TranslateIPv4(net_iface->ip_address)},
|
|
|
|
.subnet_mask{Network::TranslateIPv4(net_iface->subnet_mask)},
|
|
|
|
.subnet_mask{Network::TranslateIPv4(net_iface->subnet_mask)},
|
|
|
|
.gateway{Network::TranslateIPv4(net_iface->gateway)},
|
|
|
|
.default_gateway{Network::TranslateIPv4(net_iface->gateway)},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
.dns_setting{
|
|
|
|
.dns_setting{
|
|
|
|
.is_automatic{true},
|
|
|
|
.is_automatic{true},
|
|
|
@ -459,7 +484,7 @@ void IGeneralService::GetCurrentIpConfigInfo(Kernel::HLERequestContext& ctx) {
|
|
|
|
// When we're connected to a room, spoof the hosts IP address
|
|
|
|
// When we're connected to a room, spoof the hosts IP address
|
|
|
|
if (auto room_member = network.GetRoomMember().lock()) {
|
|
|
|
if (auto room_member = network.GetRoomMember().lock()) {
|
|
|
|
if (room_member->IsConnected()) {
|
|
|
|
if (room_member->IsConnected()) {
|
|
|
|
ip_config_info.ip_address_setting.current_address = room_member->GetFakeIpAddress();
|
|
|
|
ip_config_info.ip_address_setting.ip_address = room_member->GetFakeIpAddress();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -480,7 +505,7 @@ void IGeneralService::GetInternetConnectionStatus(Kernel::HLERequestContext& ctx
|
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
|
|
|
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
|
|
|
|
|
|
|
|
|
|
|
struct Output {
|
|
|
|
struct Output {
|
|
|
|
InternetConnectionType type{InternetConnectionType::WiFi};
|
|
|
|
u8 type{static_cast<u8>(NetworkInterfaceType::WiFi_Ieee80211)};
|
|
|
|
u8 wifi_strength{3};
|
|
|
|
u8 wifi_strength{3};
|
|
|
|
InternetConnectionStatus state{InternetConnectionStatus::Connected};
|
|
|
|
InternetConnectionStatus state{InternetConnectionStatus::Connected};
|
|
|
|
};
|
|
|
|
};
|
|
|
|