GCC Code Coverage Report


Directory: ./
File: channeloutput/Twinkly.h
Date: 2026-10-29 08:11:58
Exec Total Coverage
Lines: 1 1 100.0%
Functions: 1 1 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 #pragma once
2 /*
3 * This file is part of the Falcon Player (FPP) and is Copyright (C)
4 * 2013-2022 by the Falcon Player Developers.
5 *
6 * The Falcon Player (FPP) is free software, and is covered under
7 * multiple Open Source licenses. Please see the included 'LICENSES'
8 * file for descriptions of what files are covered by each license.
9 *
10 * This source file is covered under the GPL v2 as described in the
11 * included LICENSE.GPL file.
12 */
13
14 #include "UDPOutput.h"
15 #include "fpp-json-fwd.h"
16 #include <atomic>
17 #include <list>
18 #include <mutex>
19
20 #define TWINKLY_PORT 7777
21
22 class TwinklyOutputData : public UDPOutputData {
23 public:
24 explicit TwinklyOutputData(const Json::Value& config);
25 virtual ~TwinklyOutputData();
26
27 30 virtual bool IsPingable() override { return true; }
28 virtual void PrepareData(unsigned char* channelData, UDPOutputMessages& msgs) override;
29 virtual void DumpConfig() override;
30
31 virtual const std::string& GetOutputTypeString() const override;
32 virtual void GetRequiredChannelRange(int& min, int& max) override;
33
34 virtual void StartingOutput() override;
35 virtual void StoppingOutput() override;
36
37 Json::Value callRestAPI(bool isPost, const std::string& path, const std::string& body);
38 void verifyToken();
39 void authenticate();
40
41 // Stages a freshly issued token for the output thread to pick up. Returns
42 // false if it could not be decoded, in which case nothing was changed.
43 bool applyAuthToken(const std::string& token);
44
45 // Ends an authentication attempt and starts the one that arrived while it
46 // was running, if any.
47 void finishAuth();
48
49 std::string getAuthToken();
50 void setAuthToken(const std::string& token);
51
52 int port = 1;
53 int portCount = 1;
54
55 sockaddr_in twinklyAddress;
56
57 struct iovec* twinklyIovecs = nullptr;
58 uint8_t** twinklyBuffers = nullptr;
59
60 // The authentication chain runs on the main loop (CurlManager/Timers) while
61 // PrepareData(), StartingOutput() and StoppingOutput() run on the channel
62 // output thread, so everything they share is either guarded by authLock or
63 // an atomic.
64 std::mutex authLock;
65 uint8_t authTokenBytes[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; // staged token, guarded by authLock
66 std::string authToken = ""; // guarded by authLock
67 uint32_t reauthCount = 0; // output thread only
68 std::atomic<bool> authInFlight{ false };
69 std::atomic<bool> authPending{ false }; // a request came in while one was in flight
70 // when the last login was sent; output thread only (see PrepareData)
71 uint64_t lastAuthAttemptMS = 0;
72 // tags this output's CurlManager requests so the destructor can cancel them
73 const std::string curlOwner = "Twinkly-" + std::to_string((uintptr_t)this);
74 std::atomic<bool> tokenPending{ false }; // a staged token is waiting for the output thread
75 std::atomic<bool> outputStarted{ false }; // false once StoppingOutput() has run
76 };
77