mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-21 07:55:06 +00:00
Compare commits
3 Commits
57164ad6c8
...
8fdcb51258
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fdcb51258 | ||
|
|
fa1418d37b | ||
|
|
d57b111f0e |
1
Data/data/service/Wifi/wifi.properties
Normal file
1
Data/data/service/Wifi/wifi.properties
Normal file
@ -0,0 +1 @@
|
||||
enableOnBoot=false
|
||||
@ -2,8 +2,6 @@
|
||||
|
||||
## Higher Priority
|
||||
|
||||
- Store encrypted WiFi credentials in `/data/app/wifi/x.ap.properties` (fixes problem with long SSIDs)
|
||||
- Move WiFi settings from flash to `/data/apps/wifi/wifi.properties` (just the "start on boot")
|
||||
- Move Development settings from flash to `/data/apps/development/development.properties` (just the "start on boot")
|
||||
- Move Display settings from flash to `/data/apps/display/display.properties`
|
||||
- App data directory should be automatically created (and then we can remove the custom code from Notes.cpp)
|
||||
|
||||
@ -28,6 +28,7 @@ enum class SystemEvent {
|
||||
|
||||
/** Value 0 mean "no subscription" */
|
||||
typedef uint32_t SystemEventSubscription;
|
||||
constexpr SystemEventSubscription NoSystemEventSubscription = 0U;
|
||||
|
||||
typedef std::function<void(SystemEvent)> OnSystemEvent;
|
||||
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
namespace tt::service::wifi {
|
||||
|
||||
void bootSplashInit();
|
||||
|
||||
}
|
||||
@ -1,8 +1,10 @@
|
||||
#include "Tactility/BootProperties.h"
|
||||
|
||||
#include <Tactility/LogEsp.h>
|
||||
#include <Tactility/Log.h>
|
||||
#include <Tactility/file/PropertiesFile.h>
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace tt {
|
||||
|
||||
constexpr auto* TAG = "BootProperties";
|
||||
@ -20,7 +22,7 @@ bool loadBootProperties(BootProperties& properties) {
|
||||
})) {
|
||||
TT_LOG_E(TAG, "Failed to load %s", PROPERTIES_FILE);
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
return !properties.launcherAppId.empty();
|
||||
}
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
|
||||
#include <unordered_map>
|
||||
#include <Tactility/file/File.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define TAG "app"
|
||||
|
||||
@ -16,20 +15,12 @@ typedef std::unordered_map<std::string, std::shared_ptr<AppManifest>> AppManifes
|
||||
static AppManifestMap app_manifest_map;
|
||||
static Mutex hash_mutex(Mutex::Type::Normal);
|
||||
|
||||
void ensureAppPathsExist(const AppManifest& manifest) {
|
||||
std::string path = "/data/app/" + manifest.id;
|
||||
if (!file::findOrCreateDirectory(path, 0777)) {
|
||||
TT_LOG_E(TAG, "Failed to create app directory: %s", path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void addApp(const AppManifest& manifest) {
|
||||
TT_LOG_I(TAG, "Registering manifest %s", manifest.id.c_str());
|
||||
|
||||
hash_mutex.lock();
|
||||
|
||||
if (!app_manifest_map.contains(manifest.id)) {
|
||||
ensureAppPathsExist(manifest);
|
||||
app_manifest_map[manifest.id] = std::make_shared<AppManifest>(manifest);
|
||||
} else {
|
||||
TT_LOG_E(TAG, "App id in use: %s", manifest.id.c_str());
|
||||
|
||||
@ -10,7 +10,8 @@
|
||||
#include "Tactility/lvgl/LvglSync.h"
|
||||
|
||||
#include <Tactility/Tactility.h>
|
||||
#include "Tactility/file/File.h"
|
||||
#include <Tactility/file/File.h>
|
||||
#include <Tactility/Log.h>
|
||||
#include <Tactility/StringUtils.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
@ -6,9 +6,6 @@
|
||||
#include <Tactility/Mutex.h>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <Tactility/app/AppInstance.h>
|
||||
#include <Tactility/file/File.h>
|
||||
|
||||
namespace tt::service {
|
||||
|
||||
@ -23,12 +20,6 @@ static ServiceInstanceMap service_instance_map;
|
||||
static Mutex manifest_mutex(Mutex::Type::Normal);
|
||||
static Mutex instance_mutex(Mutex::Type::Normal);
|
||||
|
||||
void ensureServerPathsExist(const ServiceManifest& manifest) {
|
||||
std::string path = "/data/service/" + manifest.id;
|
||||
if (!file::findOrCreateDirectory(path, 0777)) {
|
||||
TT_LOG_E(TAG, "Failed to create service directory: %s", path.c_str());
|
||||
}
|
||||
}
|
||||
void addService(std::shared_ptr<const ServiceManifest> manifest, bool autoStart) {
|
||||
assert(manifest != nullptr);
|
||||
// We'll move the manifest pointer, but we'll need to id later
|
||||
@ -38,7 +29,6 @@ void addService(std::shared_ptr<const ServiceManifest> manifest, bool autoStart)
|
||||
|
||||
manifest_mutex.lock();
|
||||
if (service_manifest_map[id] == nullptr) {
|
||||
ensureServerPathsExist(*manifest);
|
||||
service_manifest_map[id] = std::move(manifest);
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Service id in use: %s", id.c_str());
|
||||
|
||||
@ -108,7 +108,7 @@ static bool decrypt(const std::string& ssidInput, std::string& ssidOutput) {
|
||||
|
||||
bool contains(const std::string& ssid) {
|
||||
const auto file_path = getApPropertiesFilePath(ssid);
|
||||
return file::exists(file_path);
|
||||
return file::isFile(file_path);
|
||||
}
|
||||
|
||||
bool load(const std::string& ssid, WifiApSettings& apSettings) {
|
||||
@ -177,7 +177,7 @@ bool save(const WifiApSettings& apSettings) {
|
||||
|
||||
bool remove(const std::string& ssid) {
|
||||
const auto path = getApPropertiesFilePath(ssid);
|
||||
if (!file::exists(path)) {
|
||||
if (!file::isFile(path)) {
|
||||
return false;
|
||||
}
|
||||
return ::remove(path.c_str()) == 0;
|
||||
|
||||
115
Tactility/Source/service/wifi/WifiBootSplashInit.cpp
Normal file
115
Tactility/Source/service/wifi/WifiBootSplashInit.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
#include "Tactility/service/wifi/WifiBootSplashInit.h"
|
||||
|
||||
#include <Tactility/file/File.h>
|
||||
#include <Tactility/Log.h>
|
||||
|
||||
#include <string>
|
||||
#include <Tactility/file/PropertiesFile.h>
|
||||
#include <Tactility/service/wifi/WifiApSettings.h>
|
||||
|
||||
namespace tt::service::wifi {
|
||||
|
||||
constexpr auto* TAG = "WifiBootSplashInit";
|
||||
|
||||
// TODO: Avoid hard-coding this
|
||||
constexpr auto* AP_PROPERTIES_PATH = "/sdcard";
|
||||
|
||||
constexpr auto* AP_PROPERTIES_KEY_SSID = "ssid";
|
||||
constexpr auto* AP_PROPERTIES_KEY_PASSWORD = "password";
|
||||
constexpr auto* AP_PROPERTIES_KEY_AUTO_CONNECT = "autoConnect";
|
||||
constexpr auto* AP_PROPERTIES_KEY_CHANNEL = "channel";
|
||||
constexpr auto* AP_PROPERTIES_KEY_AUTO_REMOVE = "autoRemovePropertiesFile";
|
||||
|
||||
struct ApProperties {
|
||||
std::string ssid;
|
||||
std::string password;
|
||||
bool autoConnect;
|
||||
int32_t channel;
|
||||
bool autoRemovePropertiesFile;
|
||||
};
|
||||
|
||||
static void importWifiAp(const std::string& filePath) {
|
||||
std::map<std::string, std::string> map;
|
||||
if (!file::loadPropertiesFile(filePath, map)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto ssid_iterator = map.find(AP_PROPERTIES_KEY_SSID);
|
||||
if (ssid_iterator == map.end()) {
|
||||
TT_LOG_E(TAG, "%s is missing ssid", filePath.c_str());
|
||||
return;
|
||||
}
|
||||
const auto ssid = ssid_iterator->second;
|
||||
|
||||
if (!settings::contains(ssid)) {
|
||||
const auto password_iterator = map.find(AP_PROPERTIES_KEY_PASSWORD);
|
||||
const auto password = password_iterator == map.end() ? "" : password_iterator->second;
|
||||
|
||||
const auto auto_connect_iterator = map.find(AP_PROPERTIES_KEY_AUTO_CONNECT);
|
||||
const auto auto_connect = auto_connect_iterator == map.end() ? true : (auto_connect_iterator->second == "true");
|
||||
|
||||
const auto channel_iterator = map.find(AP_PROPERTIES_KEY_CHANNEL);
|
||||
const auto channel = channel_iterator == map.end() ? 0 : std::stoi(channel_iterator->second);
|
||||
|
||||
settings::WifiApSettings settings(
|
||||
ssid,
|
||||
password,
|
||||
auto_connect,
|
||||
channel
|
||||
);
|
||||
|
||||
if (!settings::save(settings)) {
|
||||
TT_LOG_E(TAG, "Failed to save settings for %s", ssid.c_str());
|
||||
} else {
|
||||
TT_LOG_I(TAG, "Imported %s from %s", ssid.c_str(), filePath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
const auto auto_remove_iterator = map.find(AP_PROPERTIES_KEY_AUTO_REMOVE);
|
||||
if (auto_remove_iterator != map.end() && auto_remove_iterator->second == "true") {
|
||||
if (!remove(filePath.c_str())) {
|
||||
TT_LOG_E(TAG, "Failed to auto-remove %s", filePath.c_str());
|
||||
} else {
|
||||
TT_LOG_I(TAG, "Auto-removed %s", filePath.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bootSplashInit() {
|
||||
if (!file::isDirectory(AP_PROPERTIES_PATH)) {
|
||||
TT_LOG_I(TAG, "%s not available", AP_PROPERTIES_PATH);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<dirent> dirent_list;
|
||||
if (file::scandir(AP_PROPERTIES_PATH, dirent_list, [](const dirent* entry) {
|
||||
switch (entry->d_type) {
|
||||
case file::TT_DT_DIR:
|
||||
case file::TT_DT_CHR:
|
||||
case file::TT_DT_LNK:
|
||||
return -1;
|
||||
case file::TT_DT_REG:
|
||||
default: {
|
||||
std::string name = entry->d_name;
|
||||
if (name.ends_with(".ap.properties")) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}, nullptr) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dirent_list.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& dirent : dirent_list) {
|
||||
std::string absolute_path = std::format("{}/{}", AP_PROPERTIES_PATH, dirent.d_name);
|
||||
importWifiAp(absolute_path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -6,6 +6,7 @@
|
||||
#include "Tactility/service/ServiceContext.h"
|
||||
#include "Tactility/service/wifi/WifiGlobals.h"
|
||||
#include "Tactility/service/wifi/WifiSettings.h"
|
||||
#include "Tactility/service/wifi/WifiBootSplashInit.h"
|
||||
|
||||
#include <Tactility/kernel/SystemEvents.h>
|
||||
#include <Tactility/Timer.h>
|
||||
@ -68,6 +69,7 @@ public:
|
||||
bool pause_auto_connect = false; // Pause when manually disconnecting until manually connecting again
|
||||
bool connection_target_remember = false; // Whether to store the connection_target on successful connection or not
|
||||
esp_netif_ip_info_t ip_info;
|
||||
kernel::SystemEventSubscription bootEventSubscription = kernel::NoSystemEventSubscription;
|
||||
|
||||
RadioState getRadioState() const {
|
||||
auto lock = dataMutex.asScopedLock();
|
||||
@ -900,13 +902,17 @@ public:
|
||||
assert(wifi_singleton == nullptr);
|
||||
wifi_singleton = std::make_shared<Wifi>();
|
||||
|
||||
wifi_singleton->bootEventSubscription = kernel::subscribeSystemEvent(kernel::SystemEvent::BootSplash, [](auto) {
|
||||
bootSplashInit();
|
||||
});
|
||||
|
||||
wifi_singleton->autoConnectTimer = std::make_unique<Timer>(Timer::Type::Periodic, []() { onAutoConnectTimer(); });
|
||||
// We want to try and scan more often in case of startup or scan lock failure
|
||||
wifi_singleton->autoConnectTimer->start(std::min(2000, AUTO_SCAN_INTERVAL));
|
||||
|
||||
if (settings::shouldEnableOnBoot()) {
|
||||
TT_LOG_I(TAG, "Auto-enabling due to setting");
|
||||
getMainDispatcher().dispatch([]() { dispatchEnable(wifi_singleton); });
|
||||
getMainDispatcher().dispatch([] { dispatchEnable(wifi_singleton); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -66,7 +66,7 @@ bool isScanning() {
|
||||
return wifi->scan_active;
|
||||
}
|
||||
|
||||
void connect(const settings::WifiApSettings* ap, bool remember) {
|
||||
void connect(const settings::WifiApSettings& ap, bool remember) {
|
||||
assert(wifi);
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
@ -11,24 +11,15 @@ namespace tt::file {
|
||||
|
||||
/** File types for `dirent`'s `d_type`. */
|
||||
enum {
|
||||
TT_DT_UNKNOWN = 0,
|
||||
#define TT_DT_UNKNOWN TT_DT_UNKNOWN // Unknown type
|
||||
TT_DT_FIFO = 1,
|
||||
#define TT_DT_FIFO TT_DT_FIFO // Named pipe or FIFO
|
||||
TT_DT_CHR = 2,
|
||||
#define TT_DT_CHR TT_DT_CHR // Character device
|
||||
TT_DT_DIR = 4,
|
||||
#define TT_DT_DIR TT_DT_DIR // Directory
|
||||
TT_DT_BLK = 6,
|
||||
#define TT_DT_BLK TT_DT_BLK // Block device
|
||||
TT_DT_REG = 8,
|
||||
#define TT_DT_REG TT_DT_REG // Regular file
|
||||
TT_DT_LNK = 10,
|
||||
#define TT_DT_LNK TT_DT_LNK // Symbolic link
|
||||
TT_DT_SOCK = 12,
|
||||
#define TT_DT_SOCK TT_DT_SOCK // Local-domain socket
|
||||
TT_DT_WHT = 14
|
||||
#define TT_DT_WHT TT_DT_WHT // Whiteout inodes
|
||||
TT_DT_UNKNOWN = 0, // Unknown type
|
||||
TT_DT_FIFO = 1, // Named pipe or FIFO
|
||||
TT_DT_CHR = 2, // Character device
|
||||
TT_DT_DIR = 4, // Directory
|
||||
TT_DT_BLK = 6, // Block device
|
||||
TT_DT_REG = 8, // Regular file
|
||||
TT_DT_LNK = 10, // Symbolic link
|
||||
TT_DT_SOCK = 12, // Local-domain socket
|
||||
TT_DT_WHT = 14 // Whiteout inodes
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -92,7 +83,9 @@ bool direntSortAlphaAndType(const dirent& left, const dirent& right);
|
||||
/** A filter for filtering out "." and ".." */
|
||||
int direntFilterDotEntries(const dirent* entry);
|
||||
|
||||
bool exists(const std::string& path);
|
||||
bool isFile(const std::string& path);
|
||||
|
||||
bool isDirectory(const std::string& path);
|
||||
|
||||
/**
|
||||
* A scandir()-like implementation that works on ESP32.
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace tt::file {
|
||||
|
||||
@ -208,8 +209,13 @@ bool findOrCreateDirectory(std::string path, mode_t mode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool exists(const std::string& path) {
|
||||
bool isFile(const std::string& path) {
|
||||
return access(path.c_str(), F_OK) == 0;
|
||||
}
|
||||
|
||||
bool isDirectory(const std::string& path) {
|
||||
struct stat stat_result;
|
||||
return stat(path.c_str(), &stat_result) == 0 && S_ISDIR(stat_result.st_mode);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user