@@ -13,7 +13,6 @@ const char* const TAG = "CommandHandler";
1313#include " events/Events.h"
1414#include " Logging.h"
1515#include " radio/RFTransmitter.h"
16- #include " ReadWriteMutex.h"
1716#include " SimpleMutex.h"
1817#include " util/TaskUtils.h"
1918
@@ -38,10 +37,32 @@ struct KnownShocker {
3837 int64_t lastActivityTimestamp;
3938};
4039
41- static OpenShock::ReadWriteMutex s_rfTransmitterMutex = {};
42- static std::unique_ptr <OpenShock::RFTransmitter> s_rfTransmitter = nullptr ;
40+ static OpenShock::SimpleMutex s_rfTransmitterMutex = {};
41+ static std::shared_ptr <OpenShock::RFTransmitter> s_rfTransmitter = nullptr ;
4342
44- static OpenShock::ReadWriteMutex s_keepAliveMutex = {};
43+ static std::shared_ptr<OpenShock::RFTransmitter> GetTransmitter ()
44+ {
45+ ScopedLock lock__ (&s_rfTransmitterMutex);
46+ return s_rfTransmitter;
47+ }
48+ static bool TryCreateTransmitter (gpio_num_t txPin)
49+ {
50+ auto transmitter = std::make_shared<OpenShock::RFTransmitter>(txPin);
51+ if (!transmitter->ok ()) {
52+ return false ;
53+ }
54+
55+ ScopedLock lock__ (&s_rfTransmitterMutex);
56+ s_rfTransmitter = std::move (transmitter);
57+ return true ;
58+ }
59+ static void DestroyTransmitter ()
60+ {
61+ ScopedLock lock__ (&s_rfTransmitterMutex);
62+ s_rfTransmitter = nullptr ;
63+ }
64+
65+ static OpenShock::SimpleMutex s_keepAliveMutex = {};
4566static QueueHandle_t s_keepAliveQueue = nullptr ;
4667static TaskHandle_t s_keepAliveTaskHandle = nullptr ;
4768
@@ -86,13 +107,13 @@ static void commandhandler_keepalivetask(void* arg)
86107 if (cmdRef.lastActivityTimestamp + KEEP_ALIVE_INTERVAL < now) {
87108 OS_LOGV (TAG, " Sending keep-alive for shocker %u" , cmdRef.shockerId );
88109
89- ScopedReadLock rfLock__ (&s_rfTransmitterMutex );
90- if (s_rfTransmitter == nullptr ) {
110+ auto transmitter = GetTransmitter ( );
111+ if (transmitter == nullptr ) {
91112 OS_LOGW (TAG, " RF Transmitter is not initialized, ignoring keep-alive" );
92113 break ;
93114 }
94115
95- if (!s_rfTransmitter ->SendCommand (cmdRef.model , cmdRef.shockerId , ShockerCommandType::Vibrate, 0 , KEEP_ALIVE_DURATION, false )) {
116+ if (!transmitter ->SendCommand (cmdRef.model , cmdRef.shockerId , ShockerCommandType::Vibrate, 0 , KEEP_ALIVE_DURATION, false )) {
96117 OS_LOGW (TAG, " Failed to send keep-alive for shocker %u" , cmdRef.shockerId );
97118 }
98119
@@ -112,7 +133,7 @@ bool _internalSetKeepAliveEnabled(bool enabled)
112133 return true ;
113134 }
114135
115- ScopedWriteLock lock__ (&s_keepAliveMutex);
136+ ScopedLock lock__ (&s_keepAliveMutex);
116137
117138 if (enabled) {
118139 OS_LOGV (TAG, " Enabling keep-alive task" );
@@ -200,10 +221,8 @@ bool CommandHandler::Init()
200221 }
201222 }
202223
203- s_rfTransmitter = std::make_unique<RFTransmitter>(txPin);
204- if (!s_rfTransmitter->ok ()) {
224+ if (!TryCreateTransmitter (txPin)) {
205225 OS_LOGE (TAG, " Failed to initialize RF Transmitter" );
206- s_rfTransmitter = nullptr ;
207226 return false ;
208227 }
209228
@@ -230,8 +249,7 @@ bool CommandHandler::Init()
230249
231250bool CommandHandler::Ok ()
232251{
233- ScopedReadLock lock__ (&s_rfTransmitterMutex);
234- return s_rfTransmitter != nullptr ;
252+ return GetTransmitter () != nullptr ;
235253}
236254
237255SetGPIOResultCode CommandHandler::SetRfTxPin (gpio_num_t txPin)
@@ -240,16 +258,10 @@ SetGPIOResultCode CommandHandler::SetRfTxPin(gpio_num_t txPin)
240258 return SetGPIOResultCode::InvalidPin;
241259 }
242260
243- ScopedWriteLock lock__ (&s_rfTransmitterMutex);
244-
245- if (s_rfTransmitter != nullptr ) {
246- OS_LOGV (TAG, " Destroying existing RF transmitter" );
247- s_rfTransmitter = nullptr ;
248- }
261+ DestroyTransmitter ();
249262
250263 OS_LOGV (TAG, " Creating new RF transmitter" );
251- auto rfxmit = std::make_unique<RFTransmitter>(txPin);
252- if (!rfxmit->ok ()) {
264+ if (!TryCreateTransmitter (txPin)) {
253265 OS_LOGE (TAG, " Failed to initialize RF transmitter" );
254266 return SetGPIOResultCode::InternalError;
255267 }
@@ -259,8 +271,6 @@ SetGPIOResultCode CommandHandler::SetRfTxPin(gpio_num_t txPin)
259271 return SetGPIOResultCode::InternalError;
260272 }
261273
262- s_rfTransmitter = std::move (rfxmit);
263-
264274 return SetGPIOResultCode::Success;
265275}
266276
@@ -280,9 +290,9 @@ bool CommandHandler::SetKeepAliveEnabled(bool enabled)
280290
281291gpio_num_t CommandHandler::GetRfTxPin ()
282292{
283- ScopedReadLock lock__ (&s_rfTransmitterMutex );
284- if (s_rfTransmitter != nullptr ) {
285- return s_rfTransmitter ->GetTxPin ();
293+ auto transmitter = GetTransmitter ( );
294+ if (transmitter != nullptr ) {
295+ return transmitter ->GetTxPin ();
286296 }
287297
288298 gpio_num_t txPin;
@@ -296,17 +306,15 @@ gpio_num_t CommandHandler::GetRfTxPin()
296306
297307bool CommandHandler::HandleCommand (ShockerModelType model, uint16_t shockerId, ShockerCommandType type, uint8_t intensity, uint16_t durationMs)
298308{
299- ScopedReadLock lock__rf (&s_rfTransmitterMutex);
300-
301- if (s_rfTransmitter == nullptr ) {
309+ auto transmitter = GetTransmitter ();
310+ if (transmitter == nullptr ) {
302311 OS_LOGW (TAG, " RF Transmitter is not initialized, ignoring command" );
303312 return false ;
304313 }
305314
306- bool ok = s_rfTransmitter ->SendCommand (model, shockerId, type, intensity, durationMs);
315+ bool ok = transmitter ->SendCommand (model, shockerId, type, intensity, durationMs);
307316
308- lock__rf.unlock ();
309- ScopedReadLock lock__ka (&s_keepAliveMutex);
317+ ScopedLock lock__ka (&s_keepAliveMutex);
310318
311319 if (ok && s_keepAliveQueue != nullptr ) {
312320 KnownShocker cmd {.killTask = false , .model = model, .shockerId = shockerId, .lastActivityTimestamp = OpenShock::millis () + durationMs};
0 commit comments