-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Expand file tree
/
Copy pathServerAPI.cpp
More file actions
98 lines (86 loc) · 2.73 KB
/
ServerAPI.cpp
File metadata and controls
98 lines (86 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "ServerAPI.h"
#include "Throttle.h"
#include "configuration.h"
#include <Arduino.h>
#define TCP_IDLE_TIMEOUT_MS (15 * 60 * 1000UL)
template <typename T>
ServerAPI<T>::ServerAPI(T &_client) : StreamAPI(&client), concurrency::OSThread("ServerAPI"), client(_client)
{
LOG_INFO("Incoming API connection");
}
template <typename T> ServerAPI<T>::~ServerAPI()
{
client.stop();
}
template <typename T> void ServerAPI<T>::close()
{
client.stop(); // drop tcp connection
StreamAPI::close();
}
/// Check the current underlying physical link to see if the client is currently connected
template <typename T> bool ServerAPI<T>::checkIsConnected()
{
return client.connected();
}
template <class T> int32_t ServerAPI<T>::runOnce()
{
if (client.connected()) {
if (lastContactMsec > 0 && !Throttle::isWithinTimespanMs(lastContactMsec, TCP_IDLE_TIMEOUT_MS)) {
LOG_WARN("TCP connection timeout, no data for %lu ms", (unsigned long)(millis() - lastContactMsec));
close();
enabled = false;
return 0;
}
return StreamAPI::runOncePart();
} else {
LOG_INFO("Client dropped connection, suspend API service");
enabled = false; // we no longer need to run
return 0;
}
}
template <class T, class U> APIServerPort<T, U>::APIServerPort(int port) : U(port), concurrency::OSThread("ApiServer") {}
template <class T, class U> void APIServerPort<T, U>::init()
{
U::begin();
}
template <class T, class U> int32_t APIServerPort<T, U>::runOnce()
{
if (openAPI && !openAPI->isClientConnected()) {
LOG_INFO("Cleaning up disconnected TCP API client");
delete openAPI;
openAPI = nullptr;
}
#ifdef ARCH_ESP32
#if ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(3, 0, 0)
auto client = U::accept();
#else
auto client = U::available();
#endif
#elif defined(ARCH_RP2040) || defined(ARCH_NRF52)
auto client = U::accept();
#else
auto client = U::available();
#endif
if (client) {
// Close any previous connection (see FIXME in header file)
if (openAPI) {
#if RAK_4631
// RAK13800 Ethernet requests periodically take more time
// This backoff addresses most cases keeping max wait < 1s
// Reconnections are delayed by full wait time
if (waitTime < 400) {
waitTime *= 2;
LOG_INFO("Previous TCP connection still open, try again in %dms", waitTime);
return waitTime;
}
#endif
LOG_INFO("Force close previous TCP connection");
delete openAPI;
}
openAPI = new T(client);
}
#if RAK_4631
waitTime = 100;
#endif
return 100; // only check occasionally for incoming connections
}