mirror of
https://github.com/wiiu-env/ftpiiu_plugin.git
synced 2024-11-25 22:24:17 +01:00
Add access point for Switch
This commit is contained in:
parent
852669818d
commit
709e24d458
@ -86,7 +86,7 @@ LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) \
|
|||||||
CC := `which ccache 2>/dev/null` $(CC)
|
CC := `which ccache 2>/dev/null` $(CC)
|
||||||
CXX := `which ccache 2>/dev/null` $(CXX)
|
CXX := `which ccache 2>/dev/null` $(CXX)
|
||||||
|
|
||||||
LIBS := `$(PREFIX)pkg-config --libs libzstd` -ldeko3dd -lnx
|
LIBS := `$(PREFIX)pkg-config --libs libzstd` -ldeko3d -lnx
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
@ -20,8 +20,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "platform.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class FtpConfig;
|
class FtpConfig;
|
||||||
@ -40,6 +43,10 @@ public:
|
|||||||
/// \param path_ Path to config file
|
/// \param path_ Path to config file
|
||||||
static UniqueFtpConfig load (char const *path_);
|
static UniqueFtpConfig load (char const *path_);
|
||||||
|
|
||||||
|
#ifndef NDS
|
||||||
|
std::lock_guard<platform::Mutex> lockGuard ();
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief Save config
|
/// \brief Save config
|
||||||
/// \param path_ Path to config file
|
/// \param path_ Path to config file
|
||||||
bool save (char const *path_);
|
bool save (char const *path_);
|
||||||
@ -59,6 +66,17 @@ public:
|
|||||||
bool getMTime () const;
|
bool getMTime () const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
/// \brief Whether to enable access point
|
||||||
|
bool enableAP () const;
|
||||||
|
|
||||||
|
/// \brief Access point SSID
|
||||||
|
std::string const &ssid () const;
|
||||||
|
|
||||||
|
/// \brief Access point passphrase
|
||||||
|
std::string const &passphrase () const;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief Set user
|
/// \brief Set user
|
||||||
/// \param user_ User
|
/// \param user_ User
|
||||||
void setUser (std::string const &user_);
|
void setUser (std::string const &user_);
|
||||||
@ -81,9 +99,28 @@ public:
|
|||||||
void setGetMTime (bool getMTime_);
|
void setGetMTime (bool getMTime_);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
/// \brief Set whether to enable access point
|
||||||
|
/// \param enable_ Whether to enable access point
|
||||||
|
void setEnableAP (bool enable_);
|
||||||
|
|
||||||
|
/// \brief Set access point SSID
|
||||||
|
/// \param ssid_ SSID
|
||||||
|
void setSSID (std::string const &ssid_);
|
||||||
|
|
||||||
|
/// \brief Set access point passphrase
|
||||||
|
/// \param passphrase_ Passphrase
|
||||||
|
void setPassphrase (std::string const &passphrase_);
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FtpConfig ();
|
FtpConfig ();
|
||||||
|
|
||||||
|
#ifndef NDS
|
||||||
|
/// \brief Mutex
|
||||||
|
mutable platform::Mutex m_lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief Username
|
/// \brief Username
|
||||||
std::string m_user;
|
std::string m_user;
|
||||||
|
|
||||||
@ -97,4 +134,15 @@ private:
|
|||||||
/// \brief Whether to get mtime
|
/// \brief Whether to get mtime
|
||||||
bool m_getMTime = true;
|
bool m_getMTime = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
/// \brief Whether to enable access point
|
||||||
|
bool m_enableAP = false;
|
||||||
|
|
||||||
|
/// \brief Access point SSID
|
||||||
|
std::string m_ssid = "ftpd";
|
||||||
|
|
||||||
|
/// \brief Access point passphrase
|
||||||
|
std::string m_passphrase;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -67,6 +67,7 @@ private:
|
|||||||
/// \brief Handle when network is lost
|
/// \brief Handle when network is lost
|
||||||
void handleNetworkLost ();
|
void handleNetworkLost ();
|
||||||
|
|
||||||
|
#ifndef CLASSIC
|
||||||
/// \brief Show menu in the current window
|
/// \brief Show menu in the current window
|
||||||
void showMenu ();
|
void showMenu ();
|
||||||
|
|
||||||
@ -75,6 +76,7 @@ private:
|
|||||||
|
|
||||||
/// \brief Show about window
|
/// \brief Show about window
|
||||||
void showAbout ();
|
void showAbout ();
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief Server loop
|
/// \brief Server loop
|
||||||
void loop ();
|
void loop ();
|
||||||
@ -108,6 +110,12 @@ private:
|
|||||||
#ifndef CLASSIC
|
#ifndef CLASSIC
|
||||||
/// \brief Whether to show settings menu
|
/// \brief Whether to show settings menu
|
||||||
bool m_showSettings = false;
|
bool m_showSettings = false;
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
/// \brief Whether to show access point menu
|
||||||
|
bool m_showAP = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief Whether to show about window
|
/// \brief Whether to show about window
|
||||||
bool m_showAbout = false;
|
bool m_showAbout = false;
|
||||||
|
|
||||||
@ -124,5 +132,19 @@ private:
|
|||||||
/// \brief getMTime setting
|
/// \brief getMTime setting
|
||||||
bool m_getMTimeSetting;
|
bool m_getMTimeSetting;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
/// \brief Whether an error occurred enabling access point
|
||||||
|
std::atomic<bool> m_apError = false;
|
||||||
|
|
||||||
|
/// \brief Enable access point setting
|
||||||
|
bool m_enableAPSetting;
|
||||||
|
|
||||||
|
/// \brief Access point SSID setting
|
||||||
|
std::string m_ssidSetting;
|
||||||
|
|
||||||
|
/// \brief Access point passphrase setting
|
||||||
|
std::string m_passphraseSetting;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "sockAddr.h"
|
||||||
|
|
||||||
#if defined(NDS)
|
#if defined(NDS)
|
||||||
#include <nds.h>
|
#include <nds.h>
|
||||||
#elif defined(_3DS)
|
#elif defined(_3DS)
|
||||||
@ -44,9 +46,31 @@ namespace platform
|
|||||||
/// \brief Initialize platform
|
/// \brief Initialize platform
|
||||||
bool init ();
|
bool init ();
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
/// \brief Enable access point
|
||||||
|
/// \param enable_ Whether to enable access point
|
||||||
|
/// \param ssid_ SSID
|
||||||
|
/// \param passphrase_ Passphrase
|
||||||
|
bool enableAP (bool enable_, std::string const &ssid_, std::string const &passphrase_);
|
||||||
|
|
||||||
|
/// \brief Check if SSID is valid
|
||||||
|
/// \param ssid_ SSID to check
|
||||||
|
/// \returns empty string on success, error message on failure
|
||||||
|
char const *validateSSID (std::string const &ssid_);
|
||||||
|
|
||||||
|
/// \brief Check if passphrase is valid
|
||||||
|
/// \param passphrase_ Passphrase to check
|
||||||
|
/// \returns empty string on success, error message on failure
|
||||||
|
char const *validatePassphrase (std::string const &passphrase_);
|
||||||
|
#endif
|
||||||
|
|
||||||
/// \brief Whether network is visible
|
/// \brief Whether network is visible
|
||||||
bool networkVisible ();
|
bool networkVisible ();
|
||||||
|
|
||||||
|
/// \brief Get network address
|
||||||
|
/// \param[out] addr_ Network address
|
||||||
|
bool networkAddress (SockAddr &addr_);
|
||||||
|
|
||||||
/// \brief Platform loop
|
/// \brief Platform loop
|
||||||
bool loop ();
|
bool loop ();
|
||||||
|
|
||||||
|
@ -94,8 +94,12 @@ public:
|
|||||||
/// \brief Address port
|
/// \brief Address port
|
||||||
std::uint16_t port () const;
|
std::uint16_t port () const;
|
||||||
|
|
||||||
|
/// \brief Set address port
|
||||||
|
/// \param port_ Port to set
|
||||||
|
bool setPort (std::uint16_t port_);
|
||||||
|
|
||||||
/// \brief Address name
|
/// \brief Address name
|
||||||
/// \param buffer_
|
/// \param buffer_ Buffer to hold name
|
||||||
/// \param size_ Size of buffer_
|
/// \param size_ Size of buffer_
|
||||||
/// \retval buffer_ success
|
/// \retval buffer_ success
|
||||||
/// \retval nullptr failure
|
/// \retval nullptr failure
|
||||||
|
@ -165,7 +165,7 @@ void handleAPTHook (APT_HookType const type_, void *const param_)
|
|||||||
bool getNetworkVisibility ()
|
bool getNetworkVisibility ()
|
||||||
{
|
{
|
||||||
// serialize ac:u access from multiple threads
|
// serialize ac:u access from multiple threads
|
||||||
auto lock = std::scoped_lock (s_acuFence);
|
auto lock = std::lock_guard (s_acuFence);
|
||||||
|
|
||||||
// get wifi status
|
// get wifi status
|
||||||
std::uint32_t wifi = 0;
|
std::uint32_t wifi = 0;
|
||||||
@ -428,6 +428,16 @@ bool platform::networkVisible ()
|
|||||||
return getNetworkVisibility ();
|
return getNetworkVisibility ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool platform::networkAddress (SockAddr &addr_)
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = gethostid ();
|
||||||
|
|
||||||
|
addr_ = addr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool platform::loop ()
|
bool platform::loop ()
|
||||||
{
|
{
|
||||||
if (!aptMainLoop ())
|
if (!aptMainLoop ())
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -162,6 +163,21 @@ UniqueFtpConfig FtpConfig::load (char const *const path_)
|
|||||||
else
|
else
|
||||||
error ("Invalid value for mtime: %s\n", val.c_str ());
|
error ("Invalid value for mtime: %s\n", val.c_str ());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
else if (key == "ap")
|
||||||
|
{
|
||||||
|
if (val == "0")
|
||||||
|
config->m_enableAP = false;
|
||||||
|
else if (val == "1")
|
||||||
|
config->m_enableAP = true;
|
||||||
|
else
|
||||||
|
error ("Invalid value for ap: %s\n", val.c_str ());
|
||||||
|
}
|
||||||
|
else if (key == "ssid")
|
||||||
|
config->m_ssid = val;
|
||||||
|
else if (key == "passphrase")
|
||||||
|
config->m_passphrase = val;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +186,13 @@ UniqueFtpConfig FtpConfig::load (char const *const path_)
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDS
|
||||||
|
std::lock_guard<platform::Mutex> FtpConfig::lockGuard ()
|
||||||
|
{
|
||||||
|
return std::lock_guard<platform::Mutex> (m_lock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool FtpConfig::save (char const *const path_)
|
bool FtpConfig::save (char const *const path_)
|
||||||
{
|
{
|
||||||
if (!mkdirParent (path_))
|
if (!mkdirParent (path_))
|
||||||
@ -189,6 +212,14 @@ bool FtpConfig::save (char const *const path_)
|
|||||||
std::fprintf (fp, "mtime=%u\n", m_getMTime);
|
std::fprintf (fp, "mtime=%u\n", m_getMTime);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
std::fprintf (fp, "ap=%u\n", m_enableAP);
|
||||||
|
if (!m_ssid.empty ())
|
||||||
|
std::fprintf (fp, "ssid=%s\n", m_ssid.c_str ());
|
||||||
|
if (!m_passphrase.empty ())
|
||||||
|
std::fprintf (fp, "passphrase=%s\n", m_passphrase.c_str ());
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,6 +245,23 @@ bool FtpConfig::getMTime () const
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
bool FtpConfig::enableAP () const
|
||||||
|
{
|
||||||
|
return m_enableAP;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const &FtpConfig::ssid () const
|
||||||
|
{
|
||||||
|
return m_ssid;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const &FtpConfig::passphrase () const
|
||||||
|
{
|
||||||
|
return m_passphrase;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void FtpConfig::setUser (std::string const &user_)
|
void FtpConfig::setUser (std::string const &user_)
|
||||||
{
|
{
|
||||||
m_user = user_.substr (0, user_.find_first_of ('\0'));
|
m_user = user_.substr (0, user_.find_first_of ('\0'));
|
||||||
@ -255,3 +303,20 @@ void FtpConfig::setGetMTime (bool const getMTime_)
|
|||||||
m_getMTime = getMTime_;
|
m_getMTime = getMTime_;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
void FtpConfig::setEnableAP (bool const enable_)
|
||||||
|
{
|
||||||
|
m_enableAP = enable_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FtpConfig::setSSID (std::string const &ssid_)
|
||||||
|
{
|
||||||
|
m_ssid = ssid_.substr (0, ssid_.find_first_of ('\0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FtpConfig::setPassphrase (std::string const &passphrase_)
|
||||||
|
{
|
||||||
|
m_passphrase = passphrase_.substr (0, passphrase_.find_first_of ('\0'));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@ -36,10 +36,12 @@
|
|||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <string_view>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
@ -49,7 +51,7 @@ using namespace std::chrono_literals;
|
|||||||
#define LOCKED(x) \
|
#define LOCKED(x) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
auto const lock = std::scoped_lock (m_lock); \
|
auto const lock = std::lock_guard (m_lock); \
|
||||||
x; \
|
x; \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
@ -95,7 +97,7 @@ void FtpServer::draw ()
|
|||||||
{
|
{
|
||||||
char port[7];
|
char port[7];
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto lock = std::scoped_lock (m_lock);
|
auto const lock = std::lock_guard (m_lock);
|
||||||
#endif
|
#endif
|
||||||
if (m_socket)
|
if (m_socket)
|
||||||
std::sprintf (port, ":%u", m_socket->sockName ().port ());
|
std::sprintf (port, ":%u", m_socket->sockName ().port ());
|
||||||
@ -120,7 +122,7 @@ void FtpServer::draw ()
|
|||||||
|
|
||||||
{
|
{
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto const lock = std::scoped_lock (s_lock);
|
auto const lock = std::lock_guard (s_lock);
|
||||||
#endif
|
#endif
|
||||||
if (!s_freeSpace.empty ())
|
if (!s_freeSpace.empty ())
|
||||||
{
|
{
|
||||||
@ -134,7 +136,7 @@ void FtpServer::draw ()
|
|||||||
|
|
||||||
{
|
{
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto lock = std::scoped_lock (m_lock);
|
auto const lock = std::lock_guard (m_lock);
|
||||||
#endif
|
#endif
|
||||||
consoleSelect (&g_sessionConsole);
|
consoleSelect (&g_sessionConsole);
|
||||||
std::fputs ("\x1b[2J", stdout);
|
std::fputs ("\x1b[2J", stdout);
|
||||||
@ -164,7 +166,7 @@ void FtpServer::draw ()
|
|||||||
char title[64];
|
char title[64];
|
||||||
|
|
||||||
{
|
{
|
||||||
auto const serverLock = std::scoped_lock (m_lock);
|
auto const serverLock = std::lock_guard (m_lock);
|
||||||
std::snprintf (title,
|
std::snprintf (title,
|
||||||
sizeof (title),
|
sizeof (title),
|
||||||
STATUS_STRING " %s###ftpd",
|
STATUS_STRING " %s###ftpd",
|
||||||
@ -210,7 +212,7 @@ void FtpServer::draw ()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
auto lock = std::scoped_lock (m_lock);
|
auto const lock = std::lock_guard (m_lock);
|
||||||
for (auto &session : m_sessions)
|
for (auto &session : m_sessions)
|
||||||
session->draw ();
|
session->draw ();
|
||||||
}
|
}
|
||||||
@ -231,7 +233,7 @@ UniqueFtpServer FtpServer::create ()
|
|||||||
std::string FtpServer::getFreeSpace ()
|
std::string FtpServer::getFreeSpace ()
|
||||||
{
|
{
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto const lock = std::scoped_lock (s_lock);
|
auto const lock = std::lock_guard (s_lock);
|
||||||
#endif
|
#endif
|
||||||
return s_freeSpace;
|
return s_freeSpace;
|
||||||
}
|
}
|
||||||
@ -249,7 +251,7 @@ void FtpServer::updateFreeSpace ()
|
|||||||
auto freeSpace = fs::printSize (static_cast<std::uint64_t> (st.f_bsize) * st.f_bfree);
|
auto freeSpace = fs::printSize (static_cast<std::uint64_t> (st.f_bsize) * st.f_bfree);
|
||||||
|
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto const lock = std::scoped_lock (s_lock);
|
auto const lock = std::lock_guard (s_lock);
|
||||||
#endif
|
#endif
|
||||||
if (freeSpace != s_freeSpace)
|
if (freeSpace != s_freeSpace)
|
||||||
s_freeSpace = std::move (freeSpace);
|
s_freeSpace = std::move (freeSpace);
|
||||||
@ -262,22 +264,26 @@ std::time_t FtpServer::startTime ()
|
|||||||
|
|
||||||
void FtpServer::handleNetworkFound ()
|
void FtpServer::handleNetworkFound ()
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
SockAddr addr;
|
||||||
addr.sin_family = AF_INET;
|
if (!platform::networkAddress (addr))
|
||||||
#if defined(NDS)
|
return;
|
||||||
addr.sin_addr = Wifi_GetIPInfo (nullptr, nullptr, nullptr, nullptr);
|
|
||||||
#elif defined(_3DS) || defined(__SWITCH__)
|
std::uint16_t port;
|
||||||
addr.sin_addr.s_addr = gethostid ();
|
|
||||||
#else
|
{
|
||||||
addr.sin_addr.s_addr = INADDR_ANY;
|
#ifndef NDS
|
||||||
|
auto const lock = m_config->lockGuard ();
|
||||||
#endif
|
#endif
|
||||||
addr.sin_port = htons (m_config->port ());
|
port = m_config->port ();
|
||||||
|
}
|
||||||
|
|
||||||
|
addr.setPort (port);
|
||||||
|
|
||||||
auto socket = Socket::create ();
|
auto socket = Socket::create ();
|
||||||
if (!socket)
|
if (!socket)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_config->port () != 0 && !socket->setReuseAddress (true))
|
if (port != 0 && !socket->setReuseAddress (true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!socket->bind (addr))
|
if (!socket->bind (addr))
|
||||||
@ -290,7 +296,7 @@ void FtpServer::handleNetworkFound ()
|
|||||||
auto const name = sockName.name ();
|
auto const name = sockName.name ();
|
||||||
|
|
||||||
m_name.resize (std::strlen (name) + 3 + 5);
|
m_name.resize (std::strlen (name) + 3 + 5);
|
||||||
m_name.resize (std::sprintf (&m_name[0], "[%s]:%u", name, sockName.port ()));
|
m_name.resize (std::sprintf (m_name.data (), "[%s]:%u", name, sockName.port ()));
|
||||||
|
|
||||||
info ("Started server at %s\n", m_name.c_str ());
|
info ("Started server at %s\n", m_name.c_str ());
|
||||||
|
|
||||||
@ -314,9 +320,9 @@ void FtpServer::handleNetworkLost ()
|
|||||||
info ("Stopped server at %s\n", m_name.c_str ());
|
info ("Stopped server at %s\n", m_name.c_str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CLASSIC
|
||||||
void FtpServer::showMenu ()
|
void FtpServer::showMenu ()
|
||||||
{
|
{
|
||||||
#ifndef CLASSIC
|
|
||||||
auto const prevShowSettings = m_showSettings;
|
auto const prevShowSettings = m_showSettings;
|
||||||
auto const prevShowAbout = m_showAbout;
|
auto const prevShowAbout = m_showAbout;
|
||||||
|
|
||||||
@ -343,6 +349,10 @@ void FtpServer::showMenu ()
|
|||||||
{
|
{
|
||||||
if (!prevShowSettings)
|
if (!prevShowSettings)
|
||||||
{
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config->lockGuard ();
|
||||||
|
#endif
|
||||||
|
|
||||||
m_userSetting = m_config->user ();
|
m_userSetting = m_config->user ();
|
||||||
m_userSetting.resize (32);
|
m_userSetting.resize (32);
|
||||||
|
|
||||||
@ -355,7 +365,16 @@ void FtpServer::showMenu ()
|
|||||||
m_getMTimeSetting = m_config->getMTime ();
|
m_getMTimeSetting = m_config->getMTime ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
info ("Open \"Settings\" popup\n");
|
#ifdef __SWITCH__
|
||||||
|
m_enableAPSetting = m_config->enableAP ();
|
||||||
|
|
||||||
|
m_ssidSetting = m_config->ssid ();
|
||||||
|
m_ssidSetting.resize (19);
|
||||||
|
|
||||||
|
m_passphraseSetting = m_config->passphrase ();
|
||||||
|
m_passphraseSetting.resize (63);
|
||||||
|
#endif
|
||||||
|
|
||||||
ImGui::OpenPopup ("Settings");
|
ImGui::OpenPopup ("Settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +392,6 @@ void FtpServer::showMenu ()
|
|||||||
|
|
||||||
void FtpServer::showSettings ()
|
void FtpServer::showSettings ()
|
||||||
{
|
{
|
||||||
#ifndef CLASSIC
|
|
||||||
#ifdef _3DS
|
#ifdef _3DS
|
||||||
auto const &io = ImGui::GetIO ();
|
auto const &io = ImGui::GetIO ();
|
||||||
auto const width = io.DisplaySize.x;
|
auto const width = io.DisplaySize.x;
|
||||||
@ -388,11 +406,13 @@ void FtpServer::showSettings ()
|
|||||||
if (ImGui::BeginPopupModal ("Settings", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
if (ImGui::BeginPopupModal ("Settings", nullptr, ImGuiWindowFlags_AlwaysAutoResize))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ImGui::InputText (
|
ImGui::InputText ("User",
|
||||||
"User", &m_userSetting[0], m_userSetting.size (), ImGuiInputTextFlags_AutoSelectAll);
|
m_userSetting.data (),
|
||||||
|
m_userSetting.size (),
|
||||||
|
ImGuiInputTextFlags_AutoSelectAll);
|
||||||
|
|
||||||
ImGui::InputText ("Pass",
|
ImGui::InputText ("Pass",
|
||||||
&m_passSetting[0],
|
m_passSetting.data (),
|
||||||
m_passSetting.size (),
|
m_passSetting.size (),
|
||||||
ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_Password);
|
ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_Password);
|
||||||
|
|
||||||
@ -408,6 +428,26 @@ void FtpServer::showSettings ()
|
|||||||
ImGui::Checkbox ("Get mtime", &m_getMTimeSetting);
|
ImGui::Checkbox ("Get mtime", &m_getMTimeSetting);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
ImGui::Checkbox ("Enable Access Point", &m_enableAPSetting);
|
||||||
|
|
||||||
|
ImGui::InputText ("SSID",
|
||||||
|
m_ssidSetting.data (),
|
||||||
|
m_ssidSetting.size (),
|
||||||
|
ImGuiInputTextFlags_AutoSelectAll);
|
||||||
|
auto const ssidError = platform::validateSSID (m_ssidSetting);
|
||||||
|
if (ssidError)
|
||||||
|
ImGui::TextColored (ImVec4 (1.0f, 0.4f, 0.4f, 1.0f), ssidError);
|
||||||
|
|
||||||
|
ImGui::InputText ("Passphrase",
|
||||||
|
m_passphraseSetting.data (),
|
||||||
|
m_passphraseSetting.size (),
|
||||||
|
ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_Password);
|
||||||
|
auto const passphraseError = platform::validatePassphrase (m_passphraseSetting);
|
||||||
|
if (passphraseError)
|
||||||
|
ImGui::TextColored (ImVec4 (1.0f, 0.4f, 0.4f, 1.0f), passphraseError);
|
||||||
|
#endif
|
||||||
|
|
||||||
auto const apply = ImGui::Button ("Apply", ImVec2 (100, 0));
|
auto const apply = ImGui::Button ("Apply", ImVec2 (100, 0));
|
||||||
ImGui::SameLine ();
|
ImGui::SameLine ();
|
||||||
auto const save = ImGui::Button ("Save", ImVec2 (100, 0));
|
auto const save = ImGui::Button ("Save", ImVec2 (100, 0));
|
||||||
@ -419,6 +459,10 @@ void FtpServer::showSettings ()
|
|||||||
m_showSettings = false;
|
m_showSettings = false;
|
||||||
ImGui::CloseCurrentPopup ();
|
ImGui::CloseCurrentPopup ();
|
||||||
|
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config->lockGuard ();
|
||||||
|
#endif
|
||||||
|
|
||||||
m_config->setUser (m_userSetting);
|
m_config->setUser (m_userSetting);
|
||||||
m_config->setPass (m_passSetting);
|
m_config->setPass (m_passSetting);
|
||||||
m_config->setPort (m_portSetting);
|
m_config->setPort (m_portSetting);
|
||||||
@ -427,12 +471,24 @@ void FtpServer::showSettings ()
|
|||||||
m_config->setGetMTime (m_getMTimeSetting);
|
m_config->setGetMTime (m_getMTimeSetting);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
m_config->setEnableAP (m_enableAPSetting);
|
||||||
|
m_config->setSSID (m_ssidSetting);
|
||||||
|
m_config->setPassphrase (m_passphraseSetting);
|
||||||
|
m_apError = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
UniqueSocket socket;
|
UniqueSocket socket;
|
||||||
LOCKED (socket = std::move (m_socket));
|
LOCKED (socket = std::move (m_socket));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config->lockGuard ();
|
||||||
|
#endif
|
||||||
if (save && !m_config->save (FTPDCONFIG))
|
if (save && !m_config->save (FTPDCONFIG))
|
||||||
error ("Failed to save config\n");
|
error ("Failed to save config\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (apply || save || cancel)
|
if (apply || save || cancel)
|
||||||
{
|
{
|
||||||
@ -442,13 +498,10 @@ void FtpServer::showSettings ()
|
|||||||
|
|
||||||
ImGui::EndPopup ();
|
ImGui::EndPopup ();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FtpServer::showAbout ()
|
void FtpServer::showAbout ()
|
||||||
{
|
{
|
||||||
#ifndef CLASSIC
|
|
||||||
auto const &io = ImGui::GetIO ();
|
auto const &io = ImGui::GetIO ();
|
||||||
auto const width = io.DisplaySize.x;
|
auto const width = io.DisplaySize.x;
|
||||||
auto const height = io.DisplaySize.y;
|
auto const height = io.DisplaySize.y;
|
||||||
@ -539,13 +592,31 @@ void FtpServer::showAbout ()
|
|||||||
|
|
||||||
ImGui::EndPopup ();
|
ImGui::EndPopup ();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void FtpServer::loop ()
|
void FtpServer::loop ()
|
||||||
{
|
{
|
||||||
if (!m_socket)
|
if (!m_socket)
|
||||||
{
|
{
|
||||||
|
#ifdef __SWITCH__
|
||||||
|
if (!m_apError)
|
||||||
|
{
|
||||||
|
bool enable;
|
||||||
|
std::string ssid;
|
||||||
|
std::string passphrase;
|
||||||
|
|
||||||
|
{
|
||||||
|
auto const lock = m_config->lockGuard ();
|
||||||
|
enable = m_config->enableAP ();
|
||||||
|
ssid = m_config->ssid ();
|
||||||
|
passphrase = m_config->passphrase ();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_apError = !platform::enableAP (enable, ssid, passphrase);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (platform::networkVisible ())
|
if (platform::networkVisible ())
|
||||||
handleNetworkFound ();
|
handleNetworkFound ();
|
||||||
}
|
}
|
||||||
@ -582,7 +653,7 @@ void FtpServer::loop ()
|
|||||||
{
|
{
|
||||||
// remove dead sessions
|
// remove dead sessions
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto lock = std::scoped_lock (m_lock);
|
auto const lock = std::lock_guard (m_lock);
|
||||||
#endif
|
#endif
|
||||||
auto it = std::begin (m_sessions);
|
auto it = std::begin (m_sessions);
|
||||||
while (it != std::end (m_sessions))
|
while (it != std::end (m_sessions))
|
||||||
|
@ -50,7 +50,7 @@ using namespace std::chrono_literals;
|
|||||||
#define LOCKED(x) \
|
#define LOCKED(x) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
auto const lock = std::scoped_lock (m_lock); \
|
auto const lock = std::lock_guard (m_lock); \
|
||||||
x; \
|
x; \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
@ -293,10 +293,15 @@ FtpSession::FtpSession (FtpConfig &config_, UniqueSocket commandSocket_)
|
|||||||
m_mlstUnixMode (false),
|
m_mlstUnixMode (false),
|
||||||
m_devZero (false)
|
m_devZero (false)
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config.lockGuard ();
|
||||||
|
#endif
|
||||||
if (m_config.user ().empty ())
|
if (m_config.user ().empty ())
|
||||||
m_authorizedUser = true;
|
m_authorizedUser = true;
|
||||||
if (m_config.pass ().empty ())
|
if (m_config.pass ().empty ())
|
||||||
m_authorizedPass = true;
|
m_authorizedPass = true;
|
||||||
|
}
|
||||||
|
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
std::sprintf (buffer, "Session#%p", this);
|
std::sprintf (buffer, "Session#%p", this);
|
||||||
@ -313,7 +318,7 @@ FtpSession::FtpSession (FtpConfig &config_, UniqueSocket commandSocket_)
|
|||||||
bool FtpSession::dead ()
|
bool FtpSession::dead ()
|
||||||
{
|
{
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto const lock = std::scoped_lock (m_lock);
|
auto const lock = std::lock_guard (m_lock);
|
||||||
#endif
|
#endif
|
||||||
if (m_commandSocket || m_pasvSocket || m_dataSocket)
|
if (m_commandSocket || m_pasvSocket || m_dataSocket)
|
||||||
return false;
|
return false;
|
||||||
@ -324,7 +329,7 @@ bool FtpSession::dead ()
|
|||||||
void FtpSession::draw ()
|
void FtpSession::draw ()
|
||||||
{
|
{
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto const lock = std::scoped_lock (m_lock);
|
auto const lock = std::lock_guard (m_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CLASSIC
|
#ifdef CLASSIC
|
||||||
@ -610,7 +615,7 @@ void FtpSession::setState (State const state_, bool const closePasv_, bool const
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto lock = std::scoped_lock (m_lock);
|
auto lock = std::lock_guard (m_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_restartPosition = 0;
|
m_restartPosition = 0;
|
||||||
@ -1673,7 +1678,13 @@ bool FtpSession::listTransfer ()
|
|||||||
else if (m_xferDirMode == XferDirMode::NLST)
|
else if (m_xferDirMode == XferDirMode::NLST)
|
||||||
getmtime = false;
|
getmtime = false;
|
||||||
|
|
||||||
if (getmtime && m_config.getMTime ())
|
{
|
||||||
|
auto const lock = m_config.lockGuard ();
|
||||||
|
if (!m_config.getMTime ())
|
||||||
|
getmtime = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getmtime)
|
||||||
{
|
{
|
||||||
std::uint64_t mtime = 0;
|
std::uint64_t mtime = 0;
|
||||||
auto const rc = archive_getmtime (fullPath.c_str (), &mtime);
|
auto const rc = archive_getmtime (fullPath.c_str (), &mtime);
|
||||||
@ -2159,13 +2170,24 @@ void FtpSession::PASS (char const *args_)
|
|||||||
|
|
||||||
m_authorizedPass = false;
|
m_authorizedPass = false;
|
||||||
|
|
||||||
if (!m_config.user ().empty () && !m_authorizedUser)
|
std::string user;
|
||||||
|
std::string pass;
|
||||||
|
|
||||||
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config.lockGuard ();
|
||||||
|
#endif
|
||||||
|
user = m_config.user ();
|
||||||
|
pass = m_config.pass ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user.empty () && !m_authorizedUser)
|
||||||
{
|
{
|
||||||
sendResponse ("430 User not authorized\r\n");
|
sendResponse ("430 User not authorized\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_config.pass ().empty () || m_config.pass () == args_)
|
if (pass.empty () || pass == args_)
|
||||||
{
|
{
|
||||||
m_authorizedPass = true;
|
m_authorizedPass = true;
|
||||||
sendResponse ("230 OK\r\n");
|
sendResponse ("230 OK\r\n");
|
||||||
@ -2544,19 +2566,40 @@ void FtpSession::SITE (char const *args_)
|
|||||||
|
|
||||||
if (::strcasecmp (command.c_str (), "USER") == 0)
|
if (::strcasecmp (command.c_str (), "USER") == 0)
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config.lockGuard ();
|
||||||
|
#endif
|
||||||
m_config.setUser (arg);
|
m_config.setUser (arg);
|
||||||
|
}
|
||||||
|
|
||||||
sendResponse ("200 OK\r\n");
|
sendResponse ("200 OK\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (::strcasecmp (command.c_str (), "PASS") == 0)
|
else if (::strcasecmp (command.c_str (), "PASS") == 0)
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config.lockGuard ();
|
||||||
|
#endif
|
||||||
m_config.setPass (arg);
|
m_config.setPass (arg);
|
||||||
|
}
|
||||||
|
|
||||||
sendResponse ("200 OK\r\n");
|
sendResponse ("200 OK\r\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (::strcasecmp (command.c_str (), "PORT") == 0)
|
else if (::strcasecmp (command.c_str (), "PORT") == 0)
|
||||||
{
|
{
|
||||||
if (!m_config.setPort (arg))
|
bool error = false;
|
||||||
|
|
||||||
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config.lockGuard ();
|
||||||
|
#endif
|
||||||
|
error = !m_config.setPort (arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
{
|
{
|
||||||
sendResponse ("550 %s\r\n", std::strerror (errno));
|
sendResponse ("550 %s\r\n", std::strerror (errno));
|
||||||
return;
|
return;
|
||||||
@ -2569,9 +2612,19 @@ void FtpSession::SITE (char const *args_)
|
|||||||
else if (::strcasecmp (command.c_str (), "MTIME") == 0)
|
else if (::strcasecmp (command.c_str (), "MTIME") == 0)
|
||||||
{
|
{
|
||||||
if (arg == "0")
|
if (arg == "0")
|
||||||
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config.lockGuard ();
|
||||||
|
#endif
|
||||||
m_config.setGetMTime (false);
|
m_config.setGetMTime (false);
|
||||||
|
}
|
||||||
else if (arg == "1")
|
else if (arg == "1")
|
||||||
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config.lockGuard ();
|
||||||
|
#endif
|
||||||
m_config.setGetMTime (true);
|
m_config.setGetMTime (true);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sendResponse ("550 %s\r\n", std::strerror (EINVAL));
|
sendResponse ("550 %s\r\n", std::strerror (EINVAL));
|
||||||
@ -2581,7 +2634,16 @@ void FtpSession::SITE (char const *args_)
|
|||||||
#endif
|
#endif
|
||||||
else if (::strcasecmp (command.c_str (), "SAVE") == 0)
|
else if (::strcasecmp (command.c_str (), "SAVE") == 0)
|
||||||
{
|
{
|
||||||
if (!m_config.save (FTPDCONFIG))
|
bool error;
|
||||||
|
|
||||||
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config.lockGuard ();
|
||||||
|
#endif
|
||||||
|
error = !m_config.save (FTPDCONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
{
|
{
|
||||||
sendResponse ("550 %s\r\n", std::strerror (errno));
|
sendResponse ("550 %s\r\n", std::strerror (errno));
|
||||||
return;
|
return;
|
||||||
@ -2730,10 +2792,21 @@ void FtpSession::USER (char const *args_)
|
|||||||
|
|
||||||
m_authorizedUser = false;
|
m_authorizedUser = false;
|
||||||
|
|
||||||
if (m_config.user ().empty () || m_config.user () == args_)
|
std::string user;
|
||||||
|
std::string pass;
|
||||||
|
|
||||||
|
{
|
||||||
|
#ifndef NDS
|
||||||
|
auto const lock = m_config.lockGuard ();
|
||||||
|
#endif
|
||||||
|
user = m_config.user ();
|
||||||
|
pass = m_config.pass ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.empty () || user == args_)
|
||||||
{
|
{
|
||||||
m_authorizedUser = true;
|
m_authorizedUser = true;
|
||||||
if (m_config.pass ().empty ())
|
if (pass.empty ())
|
||||||
{
|
{
|
||||||
sendResponse ("230 OK\r\n");
|
sendResponse ("230 OK\r\n");
|
||||||
return;
|
return;
|
||||||
|
@ -169,6 +169,16 @@ bool platform::networkVisible ()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool platform::networkAddress (SockAddr &addr_)
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
addr_ = addr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool platform::loop ()
|
bool platform::loop ()
|
||||||
{
|
{
|
||||||
bool inactive;
|
bool inactive;
|
||||||
|
@ -79,7 +79,7 @@ platform::Mutex s_lock;
|
|||||||
void drawLog ()
|
void drawLog ()
|
||||||
{
|
{
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto const lock = std::scoped_lock (s_lock);
|
auto const lock = std::lock_guard (s_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CLASSIC
|
#ifdef CLASSIC
|
||||||
@ -211,7 +211,7 @@ void addLog (LogLevel const level_, char const *const fmt_, va_list ap_)
|
|||||||
std::vsnprintf (buffer, sizeof (buffer), fmt_, ap_);
|
std::vsnprintf (buffer, sizeof (buffer), fmt_, ap_);
|
||||||
|
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto const lock = std::scoped_lock (s_lock);
|
auto const lock = std::lock_guard (s_lock);
|
||||||
#endif
|
#endif
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// std::fprintf (stderr, "%s", s_prefix[level_]);
|
// std::fprintf (stderr, "%s", s_prefix[level_]);
|
||||||
@ -239,7 +239,7 @@ void addLog (LogLevel const level_, std::string_view const message_)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDS
|
#ifndef NDS
|
||||||
auto const lock = std::scoped_lock (s_lock);
|
auto const lock = std::lock_guard (s_lock);
|
||||||
#endif
|
#endif
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// std::fprintf (stderr, "%s", s_prefix[level_]);
|
// std::fprintf (stderr, "%s", s_prefix[level_]);
|
||||||
|
@ -73,6 +73,16 @@ bool platform::networkVisible ()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool platform::networkAddress (SockAddr &addr_)
|
||||||
|
{
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr = Wifi_GetIPInfo (nullptr, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
|
addr_ = addr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool platform::init ()
|
bool platform::init ()
|
||||||
{
|
{
|
||||||
sassert (fatInitDefault (), "Failed to initialize fat");
|
sassert (fatInitDefault (), "Failed to initialize fat");
|
||||||
|
@ -107,6 +107,26 @@ SockAddr::operator struct sockaddr const * () const
|
|||||||
return reinterpret_cast<struct sockaddr const *> (&m_addr);
|
return reinterpret_cast<struct sockaddr const *> (&m_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SockAddr::setPort (std::uint16_t const port_)
|
||||||
|
{
|
||||||
|
switch (m_addr.ss_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
reinterpret_cast<struct sockaddr_in *> (&m_addr)->sin_port = htons (port_);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#ifndef NO_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
reinterpret_cast<struct sockaddr_in6 *> (&m_addr)->sin6_port = htons (port_);
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
std::abort ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::uint16_t SockAddr::port () const
|
std::uint16_t SockAddr::port () const
|
||||||
{
|
{
|
||||||
switch (m_addr.ss_family)
|
switch (m_addr.ss_family)
|
||||||
|
@ -1372,7 +1372,7 @@ void updateKeyboard (HidKeyboardState const &kbState_, ImGuiIO &io_)
|
|||||||
io_.KeySuper = kbState_.modifiers & HidKeyboardModifier_Gui;
|
io_.KeySuper = kbState_.modifiers & HidKeyboardModifier_Gui;
|
||||||
|
|
||||||
for (int i = 0; i < 256; ++i)
|
for (int i = 0; i < 256; ++i)
|
||||||
io_.KeysDown[i] = kbState_.keys[i / 64] & (1 << (i % 64));
|
io_.KeysDown[i] = kbState_.keys[i / 64] & (1ul << (i % 64));
|
||||||
|
|
||||||
static enum {
|
static enum {
|
||||||
INACTIVE,
|
INACTIVE,
|
||||||
|
@ -53,13 +53,16 @@ namespace
|
|||||||
/// \brief Whether to power backlight
|
/// \brief Whether to power backlight
|
||||||
bool s_backlight = true;
|
bool s_backlight = true;
|
||||||
|
|
||||||
|
/// \brief Whether access point is active
|
||||||
|
bool s_activeAP = false;
|
||||||
|
|
||||||
|
/// \brief Access point SSID
|
||||||
|
std::string s_ssid;
|
||||||
|
|
||||||
/// \brief Applet hook cookie
|
/// \brief Applet hook cookie
|
||||||
AppletHookCookie s_appletHookCookie;
|
AppletHookCookie s_appletHookCookie;
|
||||||
|
|
||||||
#ifdef CLASSIC
|
#ifndef CLASSIC
|
||||||
/// \brief Host address
|
|
||||||
in_addr_t s_addr = 0;
|
|
||||||
#else
|
|
||||||
/// \brief Texture index
|
/// \brief Texture index
|
||||||
enum TextureIndex
|
enum TextureIndex
|
||||||
{
|
{
|
||||||
@ -503,6 +506,10 @@ void drawStatus ()
|
|||||||
{
|
{
|
||||||
TextureIndex netIcon = AIRPLANE_ICON;
|
TextureIndex netIcon = AIRPLANE_ICON;
|
||||||
|
|
||||||
|
if (s_activeAP)
|
||||||
|
netIcon = WIFI3_ICON;
|
||||||
|
else
|
||||||
|
{
|
||||||
NifmInternetConnectionType type;
|
NifmInternetConnectionType type;
|
||||||
std::uint32_t wifiStrength;
|
std::uint32_t wifiStrength;
|
||||||
NifmInternetConnectionStatus status;
|
NifmInternetConnectionStatus status;
|
||||||
@ -527,6 +534,7 @@ void drawStatus ()
|
|||||||
netIcon = WIFI_NONE_ICON;
|
netIcon = WIFI_NONE_ICON;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// draw network icon
|
// draw network icon
|
||||||
pos.x -= ICON_WIDTH + style.FramePadding.x;
|
pos.x -= ICON_WIDTH + style.FramePadding.x;
|
||||||
@ -547,6 +555,15 @@ void drawStatus ()
|
|||||||
pos, ImGui::GetColorU32 (ImGuiCol_Text), freeSpace.c_str ());
|
pos, ImGui::GetColorU32 (ImGuiCol_Text), freeSpace.c_str ());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s_activeAP)
|
||||||
|
{
|
||||||
|
auto const size = ImGui::CalcTextSize (s_ssid.c_str ());
|
||||||
|
auto const ssidPos = ImVec2 (
|
||||||
|
io.DisplaySize.x - style.FramePadding.x - size.x, 3 * style.FramePadding.y + size.y);
|
||||||
|
ImGui::GetForegroundDrawList ()->AddText (
|
||||||
|
ssidPos, ImGui::GetColorU32 (ImGuiCol_Text), s_ssid.c_str ());
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
// get current timestamp
|
// get current timestamp
|
||||||
char timeBuffer[16];
|
char timeBuffer[16];
|
||||||
@ -598,22 +615,154 @@ bool platform::init ()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool platform::enableAP (bool const enableAP_,
|
||||||
|
std::string const &ssid_,
|
||||||
|
std::string const &passphrase_)
|
||||||
|
{
|
||||||
|
if (s_activeAP == enableAP_)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (enableAP_)
|
||||||
|
{
|
||||||
|
auto const ssidError = validateSSID (ssid_);
|
||||||
|
if (ssidError)
|
||||||
|
{
|
||||||
|
error ("Access Point: %s\n", ssidError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const passphraseError = validatePassphrase (passphrase_);
|
||||||
|
if (passphraseError)
|
||||||
|
{
|
||||||
|
error ("Access Point: %s\n", passphraseError);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rc = lp2pInitialize (Lp2pServiceType_App);
|
||||||
|
if (R_FAILED (rc))
|
||||||
|
{
|
||||||
|
error ("lp2pInitialize: 0x%x\n", rc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Lp2pGroupInfo groupInfo;
|
||||||
|
lp2pCreateGroupInfo (&groupInfo);
|
||||||
|
|
||||||
|
// set SSID
|
||||||
|
lp2pGroupInfoSetServiceName (&groupInfo, ssid_.c_str ());
|
||||||
|
|
||||||
|
// enable WPA2-PSK
|
||||||
|
s8 flags = 0;
|
||||||
|
lp2pGroupInfoSetFlags (&groupInfo, &flags, 1);
|
||||||
|
|
||||||
|
// passphrase
|
||||||
|
rc = lp2pGroupInfoSetPassphrase (&groupInfo, passphrase_.c_str ());
|
||||||
|
if (R_FAILED (rc))
|
||||||
|
{
|
||||||
|
error ("lp2pGroupInfoSetPassphrase: 0x%x\n", rc);
|
||||||
|
lp2pExit ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create group
|
||||||
|
rc = lp2pCreateGroup (&groupInfo);
|
||||||
|
if (R_FAILED (rc))
|
||||||
|
{
|
||||||
|
error ("lp2pCreateGroup: 0x%x\n", rc);
|
||||||
|
lp2pExit ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = lp2pGetGroupInfo (&groupInfo);
|
||||||
|
if (R_FAILED (rc))
|
||||||
|
{
|
||||||
|
error ("lp2pGetGroupInfo: 0x%x\n", rc);
|
||||||
|
lp2pDestroyGroup ();
|
||||||
|
lp2pExit ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_ssid = std::string ("SSID: ") + groupInfo.service_name;
|
||||||
|
|
||||||
|
s_activeAP = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lp2pDestroyGroup ();
|
||||||
|
lp2pExit ();
|
||||||
|
s_activeAP = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const *platform::validateSSID (std::string const &ssid_)
|
||||||
|
{
|
||||||
|
auto const ssid = std::string_view (ssid_).substr (0, ssid_.find_first_of ('\0'));
|
||||||
|
|
||||||
|
if (ssid.size () > 19)
|
||||||
|
return "SSID too long";
|
||||||
|
|
||||||
|
for (auto const &c : ssid)
|
||||||
|
{
|
||||||
|
if (!std::isalnum (c) && c != '-')
|
||||||
|
return "SSID can only contain alphanumeric and -";
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const *platform::validatePassphrase (std::string const &passphrase_)
|
||||||
|
{
|
||||||
|
auto const passphrase =
|
||||||
|
std::string_view (passphrase_).substr (0, passphrase_.find_first_of ('\0'));
|
||||||
|
|
||||||
|
if (passphrase.size () < 8)
|
||||||
|
return "Passphrase too short";
|
||||||
|
else if (passphrase.size () > 63)
|
||||||
|
return "Passphrase too long";
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool platform::networkVisible ()
|
bool platform::networkVisible ()
|
||||||
{
|
{
|
||||||
|
if (s_activeAP)
|
||||||
|
return true;
|
||||||
|
|
||||||
NifmInternetConnectionType type;
|
NifmInternetConnectionType type;
|
||||||
std::uint32_t wifi;
|
std::uint32_t wifi;
|
||||||
NifmInternetConnectionStatus status;
|
NifmInternetConnectionStatus status;
|
||||||
if (R_FAILED (nifmGetInternetConnectionStatus (&type, &wifi, &status)))
|
if (R_FAILED (nifmGetInternetConnectionStatus (&type, &wifi, &status)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#ifdef CLASSIC
|
|
||||||
if (!s_addr)
|
|
||||||
s_addr = gethostid ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return status == NifmInternetConnectionStatus_Connected;
|
return status == NifmInternetConnectionStatus_Connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool platform::networkAddress (SockAddr &addr_)
|
||||||
|
{
|
||||||
|
if (s_activeAP)
|
||||||
|
{
|
||||||
|
Lp2pIpConfig ipConfig;
|
||||||
|
auto const rc = lp2pGetIpConfig (&ipConfig);
|
||||||
|
if (R_FAILED (rc))
|
||||||
|
{
|
||||||
|
error ("lp2pGetIpConfig: 0x%x\n", rc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_ = *reinterpret_cast<struct sockaddr_in *> (ipConfig.ip_addr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_addr.s_addr = gethostid ();
|
||||||
|
|
||||||
|
addr_ = addr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool platform::loop ()
|
bool platform::loop ()
|
||||||
{
|
{
|
||||||
if (!appletMainLoop ())
|
if (!appletMainLoop ())
|
||||||
@ -672,7 +821,7 @@ void platform::render ()
|
|||||||
#else
|
#else
|
||||||
ImGui::Render ();
|
ImGui::Render ();
|
||||||
|
|
||||||
auto &io = ImGui::GetIO ();
|
auto const &io = ImGui::GetIO ();
|
||||||
|
|
||||||
if (s_width != io.DisplaySize.x || s_height != io.DisplaySize.y)
|
if (s_width != io.DisplaySize.x || s_height != io.DisplaySize.y)
|
||||||
{
|
{
|
||||||
@ -726,6 +875,13 @@ void platform::exit ()
|
|||||||
|
|
||||||
if (!s_backlight)
|
if (!s_backlight)
|
||||||
appletSetLcdBacklightOffEnabled (false);
|
appletSetLcdBacklightOffEnabled (false);
|
||||||
|
|
||||||
|
if (s_activeAP)
|
||||||
|
{
|
||||||
|
lp2pDestroyGroup ();
|
||||||
|
lp2pExit ();
|
||||||
|
s_activeAP = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user