181 lines
5.3 KiB
C++
181 lines
5.3 KiB
C++
#include "WifiManage.h"
|
|
|
|
#include "app/App.h"
|
|
#include "app/wificonnect/WifiConnectBundle.h"
|
|
#include "TactilityCore.h"
|
|
#include "service/loader/Loader.h"
|
|
#include "service/wifi/WifiSettings.h"
|
|
#include "lvgl/LvglSync.h"
|
|
#include "WifiManageStateUpdating.h"
|
|
#include "WifiManageView.h"
|
|
|
|
namespace tt::app::wifimanage {
|
|
|
|
#define TAG "wifi_manage"
|
|
|
|
// Forward declarations
|
|
static void event_callback(const void* message, void* context);
|
|
|
|
static void on_connect(const char* ssid) {
|
|
service::wifi::settings::WifiApSettings settings;
|
|
if (service::wifi::settings::load(ssid, &settings)) {
|
|
TT_LOG_I(TAG, "Connecting with known credentials");
|
|
service::wifi::connect(&settings, false);
|
|
} else {
|
|
TT_LOG_I(TAG, "Starting connection dialog");
|
|
Bundle bundle;
|
|
bundle.putString(WIFI_CONNECT_PARAM_SSID, ssid);
|
|
bundle.putString(WIFI_CONNECT_PARAM_PASSWORD, "");
|
|
service::loader::start_app("WifiConnect", false, bundle);
|
|
}
|
|
}
|
|
|
|
static void on_disconnect() {
|
|
service::wifi::disconnect();
|
|
}
|
|
|
|
static void on_wifi_toggled(bool enabled) {
|
|
service::wifi::set_enabled(enabled);
|
|
}
|
|
|
|
static WifiManage* wifi_manage_alloc() {
|
|
auto* wifi = static_cast<WifiManage*>(malloc(sizeof(WifiManage)));
|
|
|
|
wifi->wifi_subscription = nullptr;
|
|
wifi->mutex = tt_mutex_alloc(MutexTypeNormal);
|
|
wifi->state = (WifiManageState) {
|
|
.scanning = service::wifi::is_scanning(),
|
|
.radio_state = service::wifi::get_radio_state(),
|
|
.connect_ssid = { 0 },
|
|
.ap_records = { },
|
|
.ap_records_count = 0
|
|
};
|
|
wifi->view_enabled = false;
|
|
wifi->bindings = (WifiManageBindings) {
|
|
.on_wifi_toggled = &on_wifi_toggled,
|
|
.on_connect_ssid = &on_connect,
|
|
.on_disconnect = &on_disconnect
|
|
};
|
|
|
|
return wifi;
|
|
}
|
|
|
|
static void wifi_manage_free(WifiManage* wifi) {
|
|
tt_mutex_free(wifi->mutex);
|
|
|
|
free(wifi);
|
|
}
|
|
|
|
void lock(WifiManage* wifi) {
|
|
tt_assert(wifi);
|
|
tt_assert(wifi->mutex);
|
|
tt_mutex_acquire(wifi->mutex, TtWaitForever);
|
|
}
|
|
|
|
void unlock(WifiManage* wifi) {
|
|
tt_assert(wifi);
|
|
tt_assert(wifi->mutex);
|
|
tt_mutex_release(wifi->mutex);
|
|
}
|
|
|
|
void request_view_update(WifiManage* wifi) {
|
|
lock(wifi);
|
|
if (wifi->view_enabled) {
|
|
if (lvgl::lock(1000)) {
|
|
view_update(&wifi->view, &wifi->bindings, &wifi->state);
|
|
lvgl::unlock();
|
|
} else {
|
|
TT_LOG_E(TAG, "failed to lock lvgl");
|
|
}
|
|
}
|
|
unlock(wifi);
|
|
}
|
|
|
|
static void wifi_manage_event_callback(const void* message, void* context) {
|
|
auto* event = (service::wifi::WifiEvent*)message;
|
|
auto* wifi = (WifiManage*)context;
|
|
TT_LOG_I(TAG, "Update with state %d", service::wifi::get_radio_state());
|
|
state_set_radio_state(wifi, service::wifi::get_radio_state());
|
|
switch (event->type) {
|
|
case tt::service::wifi::WifiEventTypeScanStarted:
|
|
state_set_scanning(wifi, true);
|
|
break;
|
|
case tt::service::wifi::WifiEventTypeScanFinished:
|
|
state_set_scanning(wifi, false);
|
|
state_update_scanned_records(wifi);
|
|
break;
|
|
case tt::service::wifi::WifiEventTypeRadioStateOn:
|
|
if (!service::wifi::is_scanning()) {
|
|
service::wifi::scan();
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
request_view_update(wifi);
|
|
}
|
|
|
|
static void app_show(App app, lv_obj_t* parent) {
|
|
auto* wifi = (WifiManage*)tt_app_get_data(app);
|
|
|
|
PubSub* wifi_pubsub = service::wifi::get_pubsub();
|
|
wifi->wifi_subscription = tt_pubsub_subscribe(wifi_pubsub, &wifi_manage_event_callback, wifi);
|
|
|
|
// State update (it has its own locking)
|
|
state_set_radio_state(wifi, service::wifi::get_radio_state());
|
|
state_set_scanning(wifi, service::wifi::is_scanning());
|
|
state_update_scanned_records(wifi);
|
|
|
|
// View update
|
|
lock(wifi);
|
|
wifi->view_enabled = true;
|
|
strcpy((char*)wifi->state.connect_ssid, "Connected"); // TODO update with proper SSID
|
|
view_create(app, &wifi->view, &wifi->bindings, parent);
|
|
view_update(&wifi->view, &wifi->bindings, &wifi->state);
|
|
unlock(wifi);
|
|
|
|
service::wifi::WifiRadioState radio_state = service::wifi::get_radio_state();
|
|
bool can_scan = radio_state == service::wifi::WIFI_RADIO_ON ||
|
|
radio_state == service::wifi::WIFI_RADIO_CONNECTION_PENDING ||
|
|
radio_state == service::wifi::WIFI_RADIO_CONNECTION_ACTIVE;
|
|
if (can_scan && !service::wifi::is_scanning()) {
|
|
service::wifi::scan();
|
|
}
|
|
}
|
|
|
|
static void app_hide(App app) {
|
|
auto* wifi = (WifiManage*)tt_app_get_data(app);
|
|
lock(wifi);
|
|
PubSub* wifi_pubsub = service::wifi::get_pubsub();
|
|
tt_pubsub_unsubscribe(wifi_pubsub, wifi->wifi_subscription);
|
|
wifi->wifi_subscription = nullptr;
|
|
wifi->view_enabled = false;
|
|
unlock(wifi);
|
|
}
|
|
|
|
static void app_start(App app) {
|
|
WifiManage* wifi = wifi_manage_alloc();
|
|
tt_app_set_data(app, wifi);
|
|
}
|
|
|
|
static void app_stop(App app) {
|
|
auto* wifi = (WifiManage*)tt_app_get_data(app);
|
|
tt_assert(wifi != nullptr);
|
|
wifi_manage_free(wifi);
|
|
tt_app_set_data(app, nullptr);
|
|
}
|
|
|
|
extern const Manifest manifest = {
|
|
.id = "WifiManage",
|
|
.name = "Wi-Fi",
|
|
.icon = LV_SYMBOL_WIFI,
|
|
.type = TypeSettings,
|
|
.on_start = &app_start,
|
|
.on_stop = &app_stop,
|
|
.on_show = &app_show,
|
|
.on_hide = &app_hide
|
|
};
|
|
|
|
} // namespace
|