@@ -10,6 +10,9 @@ const char* const TAG = "GatewayConnectionManager";
1010#include " http/JsonAPI.h"
1111#include " Logging.h"
1212
13+ #include " SimpleMutex.h"
14+
15+ #include < atomic>
1316#include < unordered_map>
1417
1518//
@@ -34,25 +37,29 @@ const uint8_t FLAG_LINKED = 1 << 1;
3437
3538const uint8_t LINK_CODE_LENGTH = 6 ;
3639
37- static uint8_t s_flags = 0 ;
38- static int64_t s_lastAuthFailure = 0 ;
39- static int64_t s_lastConnectionAttempt = 0 ;
40+ static std::atomic<uint8_t > s_flags = 0 ;
41+ static std::atomic<int64_t > s_lastAuthFailure = 0 ;
42+ static std::atomic<int64_t > s_lastConnectionAttempt = 0 ;
43+ static OpenShock::SimpleMutex s_clientMutex;
4044static std::unique_ptr<OpenShock::GatewayClient> s_wsClient = nullptr ;
4145
4246static void evh_gotIP (arduino_event_t * event)
4347{
4448 (void )event;
4549
46- s_flags |= FLAG_HAS_IP;
50+ s_flags. fetch_or ( FLAG_HAS_IP, std::memory_order_relaxed) ;
4751 OS_LOGD (TAG, " Got IP address" );
4852}
4953
5054static void evh_wiFiDisconnected (arduino_event_t * event)
5155{
5256 (void )event;
5357
54- s_flags = FLAG_NONE;
55- s_wsClient = nullptr ;
58+ s_flags.store (FLAG_NONE, std::memory_order_relaxed);
59+ {
60+ OpenShock::ScopedLock lock__ (&s_clientMutex);
61+ s_wsClient = nullptr ;
62+ }
5663 OS_LOGD (TAG, " Lost IP address" );
5764}
5865
@@ -79,6 +86,7 @@ bool GatewayConnectionManager::Init()
7986
8087bool GatewayConnectionManager::IsConnected ()
8188{
89+ ScopedLock lock__ (&s_clientMutex);
8290 if (s_wsClient == nullptr ) {
8391 return false ;
8492 }
@@ -88,15 +96,18 @@ bool GatewayConnectionManager::IsConnected()
8896
8997bool GatewayConnectionManager::IsLinked ()
9098{
91- return (s_flags & FLAG_LINKED) != 0 ;
99+ return (s_flags. load (std::memory_order_relaxed) & FLAG_LINKED) != 0 ;
92100}
93101
94102AccountLinkResultCode GatewayConnectionManager::Link (std::string_view linkCode)
95103{
96- if ((s_flags & FLAG_HAS_IP) == 0 ) {
104+ if ((s_flags. load (std::memory_order_relaxed) & FLAG_HAS_IP) == 0 ) {
97105 return AccountLinkResultCode::NoInternetConnection;
98106 }
99- s_wsClient = nullptr ;
107+ {
108+ ScopedLock lock__ (&s_clientMutex);
109+ s_wsClient = nullptr ;
110+ }
100111
101112 OS_LOGD (TAG, " Attempting to link to account using code %.*s" , linkCode.length (), linkCode.data ());
102113
@@ -136,20 +147,24 @@ AccountLinkResultCode GatewayConnectionManager::Link(std::string_view linkCode)
136147 return AccountLinkResultCode::InternalError;
137148 }
138149
139- s_flags |= FLAG_LINKED;
150+ s_flags. fetch_or ( FLAG_LINKED, std::memory_order_relaxed) ;
140151 OS_LOGD (TAG, " Successfully linked to account" );
141152
142153 return AccountLinkResultCode::Success;
143154}
144155void GatewayConnectionManager::UnLink ()
145156{
146- s_flags &= FLAG_HAS_IP;
147- s_wsClient = nullptr ;
157+ s_flags.fetch_and (static_cast <uint8_t >(~FLAG_LINKED), std::memory_order_relaxed);
158+ {
159+ ScopedLock lock__ (&s_clientMutex);
160+ s_wsClient = nullptr ;
161+ }
148162 Config::ClearBackendAuthToken ();
149163}
150164
151165bool GatewayConnectionManager::SendMessageTXT (std::string_view data)
152166{
167+ ScopedLock lock__ (&s_clientMutex);
153168 if (s_wsClient == nullptr ) {
154169 return false ;
155170 }
@@ -159,6 +174,7 @@ bool GatewayConnectionManager::SendMessageTXT(std::string_view data)
159174
160175bool GatewayConnectionManager::SendMessageBIN (tcb::span<const uint8_t > data)
161176{
177+ ScopedLock lock__ (&s_clientMutex);
162178 if (s_wsClient == nullptr ) {
163179 return false ;
164180 }
@@ -169,7 +185,7 @@ bool GatewayConnectionManager::SendMessageBIN(tcb::span<const uint8_t> data)
169185bool FetchHubInfo (std::string authToken)
170186{
171187 // TODO: this function is very slow, should be optimized!
172- if ((s_flags & FLAG_HAS_IP) == 0 ) {
188+ if ((s_flags. load (std::memory_order_relaxed) & FLAG_HAS_IP) == 0 ) {
173189 return false ;
174190 }
175191
@@ -181,7 +197,7 @@ bool FetchHubInfo(std::string authToken)
181197
182198 if (response.code == 401 ) {
183199 OS_LOGD (TAG, " Auth token is invalid, waiting 5 minutes before checking again" );
184- s_lastAuthFailure = OpenShock::micros ();
200+ s_lastAuthFailure = OpenShock::millis ();
185201 return false ;
186202 }
187203
@@ -205,7 +221,7 @@ bool FetchHubInfo(std::string authToken)
205221 OS_LOGI (TAG, " [%s] rf=%u model=%u" , shocker.id .c_str (), shocker.rfId , shocker.model );
206222 }
207223
208- s_flags |= FLAG_LINKED;
224+ s_flags. fetch_or ( FLAG_LINKED, std::memory_order_relaxed) ;
209225
210226 return true ;
211227}
@@ -245,7 +261,7 @@ bool StartConnectingToLCG()
245261
246262 if (response.code == 401 ) {
247263 OS_LOGD (TAG, " Auth token is invalid, waiting 5 minutes before retrying" );
248- s_lastAuthFailure = OpenShock::micros ();
264+ s_lastAuthFailure = OpenShock::millis ();
249265 return false ;
250266 }
251267
@@ -270,9 +286,11 @@ bool StartConnectingToLCG()
270286
271287void GatewayConnectionManager::Update ()
272288{
289+ ScopedLock lock__ (&s_clientMutex);
290+
273291 if (s_wsClient == nullptr ) {
274292 // Can't connect to the API without WiFi or an auth token
275- if ((s_flags & FLAG_HAS_IP) == 0 || !Config::HasBackendAuthToken ()) {
293+ if ((s_flags. load (std::memory_order_relaxed) & FLAG_HAS_IP) == 0 || !Config::HasBackendAuthToken ()) {
276294 return ;
277295 }
278296
@@ -287,7 +305,7 @@ void GatewayConnectionManager::Update()
287305 return ;
288306 }
289307
290- s_flags |= FLAG_LINKED;
308+ s_flags. fetch_or ( FLAG_LINKED, std::memory_order_relaxed) ;
291309 OS_LOGD (TAG, " Successfully verified auth token" );
292310
293311 s_wsClient = std::make_unique<GatewayClient>(authToken);
0 commit comments