Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0077eb6

Browse files
authored
Merge pull request #130 from kasedy/ft-ap-improve
Do not shut down Access Point rapidly if users are connected. Wait until they disconnect.
2 parents 1e05546 + 8a71ff4 commit 0077eb6

File tree

8 files changed

+96
-52
lines changed

8 files changed

+96
-52
lines changed

interface/src/ap/APStatus.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,32 @@
11
import { Theme } from "@material-ui/core";
22
import { APStatus } from "./types";
33

4-
export const apStatusHighlight = ({ active }: APStatus, theme: Theme) => {
5-
return active ? theme.palette.success.main : theme.palette.info.main;
4+
const ACTIVE = 1;
5+
const INACTIVE = 2;
6+
const WAITING_CLIENTS_DISCONNECT = 3;
7+
8+
export const apStatusHighlight = ({ status }: APStatus, theme: Theme) => {
9+
switch (status) {
10+
case ACTIVE:
11+
return theme.palette.success.main;
12+
case INACTIVE:
13+
return theme.palette.info.main;
14+
case WAITING_CLIENTS_DISCONNECT:
15+
return theme.palette.warning.main;
16+
default:
17+
return theme.palette.error.main;
18+
}
619
}
720

8-
export const apStatus = ({ active }: APStatus) => {
9-
return active ? "Active" : "Inactive";
21+
export const apStatus = ({ status }: APStatus) => {
22+
switch (status) {
23+
case ACTIVE:
24+
return "Active";
25+
case INACTIVE:
26+
return "Inactive";
27+
case WAITING_CLIENTS_DISCONNECT:
28+
return "Waiting clients to disconnect";
29+
default:
30+
return "Unknown";
31+
}
1032
};

interface/src/ap/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export interface APStatus {
2-
active: boolean;
2+
status: number;
33
ip_address: string;
44
mac_address: string;
55
station_num: number;

lib/framework/APSettingsService.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,21 +34,23 @@ void APSettingsService::loop() {
3434

3535
void APSettingsService::manageAP() {
3636
WiFiMode_t currentWiFiMode = WiFi.getMode();
37-
if (_state.provisionMode == AP_MODE_ALWAYS ||
38-
(_state.provisionMode == AP_MODE_DISCONNECTED && WiFi.status() != WL_CONNECTED)) {
37+
APSettings state = getStateSnapshot();
38+
if (state.provisionMode == AP_MODE_ALWAYS ||
39+
(state.provisionMode == AP_MODE_DISCONNECTED && WiFi.status() != WL_CONNECTED)) {
3940
if (currentWiFiMode == WIFI_OFF || currentWiFiMode == WIFI_STA) {
4041
startAP();
4142
}
42-
} else {
43-
if (currentWiFiMode == WIFI_AP || currentWiFiMode == WIFI_AP_STA) {
44-
stopAP();
45-
}
43+
} else if ((currentWiFiMode == WIFI_AP || currentWiFiMode == WIFI_AP_STA)
44+
&& WiFi.softAPgetStationNum() == 0) {
45+
stopAP();
4646
}
4747
}
4848

4949
void APSettingsService::startAP() {
5050
Serial.println(F("Starting software access point"));
51-
WiFi.softAP(_state.ssid.c_str(), _state.password.c_str());
51+
APSettings state = getStateSnapshot();
52+
// WiFi.softAP owns the copy of ssid and passwords strings
53+
WiFi.softAP(state.ssid.c_str(), state.password.c_str());
5254
if (!_dnsServer) {
5355
IPAddress apIp = WiFi.softAPIP();
5456
Serial.print(F("Starting captive portal on "));
@@ -74,3 +76,10 @@ void APSettingsService::handleDNS() {
7476
_dnsServer->processNextRequest();
7577
}
7678
}
79+
80+
APSettings APSettingsService::getStateSnapshot() {
81+
beginTransaction();
82+
APSettings snapshot(_state);
83+
endTransaction();
84+
return snapshot;
85+
}

lib/framework/APSettingsService.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class APSettingsService : public StatefulService<APSettings> {
6464
void begin();
6565
void loop();
6666

67+
APSettings getStateSnapshot();
68+
6769
private:
6870
HttpEndpoint<APSettings> _httpEndpoint;
6971
FSPersistence<APSettings> _fsPersistence;

lib/framework/APStatus.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <APStatus.h>
22

3-
APStatus::APStatus(AsyncWebServer* server, SecurityManager* securityManager) {
3+
APStatus::APStatus(APSettingsService* apSettingsService, AsyncWebServer* server, SecurityManager* securityManager) :
4+
apSettingsService(apSettingsService) {
45
server->on(AP_STATUS_SERVICE_PATH,
56
HTTP_GET,
67
securityManager->wrapRequest(std::bind(&APStatus::apStatus, this, std::placeholders::_1),
@@ -12,7 +13,20 @@ void APStatus::apStatus(AsyncWebServerRequest* request) {
1213
JsonObject root = response->getRoot();
1314

1415
WiFiMode_t currentWiFiMode = WiFi.getMode();
15-
root["active"] = (currentWiFiMode == WIFI_AP || currentWiFiMode == WIFI_AP_STA);
16+
Status status;
17+
if ((currentWiFiMode & WIFI_AP) == 0) {
18+
status = INACTIVE;
19+
} else {
20+
uint8_t provisionMode = apSettingsService->getStateSnapshot().provisionMode;
21+
if (provisionMode == AP_MODE_ALWAYS
22+
|| (provisionMode == AP_MODE_DISCONNECTED && WiFi.status() != WL_CONNECTED)) {
23+
status = ACTIVE;
24+
} else {
25+
status = WAITING_CLIENTS_DISCONNECT;
26+
}
27+
}
28+
29+
root["status"] = (uint8_t) status;
1630
root["ip_address"] = WiFi.softAPIP().toString();
1731
root["mac_address"] = WiFi.softAPmacAddress();
1832
root["station_num"] = WiFi.softAPgetStationNum();

lib/framework/APStatus.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include <ArduinoJson.h>
1313
#include <AsyncJson.h>
14+
#include <APSettingsService.h>
1415
#include <ESPAsyncWebServer.h>
1516
#include <IPAddress.h>
1617
#include <SecurityManager.h>
@@ -19,8 +20,16 @@
1920
#define AP_STATUS_SERVICE_PATH "/rest/apStatus"
2021

2122
class APStatus {
23+
APSettingsService* apSettingsService;
24+
25+
enum Status {
26+
ACTIVE = 1,
27+
INACTIVE = 2,
28+
WAITING_CLIENTS_DISCONNECT = 3,
29+
};
30+
2231
public:
23-
APStatus(AsyncWebServer* server, SecurityManager* securityManager);
32+
APStatus(APSettingsService* apSettingsService, AsyncWebServer* server, SecurityManager* securityManager);
2433

2534
private:
2635
void apStatus(AsyncWebServerRequest* request);

lib/framework/ESP8266React.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ ESP8266React::ESP8266React(AsyncWebServer* server, FS* fs) :
1313
_wifiScanner(server, &_securitySettingsService),
1414
_wifiStatus(server, &_securitySettingsService),
1515
_ntpStatus(server, &_securitySettingsService),
16-
_apStatus(server, &_securitySettingsService),
16+
_apStatus(&_apSettingsService, server, &_securitySettingsService),
1717
_mqttStatus(server, &_mqttSettingsService, &_securitySettingsService),
1818
_systemStatus(server, &_securitySettingsService) {
1919
#ifdef PROGMEM_WWW

lib/framework/StatefulService.h

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -61,65 +61,41 @@ class StatefulService {
6161
}
6262

6363
void updateWithoutPropagation(std::function<void(T&)> callback) {
64-
#ifdef ESP32
65-
xSemaphoreTakeRecursive(_accessMutex, portMAX_DELAY);
66-
#endif
64+
beginTransaction();
6765
callback(_state);
68-
#ifdef ESP32
69-
xSemaphoreGiveRecursive(_accessMutex);
70-
#endif
66+
endTransaction();
7167
}
7268

7369
void updateWithoutPropagation(JsonObject& jsonObject, JsonDeserializer<T> deserializer) {
74-
#ifdef ESP32
75-
xSemaphoreTakeRecursive(_accessMutex, portMAX_DELAY);
76-
#endif
70+
beginTransaction();
7771
deserializer(jsonObject, _state);
78-
#ifdef ESP32
79-
xSemaphoreGiveRecursive(_accessMutex);
80-
#endif
72+
endTransaction();
8173
}
8274

8375
void update(std::function<void(T&)> callback, const String& originId) {
84-
#ifdef ESP32
85-
xSemaphoreTakeRecursive(_accessMutex, portMAX_DELAY);
86-
#endif
76+
beginTransaction();
8777
callback(_state);
8878
callUpdateHandlers(originId);
89-
#ifdef ESP32
90-
xSemaphoreGiveRecursive(_accessMutex);
91-
#endif
79+
endTransaction();
9280
}
9381

9482
void update(JsonObject& jsonObject, JsonDeserializer<T> deserializer, const String& originId) {
95-
#ifdef ESP32
96-
xSemaphoreTakeRecursive(_accessMutex, portMAX_DELAY);
97-
#endif
83+
beginTransaction();
9884
deserializer(jsonObject, _state);
9985
callUpdateHandlers(originId);
100-
#ifdef ESP32
101-
xSemaphoreGiveRecursive(_accessMutex);
102-
#endif
86+
endTransaction();
10387
}
10488

10589
void read(std::function<void(T&)> callback) {
106-
#ifdef ESP32
107-
xSemaphoreTakeRecursive(_accessMutex, portMAX_DELAY);
108-
#endif
90+
beginTransaction();
10991
callback(_state);
110-
#ifdef ESP32
111-
xSemaphoreGiveRecursive(_accessMutex);
112-
#endif
92+
endTransaction();
11393
}
11494

11595
void read(JsonObject& jsonObject, JsonSerializer<T> serializer) {
116-
#ifdef ESP32
117-
xSemaphoreTakeRecursive(_accessMutex, portMAX_DELAY);
118-
#endif
96+
beginTransaction();
11997
serializer(_state, jsonObject);
120-
#ifdef ESP32
121-
xSemaphoreGiveRecursive(_accessMutex);
122-
#endif
98+
endTransaction();
12399
}
124100

125101
void callUpdateHandlers(const String& originId) {
@@ -131,6 +107,18 @@ class StatefulService {
131107
protected:
132108
T _state;
133109

110+
inline void beginTransaction() {
111+
#ifdef ESP32
112+
xSemaphoreTakeRecursive(_accessMutex, portMAX_DELAY);
113+
#endif
114+
}
115+
116+
inline void endTransaction() {
117+
#ifdef ESP32
118+
xSemaphoreGiveRecursive(_accessMutex);
119+
#endif
120+
}
121+
134122
private:
135123
#ifdef ESP32
136124
SemaphoreHandle_t _accessMutex;

0 commit comments

Comments
 (0)