diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
index 3f579ae..4396ca2 100644
--- a/.vscode/c_cpp_properties.json
+++ b/.vscode/c_cpp_properties.json
@@ -2,7 +2,7 @@
"configurations": [
{
"name": "ESP-IDF",
- "compileCommands": "/home/gustice/jobs/projects/Proj_Zwickau_waitingRoom/FW_X_WatchController/build_uTest/compile_commands.json",
+ "compileCommands": "/home/gustice/jobs/projects/Proj_Zwickau_waitingRoom/FW_X_WatchController/build/compile_commands.json",
"includePath": [
"${config:idf.espIdfPath}/components/**",
"${config:idf.espIdfPathWin}/components/**",
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 5930075..2543558 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -38,5 +38,21 @@
"--background-index",
"--query-driver=/home/gustice/.espressif/tools/riscv32-esp-elf/esp-14.2.0_20241119/riscv32-esp-elf/bin/riscv32-esp-elf-gcc",
"--compile-commands-dir=/home/gustice/jobs/projects/Proj_Zwickau_waitingRoom/FW_X_WatchController/build_uTest"
- ]
-}
+ ],
+ "cmake.debugConfig": {
+ "setupCommands": [
+ {
+ "description": "Skip standard library code",
+ "text": "skip file /usr/include/*"
+ },
+ {
+ "description": "Skip GCC internal code",
+ "text": "skip file /usr/lib/gcc/*"
+ },
+ {
+ "description": "Skip std namespace",
+ "text": "skip namespace std"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 368dd37..d6eab38 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,5 @@
cmake_minimum_required(VERSION 3.16)
-option(BUILD_UNIT_TESTS "Build unit tests instead of main app" OFF)
-
if(TgtEnv STREQUAL "Host")
message("Using Host-Branch")
add_subdirectory("test/unitOnHost")
diff --git a/components/spit/include/spit_client.hpp b/components/spit/include/spit_client.hpp
index 5fe9903..d107a01 100644
--- a/components/spit/include/spit_client.hpp
+++ b/components/spit/include/spit_client.hpp
@@ -238,7 +238,7 @@ class SClient : ISadClient {
* @param p_DefaultDuration maybe the action has a default duration, this is only used for graphical representations, 0 is allowd
* @return the pointer to the new SPITType.
*/
- SType *createSPITTypeFixed(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration);
+ SType *createTypeFixed(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration);
/**
* Creates a SPITType for application actions.
@@ -252,11 +252,11 @@ class SClient : ISadClient {
* @param p_ProjectIndepended true = the SPITType belongs to a specific project, false = the SpitType always exists for every project
* @return the pointer to the new SPITType.
*/
- SType *createSPITType(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration, bool fixed, bool projectIndepended);
+ SType *createType(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration, bool fixed, bool projectIndepended);
private:
- // receive SPITTypes
- void parseReportSPITType(Message::ReportType &message);
+ // receive SPIT-Types
+ void parseReportType(Message::ReportType &message);
void parseRemoveSPITType(Message::RemoveType &message);
int sendSPITTypeInternal(SType &spitType);
diff --git a/components/spit/include/spit_message.hpp b/components/spit/include/spit_message.hpp
index c35533a..b50b44a 100644
--- a/components/spit/include/spit_message.hpp
+++ b/components/spit/include/spit_message.hpp
@@ -389,7 +389,7 @@ class Message {
private:
bool mConfirmed{};
- string mSPITTypeID{};
+ string mTypeID{};
bool mFixed{};
bool mServerRemote{};
bool mServerProjectIndepended{};
@@ -405,7 +405,7 @@ class Message {
bool parse(const std::vector &message);
bool getConfirmed() const { return mConfirmed; }
- const string getID() const { return mSPITTypeID; }
+ const string getID() const { return mTypeID; }
bool getFixed() const { return mFixed; }
bool getServerRemote() const { return mServerRemote; }
bool getServerProjectIndepended() const { return mServerProjectIndepended; }
@@ -417,7 +417,7 @@ class Message {
ReportType();
void setConfirmed(bool p_Confirmed) { mConfirmed = p_Confirmed; }
- void setID(string iD) { mSPITTypeID = iD; }
+ void setID(string iD) { mTypeID = iD; }
void setFixed(bool p_Fixed) { mFixed = p_Fixed; }
void setServerRemote(bool p_IsServerRemote) { mServerRemote = p_IsServerRemote; }
void setServerProjectIndepended(bool p_ProjectIndpended) { mServerProjectIndepended = p_ProjectIndpended; }
@@ -437,7 +437,7 @@ class Message {
static constexpr int BYTESLENGTH = 45;
private:
- string mSPITTypeID{};
+ string mTypeID{};
public:
RemoveType(const RemoveType &orig);
@@ -445,11 +445,11 @@ class Message {
RemoveType(unique_ptr header);
bool parse(const std::vector &message);
- const string getID() const { return mSPITTypeID; }
+ const string getID() const { return mTypeID; }
// Send
RemoveType();
- void setID(string iD) { mSPITTypeID = iD; }
+ void setID(string iD) { mTypeID = iD; }
bool fillBytes(std::vector &message);
};
@@ -468,7 +468,7 @@ class Message {
bool mFixed{};
bool mServerRemote{};
string mSPITObjectName{};
- string mSPITTypeID{};
+ string mTypeID{};
string mServerParams{};
uint64_t mFrameStart{};
uint64_t mFrameLength{};
@@ -493,7 +493,7 @@ class Message {
bool getFixed() const { return mFixed; }
bool getServerRemote() const { return mServerRemote; }
const string getName() const { return mSPITObjectName; }
- const string getSPITTypeID() const { return mSPITTypeID; }
+ const string getSPITTypeID() const { return mTypeID; }
const string getServerParams() const { return mServerParams; }
uint64_t getFrameStart() const { return mFrameStart; }
uint64_t getFrameLength() const { return mFrameLength; }
@@ -515,7 +515,7 @@ class Message {
void setFixed(bool p_Fixed) { mFixed = p_Fixed; };
void setServerRemote(bool p_IsRemote) { mServerRemote = p_IsRemote; };
void setName(string p_Name) { mSPITObjectName = p_Name; };
- void setSPITTypeID(string iD) { mSPITTypeID = iD; };
+ void setSPITTypeID(string iD) { mTypeID = iD; };
void setServerParams(string p_Parameters) { mServerParams = p_Parameters; };
void setFrameStart(uint64_t p_StartTime) { mFrameStart = p_StartTime; };
void setFrameLength(uint64_t p_Length) { mFrameLength = p_Length; };
diff --git a/components/spit/include/spit_processor.hpp b/components/spit/include/spit_processor.hpp
new file mode 100644
index 0000000..7b01a1f
--- /dev/null
+++ b/components/spit/include/spit_processor.hpp
@@ -0,0 +1,321 @@
+#pragma once
+
+#include "sad_DetectedServer.hpp"
+#include "spit_object.hpp"
+#include "spit_player.hpp"
+#include "spit_type.hpp"
+#include "spit_message.hpp"
+#include "spit_repo.hpp"
+#include
+#include
+#include
+
+using namespace std;
+
+namespace spit {
+
+class SProcessor {
+ public:
+ /** Maximal length of a SPITMessage*/
+ static const int MAXSPITMESSAGEBYTECOUNT = 512;
+
+ enum class ProjUpdate {
+ ServerLoaded,
+ StartTransfer,
+ EndTransfer,
+ ServerClosed,
+ };
+ enum class ServerEvent {
+ Detect,
+ Lost,
+ Changed,
+ };
+ enum class ObjectEvent {
+ Created,
+ Changed,
+ Deleted
+ };
+ enum class Connection {
+ None = 0, // No Connection established.
Either no connect tried or disconnected
+ NoneServer = 1, // Server has disconnected
+ Lost = 2, // The connection is lost
Either because of a network crash or because the server no longer responds.
+ Ok = 3, // Connection to the serv er is established.
+ TryConnection = 4, // A connection to the server is tried.
+ };
+
+ struct Callbacks {
+ function onServerEvent;
+ function onConnectionStatus;
+ function onProjectUpdate;
+ function onSpitType;
+ function onSpitObject;
+ function onPlay;
+ function onPlaySpitType;
+ function onPlayRemoteObjectStatus;
+ function onCheckSpitTypeVeto;
+ function onCheckSpitObjectVeto;
+ };
+
+ //------ PlayerType ------
+ public:
+ /** continous main player, time value can be used like a timecode.
The time value is the position in server's project.
A server should use only one main player.*/
+ static constexpr char PLAYERTYPE_MAIN = 0x02;
+ /** continous player. This player plays SPIT objects sometime during the project.*/
+ static constexpr char PLAYERTYPE_CONTINOUS = 0x01;
+ /** diescrete player. This player is used to transmit single discrete values.*/
+ static constexpr char PLAYERTYPE_DISCRETE = 0x00;
+
+ //------ Value Flag ------
+ //------ used by sendRemoteObject
+ public:
+ /**Set the given value directly*/
+ static constexpr char VALUEFLAG_DIRECT = 0x00;
+ /**Increase the existing value by the given value.
This is usefull e.g. when instead of a fader a endless wheel is used*/
+ static constexpr char VALUEFLAG_INCREASE = 0x01;
+ /**Decrease the existing value by the given value.
This is usefull e.g. when instead of a fader a endless wheel is used*/
+ static constexpr char VALUEFLAG_DECREASE = 0x02;
+ static constexpr int MAX_OVERTAKING_SPIT_MESSAGES = 10;
+
+ //----- SProcessor -----
+ public:
+ SProcessor(string name, string projName, string hostName, string guid, Callbacks calls);
+ virtual ~SProcessor();
+
+ private:
+ Callbacks mCallbacks;
+
+ Connection mConnectionStatus{Connection::None};
+ bool mDisconnectedByServer{}; // flag true = when server disconnects
+ string mGuid;
+ string mName;
+ string mProjName;
+ string mComputerName;
+
+ string mClientProjectName;
+
+ uint8_t mMessageNumberSend{1};
+ int mMessageNumberReceived{-1}; // set to -1 because the first received message will set the number (1..255)
+ vector> mOvertakingMessages;
+
+ // Server's info filled by parseConnectAnswer
+ string mServerID{};
+ string mServerName{};
+ string mServerComputerName{};
+ int mServerStepTime{-1};
+
+ //--- Server Project ---
+ string mServerProjectID;
+ string mServerProjectName;
+ int mServerFramesPerSecond;
+
+ public:
+ /** The ID of the client.
Every client instance should set an unique id*/
+ string getID() { return mGuid; }
+ /** The name of the client, should be set by the user app*/
+ string getName() { return mName; }
+ //----- Computer Params -----
+ /** The name of the client's host computer*/
+ string getComputerName() { return mComputerName; }
+ void setClientProjectName(string clientProjectName) { mClientProjectName = clientProjectName; }
+ string getClientProjectName() { return mClientProjectName; }
+
+ // connected Server Infos
+ /** The ID of the connected SPITServer*/
+ string getServerID() { return mServerID; }
+ /** The host computername of the connected SPITServer*/
+ string getServerComputerName() { return mServerComputerName; }
+ /** The name of the connected SPITServer*/
+ string getServerName() { return mServerName; }
+
+ /** Expected Refreah Rate of the connectd SPITServer.
+ * When the server plays objects, it will do so at discrete time steps.
+ * Play events will take place in these time steps..
+ */
+ int getServerStepTime() { return mServerStepTime; }
+
+ /** Should be called when the client wants to close his project*/
+ void clientProjectClose();
+ /**
+ * Should be called whenever the client has a project loaded
+ */
+ void clientProjectLoaded();
+
+ void setActionSPITType(string spitypeID, bool actionAssigned);
+ void setActionSPITObject(string objectID, bool actionAssigned);
+
+ //--------------- SPITMessage ---------------
+ private:
+ // Reconnect to the server when connection is lost see eventConnectionStatus and eventServerDetected
+ bool _doReconnect{}; // true = on eventServerDetected connect to the server identified by mServerID
+ public:
+ std::vector createMessage(Message::OPPart & spitMessageOPPart);
+ void checkParseMessageData(vector data);
+
+
+ //--------------- ServerAutoDetection SAD ---------------
+ public:
+ /** Starts the autodetection of SPITServers in the local network. If a connection is tried, the autodetection should be stopped before.*/
+ void startServerAutoDetect();
+ /** Stops the autodetection of SPITServers in the local network*/
+ void stopServerAutoDetect();
+ /** Called every time a new SPITServer is detetced in the local network */
+ void eventServerDetected(SadDetectedServer &server);
+ /** Called every time a prior detected SPITServer is is no longer found.*/
+ void eventServerLost(SadDetectedServer &server);
+ void eventServerChanged(SadDetectedServer &server);
+
+ //--------------- Connection ---------------
+ public:
+ /**
+ * Tries a connection to the SPITServer
+ * @param p_ServerIP ip address of the SPITServer
+ * @param p_ServerPort port of the SPITServer
+ * @param p_ClientIP IP of the client
+ * @param p_ClientPort if "0" any free port will be used
+ * @param p_LoginName maybe some SPITServer need a login - liveSHOWsoftware will not.
+ * @param p_LoginPassword maybe some SPITServer need a login - liveSHOWsoftware will not
+ * @return true = the connection try is ok, SPITServer will answer with COnnectAnswer and an eventConnectionStatus will occur.
+ * false = something is going wrong. (client could not bind)
+ */
+ bool connect(string serverIP, string serverPort, string clientIP, string clientPort, string loginName = "", string loginPassword = "");
+ /**
+ * Terminates the connection to the SPITServer.
+ */
+ void disconnect();
+
+ private:
+ void disconnectInternal(Connection cause);
+ void resetMessageNumberReceived();
+ void parseMessage(Message& message);
+ void addOvertakingMessage(unique_ptr message);
+ void parseConnectAnswer(Message::ConnectAnswer &message);
+ void parseDisconnect(Message::Disconnect &message);
+ void parseWatchdog(Message::Watchdog &message);
+ void parseWatchdogAnswer(Message::WatchdogAnswer &message);
+
+ public:
+ /** Used internally*/
+ void sendWatchdog();
+ /** Used internally. When the connection to the SPITServer is lost an eventConnectionStatus will occur*/
+ void eventWatchdogLost();
+ //--------------- SPIT Project ---------------
+ private:
+ void parseReportProject(Message::ReportProject &message);
+ void parseCloseProject(Message::CloseProject &message);
+
+ public:
+ /** Returns the SPITServer's project ID - may be the same as the project's name*/
+ string getServerProjectID();
+ /** Returns the SPITServer's project name*/
+ string getServerProjectName();
+ /** Returns frame rate per second. This is the time resolution in which the server transmits time data. The unit of time data is always frames.*/
+ int getServerFramesPerSecond();
+
+ private:
+ void parseRequestProjectTransfer(Message::RequestProjectTransfer &message);
+ void parseStartProjectTransfer(Message::StartProjectTransfer &message);
+ void parseEndProjectTransfer(Message::EndProjectTransfer &message);
+
+ public:
+ // static void sendProject(SClient *p_PtrSProcessor);
+
+ // --------------- SPIT Types ---------------
+ public:
+ /**
+ * Creates a fixed SPITType for application actions that are always present and project independent.
+ * Fixed SPIT types cannot be changed or deleted by the server.
+ * These SPITTypes will be automatically added to the SPITType-List and sended to the server.
+ * @param p_ID an unique of the SPITType, these are always the same per client approach. Different client approaches should use different ids.
+ * @param p_GroupName a name which groups the actions/SPITTypes
+ * @param p_Name the name of the Action/SPITType
+ * @param p_DefaultDelay maybe there is an default delay until the action starts, this is only used for graphical representations, 0 is allowd
+ * @param p_DefaultDuration maybe the action has a default duration, this is only used for graphical representations, 0 is allowd
+ * @return the pointer to the new SPITType.
+ */
+ SType *createTypeFixed(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration);
+
+ /**
+ * Creates a SPITType for application actions.
+ * These SPITTypes will be automatically added to the SPITType-List and sended to the server.
+ * @param p_ID an unique of the SPITType, these are always the same per client approach. Different client approaches should use different ids.
+ * @param p_GroupName a name which groups the actions/SPITTypes
+ * @param p_Name the name of the Action/SPITType
+ * @param p_DefaultDelay maybe there is an default delay until the action starts, this is only used for graphical representations, 0 is allowd
+ * @param p_DefaultDuration maybe the action has a default duration, this is only used for graphical representations, 0 is allowd
+ * @param p_Fixed true = the server is not allowed to change this SPITType, false = the server may change or delete this SPITType
+ * @param p_ProjectIndepended true = the SPITType belongs to a specific project, false = the SpitType always exists for every project
+ * @return the pointer to the new SPITType.
+ */
+ SType *createType(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration, bool fixed, bool projectIndepended);
+
+ private:
+ // receive SPIT-Types
+ void parseReportType(Message::ReportType &message);
+ void parseRemoveSPITType(Message::RemoveType &message);
+ int sendSPITTypeInternal(SType &sType);
+
+ public:
+ /**
+ * If a client wants to change a SPITType, he should send it to the server.
+ * If the SPITTye is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the change.
+ * @param spitypeID the id of the SPITType to remove.
+ * @return 0 = is sended, -1 = is not sended
+ */
+ bool changeSPITType(SType *spitType);
+ /**
+ * If a client wants to remove a SPITType, he should send it to the server.
+ * If the SPITTye is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the deletion.
+ * @param spitypeID the id of the SPITType to remove.
+ * @return 0 = is sended, -1 = is not sended
+ */
+ int removeSPITType(string spitypeID);
+
+ public:
+ //--------------- SPIT Objects ---------------
+ private:
+ void parseReportSPITObject(Message::ReportObject &message);
+ void parseRemoveSPITObject(Message::RemoveObject &message);
+ int sendSPITObjectInternal(SObject *ptrObject);
+
+ public:
+ /**
+ * When the client changes a SPITObject (normally the client should not do this), then it should send the changes to the SPITServer.
+ * The SPITServer may discard the changes and an eventSPITObject occurs.
+ * @param spitObject the pointer to the changed SPITObject.
+ * @return 0 = sended, -1 = not sended
+ */
+ bool changeSPITObject(SObject *spitObject);
+ /**
+ * When the client removes a SPITObject (normally the client should not do this), then he should send it to the SPITServer.
+ * The SPITServer may discard the deletion and an eventSPITObject occurs.
+ * @param objectID the id of the SPITObject to remove.
+ * @return 0 = sended, -1 = not sended
+ */
+ int removeSPITObject(string objectID);
+
+ public:
+ //--------------- Play SPIT Objects ---------------
+ private:
+ void parsePlaySPITStart(Message::PlayStart &message);
+ void parsePlaySPITObject(Message::PlayObject &message);
+ void parsePlaySPITEnd(Message::PlayEnd &message);
+ void parseReportPlayStatus(Message::ReportPlayStatus &message);
+
+ public:
+ //--------- Remote ----------
+ void sendRemoteObject(string objectID, int valuePpm = 0, char valueFlag = 0x00);
+
+ private:
+ bool mAbortSearch{};
+ bool sAnswered{};
+ void answerWatchdog() {
+ sAnswered = true;
+ }
+
+ SpitRepo mSpitObjects;
+ SpitRepo mRemoteSpitObjects;
+ SpitRepo mSpitTypes;
+ SpitRepo mRemoteSpitTypes;
+};
+
+}
\ No newline at end of file
diff --git a/components/spit/include/spit_type.hpp b/components/spit/include/spit_type.hpp
index ed8c1bb..5b3c0ef 100644
--- a/components/spit/include/spit_type.hpp
+++ b/components/spit/include/spit_type.hpp
@@ -1,6 +1,5 @@
#pragma once
-#include "spit_socket.hpp"
#include "spit_message.hpp"
#include "spit_repo.hpp"
@@ -88,7 +87,7 @@ class SType {
private:
bool mConfirmed{};
string mID;
- bool mCreatedByClient; // flag true = the SPITTyype is created by the client
+ bool mCreatedByClient{}; // flag true = the SPITTyype is created by the client
// false = the SType is received from the server
public:
diff --git a/components/spit/src/spit_client.cpp b/components/spit/src/spit_client.cpp
index bbe8769..3a39a8b 100644
--- a/components/spit/src/spit_client.cpp
+++ b/components/spit/src/spit_client.cpp
@@ -258,7 +258,7 @@ void SClient::resetMessageNumberReceived() {
void SClient::checkParseMessage(unique_ptr p_SPITMessage) {
answerWatchdog();
- if (!p_SPITMessage || !p_SPITMessage->getHeader() || p_SPITMessage->getOPPart()) {
+ if (!p_SPITMessage || !p_SPITMessage->getHeader() || !p_SPITMessage->getOPPart()) {
ESP_LOGD(TAG, "Client::parseMessage incomplete message");
return;
}
@@ -370,7 +370,7 @@ void SClient::parseMessage(unique_ptr message) {
break;
//----- SPIT Types ------
case Message::ReportType::OPFLAG:
- parseReportSPITType(message->getAs());
+ parseReportType(message->getAs());
break;
case Message::RemoveType::OPFLAG:
parseRemoveSPITType(message->getAs());
@@ -785,7 +785,7 @@ void SClient::parseEndProjectTransfer(Message::EndProjectTransfer &message) {
}
//----- SPIT Types ------
-void SClient::parseReportSPITType(Message::ReportType &message) {
+void SClient::parseReportType(Message::ReportType &message) {
ESP_LOGD(TAG, "parse ReportType ID %s Name %s",message.getID().c_str(), message.getName().c_str());
SType *ptrSPITType;
bool boolNew = false;
@@ -931,11 +931,11 @@ int SClient::removeSPITType(string p_SPITTypeID) {
return -1;
}
-SType *SClient::createSPITTypeFixed(string iD, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration) {
- return createSPITType(iD, p_GroupName, p_Name, p_DefaultDelay, p_DefaultDuration, true, true);
+SType *SClient::createTypeFixed(string iD, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration) {
+ return createType(iD, p_GroupName, p_Name, p_DefaultDelay, p_DefaultDuration, true, true);
}
-SType *SClient::createSPITType(string p_ID, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration, bool p_FIxed, bool p_ProjectIndepended) {
+SType *SClient::createType(string p_ID, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration, bool p_FIxed, bool p_ProjectIndepended) {
bool boolNew;
SType *ptrSPITType = mSpitTypes.getEntry(p_ID);
if (ptrSPITType == nullptr) {
diff --git a/components/spit/src/spit_message.cpp b/components/spit/src/spit_message.cpp
index 3729786..0777670 100644
--- a/components/spit/src/spit_message.cpp
+++ b/components/spit/src/spit_message.cpp
@@ -700,7 +700,7 @@ bool Message::ReportType::parse(const std::vector &message) {
mParseOffset = Header::BYTESLENGTH;
mBytesCount = getInt(message, mParseOffset).value();
mConfirmed = getBoolean(message, mParseOffset).value();
- mSPITTypeID = getString(message, mParseOffset, 41).value();
+ mTypeID = getString(message, mParseOffset, 41).value();
mFixed = getBoolean(message, mParseOffset).value();
mServerRemote = getBoolean(message, mParseOffset).value();
mServerProjectIndepended = getBoolean(message, mParseOffset).value();
@@ -731,7 +731,7 @@ bool Message::ReportType::fillBytes(std::vector &message) {
mParseOffset = mHeader->BYTESLENGTH;
mParseOffset += setInt(mBytesCount, message, mParseOffset);
mParseOffset += setBoolean(mConfirmed, message, mParseOffset);
- mParseOffset += setString(mSPITTypeID, message, mParseOffset, 41);
+ mParseOffset += setString(mTypeID, message, mParseOffset, 41);
mParseOffset += setBoolean(mFixed, message, mParseOffset);
mParseOffset += setBoolean(mServerRemote, message, mParseOffset);
mParseOffset += setBoolean(mServerProjectIndepended, message, mParseOffset);
@@ -762,7 +762,7 @@ bool Message::RemoveType::parse(const std::vector &message) {
try {
mParseOffset = Header::BYTESLENGTH;
mBytesCount = getInt(message, mParseOffset).value();
- mSPITTypeID = getString(message, mParseOffset, 41).value();
+ mTypeID = getString(message, mParseOffset, 41).value();
} catch (...) {
ESP_LOGE(TAG, "failed to parse RemoveType message");
return false;
@@ -785,7 +785,7 @@ bool Message::RemoveType::fillBytes(std::vector &message) {
try {
mParseOffset = Header::BYTESLENGTH;
mParseOffset += setInt(mBytesCount, message, mParseOffset);
- mParseOffset += setString(mSPITTypeID, message, mParseOffset, 41);
+ mParseOffset += setString(mTypeID, message, mParseOffset, 41);
} catch (...) {
ESP_LOGE(TAG, "failed to create RemoveType message");
return false;
@@ -815,7 +815,7 @@ bool Message::ReportObject::parse(const std::vector &message) {
mFixed = getBoolean(message, mParseOffset).value();
mServerRemote = getBoolean(message, mParseOffset).value();
mSPITObjectName = getString(message, mParseOffset, 64).value();
- mSPITTypeID = getString(message, mParseOffset, 41).value();
+ mTypeID = getString(message, mParseOffset, 41).value();
mServerParams = getString(message, mParseOffset, 64).value();
mFrameStart = getLong(message, mParseOffset).value();
mFrameLength = getLong(message, mParseOffset).value();
@@ -865,7 +865,7 @@ bool Message::ReportObject::fillBytes(std::vector &message) {
mParseOffset += setBoolean(mFixed, message, mParseOffset);
mParseOffset += setBoolean(mServerRemote, message, mParseOffset);
mParseOffset += setString(mSPITObjectName, message, mParseOffset, 64);
- mParseOffset += setString(mSPITTypeID, message, mParseOffset, 41);
+ mParseOffset += setString(mTypeID, message, mParseOffset, 41);
mParseOffset += setString(mServerParams, message, mParseOffset, 64);
mParseOffset += setLong(mFrameStart, message, mParseOffset);
mParseOffset += setLong(mFrameLength, message, mParseOffset);
diff --git a/components/spit/src/spit_processor.cpp b/components/spit/src/spit_processor.cpp
new file mode 100644
index 0000000..285344d
--- /dev/null
+++ b/components/spit/src/spit_processor.cpp
@@ -0,0 +1,1235 @@
+
+#include "spit_processor.hpp"
+#include "esp_log.h"
+
+namespace spit {
+static const char *TAG = "SPIT";
+
+/**
+ * Create a new SPIT_client instance, should be done once by the user app.
+ * @param p_SPITClientInterface the user app should implement the SPIT_ClientInterface.
+ */
+SProcessor::SProcessor(string name, string projName, string hostName, string guid, Callbacks calls) // @todo
+ : mCallbacks(calls),
+ mGuid(guid),
+ mName(name),
+ mProjName(projName),
+ mComputerName(hostName) {
+}
+
+SProcessor::~SProcessor() { // @todo
+ stopServerAutoDetect();
+ disconnectInternal(Connection::None);
+}
+
+void SProcessor::clientProjectClose() { // @todo
+ if (mConnectionStatus == Connection::Ok) {
+ ESP_LOGI(TAG, " ... tidy up ressources");
+ Message::CloseProject closeSPITProject(mProjName);
+ // if (sendSPITMessage(closeSPITProject) < 0) {
+ // ESP_LOGD(TAG, "Client could not send Client's ReportProject");
+ // }
+ }
+}
+
+void SProcessor::clientProjectLoaded() { // @todo
+ // set confirmed = false for all SPITTypes and SPITObjects
+ SType::setConfirmedFalse(mSpitTypes);
+ SObject::setConfirmedFalse(mSpitObjects);
+
+ if (mConnectionStatus == Connection::Ok) {
+ // send ReportProject to the server
+ Message::ReportProject reportSPITProject(mProjName, mProjName);
+ reportSPITProject.setFramesPerSecond(0);
+ // if (sendSPITMessage(reportSPITProject) < 0) {
+ // ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send Client's ReportProject");
+ // }
+
+ // send RequestProjectTransfer
+ Message::RequestProjectTransfer sMRequestProjectTransfer;
+ // if (sendSPITMessage(sMRequestProjectTransfer) < 0) {
+ // ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send RequestProjectTransfer");
+ // }
+ }
+}
+
+/**
+ * Virtual construct - means actionAssigned for SPITTypes is is not implemented in SPITProtocol.
+ * This can used to setActionAssigned to all SPITObjects with this SPITType.
+ * This may be used in the case when the same action should be done for every SPITObject with this SPITType associated.
+ * This tells the server not what action is done, but it tells the server that there is an action.
+ * @param typeId the id of the SPITType
+ * @param actionAssigned
+ */
+void SProcessor::setActionSPITType(string typeId, bool actionAssigned) { // @todo
+ SType *spitType = mSpitTypes.getEntry(typeId);
+ if (spitType == nullptr)
+ return;
+ if (spitType->ActionAssigned.set(actionAssigned)) {
+ sendSPITTypeInternal(*spitType);
+ for (auto& [key, value] : mSpitObjects.getRepo()) {
+ if (value->SPITTypeID.get() == spitType->getID()) {
+ if (value->setActionAssignedType(actionAssigned) == true) {
+ sendSPITObjectInternal(value.get());
+ }
+ }
+ }
+ }
+}
+
+/** This should be called if the user wants to associate/remove an action with a SPITObject. */
+void SProcessor::setActionSPITObject(string spitObjId, bool actionAssigned) { // @todo
+ SObject *spitObject = mSpitObjects.getEntry(spitObjId);
+ if (spitObject == nullptr)
+ return;
+ if (spitObject->setActionAssigned(actionAssigned) == true) {
+ sendSPITObjectInternal(spitObject);
+ }
+}
+//---------- ServerAutoDetection SAD -----------
+
+/** Starts the autodetection of SPITServers in the local network. If a connection is tried, the autodetection should be stopped before.
+ * If a SPITServer is detected in the locale network an eventServerDetected occurs.
+ */
+void SProcessor::startServerAutoDetect() { // @todo
+ // if (mDisconnectedByServer == true) {
+ // // Server has previously disconnected -> do not start ServerAutodetect directly
+ // fos::Task::delayMs(1000); // sleep a little to give the SPITServer time to clean up its stuff
+ // }
+ // SadDetectedServer::clearDetectedServers();
+ // if (!sThread) {
+ // sThread = new fos::TaskT(SProcessor::processSocketTask, *this, "spitSock", fos::Task::DefaultStackSize * 2); // @todo
+ // }
+ // mAbortSearch = false;
+ // sStartSad.give();
+}
+
+/** Stops the auto detection of SPIT servers. */
+void SProcessor::stopServerAutoDetect() { // @todo
+ mAbortSearch = true;
+}
+/**
+ * If a new server was found by the ServerAutoDetect mechanism, this function is called.
+ * To do so the SAD_Client ServerAutoDetect has to be startet - see SAD_Client::startServerAutoDetect.
+ * If a server can be reached via several IP addresses, the IP address is selected according to the following preference:
+ */
+void SProcessor::eventServerDetected(SadDetectedServer &server) { // @todo
+ mCallbacks.onServerEvent(ServerEvent::Detect, server);
+ // If a connection has been established and the connection is lost -> reconnect
+ if (_doReconnect) {
+ if (mServerID == server.getID()) {
+ stopServerAutoDetect();
+ ESP_LOGI(TAG, "reconnect to %s / %s", server.getIP().data(), server.getPort().data());
+ if (connect(server.getIP(), server.getPort(), server.getClientIP(), "0")) {
+ return;
+ }
+ }
+ }
+ // Stop auto detection because a suitable server was found
+ stopServerAutoDetect();
+ ESP_LOGI(TAG, "connect to %s / %s", server.getIP().data(), server.getPort().data());
+ if (!connect(server.getIP(), server.getPort(), server.getClientIP(), "0" /*= any port*/)) {
+ // connection message could not be sent -> better to restart AutoDetection
+ startServerAutoDetect();
+ }
+}
+
+/**
+ * If a SPITServer is not more found, this function is called.
+ * To do so the SAD_Client ServerAutoDetect has to be startet - see SAD_Client::startServerAutoDetect.
+ */
+void SProcessor::eventServerLost(SadDetectedServer &server) { // @todo
+ mCallbacks.onServerEvent(ServerEvent::Lost, server);
+}
+
+void SProcessor::eventServerChanged(SadDetectedServer &server) { // @todo
+ mCallbacks.onServerEvent(ServerEvent::Changed, server);
+ // tryConnection(detectedServer);
+}
+
+// void MyApp::tryConnection(const SadDetectedServer &detected) {
+// // fetch the infoemations from the detected
+// bool boolSuccess = false;
+// bool boolPossibleConnect = checkPossibleConnection(detected);
+
+// if (boolPossibleConnect == false)
+// return;
+
+// // --------------------------------------
+// // You have three Options to use the detected server
+// // OPTION 1 Use the first server found
+// // OPTION 2 Use the first server found that fulfills specific conditions
+// // OPTION 3 take a copy of the detected and do connection later
+// // SadDetectedServer o_DetectedServer = detected; //this will call the copy constructor
+// // ---------------------------------------
+
+// // Excample use the first detected LOOPBACK server, means the server runs on the same computer as this client
+// // if (detected.getIpIsLoopback() == true) { //omit the if condition if you want to use the first server found
+
+// boolSuccess = false;
+// // Stop auto detection because a suitable server was found
+// stopServerAutoDetect();
+// if (mSPIT_Client != nullptr) {
+// mServerProjectName = detected.getProjectName();
+// mServerIP = detected.getIP();
+
+// #if defined(DEBUGOUTPUT)
+// ESP_LOGD(TAG, "MySPITApp: connect to %s ", detected.getIP().data());
+// #endif
+// // Use the mBoardNumber as login name
+// string stringLoginName = "";
+// string stringLoginPassword = "";
+// boolSuccess = mSPIT_Client->connect(detected.getIP(), detected.getPort(), detected.getClientIP(), stringLoginName, stringLoginPassword); // ClientPort = "0" meeans use any port
+// }
+// if (boolSuccess == false) {
+// // connection message could not be sent
+// // perhaps restart AutoDetection
+// startServerAutoDetect();
+// } else {
+// // WAITING FOR CONNECTION ANSWER
+// // If the Server is closed in the meantime no answer will return
+// //-> connect(..) has started the watchdog
+// }
+
+// // } //Excample
+// }
+
+std::vector SProcessor::createMessage(Message::OPPart &opPart) {
+ if (mMessageNumberSend == 255)
+ mMessageNumberSend = 1;
+ else
+ mMessageNumberSend++;
+ opPart.setMessageNumber(mMessageNumberSend);
+ opPart.setServerInfoInHeader(mGuid, mServerID);
+
+ int opFlag = opPart.getHeader()->getType();
+ try {
+ return Message::createMessage(opPart);
+ } catch (...) {
+ ESP_LOGD(TAG, "Exception client OPFlag: %d", opFlag);
+ }
+ return {};
+}
+// todo Delete SProcessor::sendSPITMessage(Message::OPPart &opPart
+
+// void SProcessor::receiveSPITMessage(SClient &rM) { // @todo
+// char buffer[MAXSPITMESSAGEBYTECOUNT + 1];
+// int rdLen;
+// while (rM.mStopReceiveMessages == false) {
+// rdLen = rM.mSocket.receiveMessage(buffer, MAXSPITMESSAGEBYTECOUNT, nullptr);
+// if (rdLen < 0) {
+// if (rM.mStopReceiveMessages) {
+// return;
+// }
+// continue;
+// }
+// auto vec = vector(buffer, buffer + rdLen);
+// rM.checkParseMessageData(move(spitMsg));
+// // rM.checkParseMessage(move(spitMsg));
+// }
+// }
+
+void SProcessor::resetMessageNumberReceived() { // @todo
+ mMessageNumberReceived = -1;
+ mOvertakingMessages.clear();
+}
+
+void SProcessor::checkParseMessageData(vector data) {
+ auto message = make_unique(data);
+ answerWatchdog();
+ if (!message->getHeader() || !message->getOPPart()) {
+ ESP_LOGD(TAG, "Client::parseMessage incomplete message");
+ return;
+ }
+
+ int msgNum = (int)(message->getHeader()->getMessageNumber() & 0xFF);
+
+ if (msgNum == 0) {
+ parseMessage(*message);
+ return;
+ }
+ if (mMessageNumberReceived < 0) {
+ mMessageNumberReceived = msgNum;
+ parseMessage(*message);
+ return;
+ }
+
+ int msgNumNext = mMessageNumberReceived + 1;
+ if (msgNumNext > 255 || msgNumNext < 1)
+ msgNumNext = 1;
+
+ if (msgNum == msgNumNext) {
+ mMessageNumberReceived = msgNum;
+ parseMessage(*message);
+
+ // check overtaking messages
+ auto it = mOvertakingMessages.begin();
+ while (mOvertakingMessages.size() > 0) {
+
+ msgNumNext = mMessageNumberReceived + 1;
+ if (msgNumNext > 255 || msgNumNext < 1)
+ msgNumNext = 1;
+
+ auto &overtakingMessage = *it;
+ msgNum = (int)(overtakingMessage->getHeader()->getMessageNumber() & 0xFF);
+
+ if (msgNum == msgNumNext) {
+ mMessageNumberReceived = msgNum;
+ parseMessage(*overtakingMessage);
+ mOvertakingMessages.erase(it);
+
+ it = mOvertakingMessages.begin();
+ } else {
+ break;
+ }
+ }
+
+ } else {
+ // p_SPITMessage has overtaken another message
+ addOvertakingMessage(move(message));
+ }
+}
+
+void SProcessor::addOvertakingMessage(unique_ptr message) { // @todo
+ if (!message) {
+ return;
+ }
+ if (mOvertakingMessages.size() > MAX_OVERTAKING_SPIT_MESSAGES) {
+ ESP_LOGD(TAG, "Client receiveing: perhaps message lost !!!!!");
+ }
+
+ int intMessageNumber = (int)(message->getHeader()->getMessageNumber() & 0xFF);
+ for (auto it = mOvertakingMessages.begin(); it != mOvertakingMessages.end(); ++it) {
+ const auto &overtaking = *it;
+ int intOvertakingMessageNumber = (int)(overtaking->getHeader()->getMessageNumber() & 0xFF);
+ if (intMessageNumber < intOvertakingMessageNumber) {
+ mOvertakingMessages.insert(it, move(message));
+ return;
+ }
+ }
+ mOvertakingMessages.push_back(move(message));
+}
+
+void SProcessor::parseMessage(Message& message) { // @todo
+ answerWatchdog();
+ if (!message.getHeader() || !message.getOPPart()) {
+ ESP_LOGD(TAG, "Client::parseMessage incomplete message");
+ return;
+ }
+
+ switch (message.getType()) {
+ //----- Connection -----
+ case Message::ConnectAnswer::OPFLAG:
+ parseConnectAnswer(message.getAs());
+ break;
+ case Message::Disconnect::OPFLAG:
+ parseDisconnect(message.getAs());
+ break;
+ case Message::ReportProject::OPFLAG:
+ parseReportProject(message.getAs());
+ break;
+ case Message::Watchdog::OPFLAG:
+ parseWatchdog(message.getAs());
+ break;
+ case Message::WatchdogAnswer::OPFLAG:
+ parseWatchdogAnswer(message.getAs());
+ break;
+ //----- SPIT Project -----
+ case Message::StartProjectTransfer::OPFLAG:
+ parseStartProjectTransfer(message.getAs());
+ break;
+ case Message::CloseProject::OPFLAG:
+ parseCloseProject(message.getAs());
+ break;
+ case Message::RequestProjectTransfer::OPFLAG:
+ parseRequestProjectTransfer(message.getAs());
+ break;
+ case Message::EndProjectTransfer::OPFLAG:
+ parseEndProjectTransfer(message.getAs());
+ break;
+ //----- SPIT Types ------
+ case Message::ReportType::OPFLAG:
+ parseReportType(message.getAs());
+ break;
+ case Message::RemoveType::OPFLAG:
+ parseRemoveSPITType(message.getAs());
+ //----- SPIT Objects ------
+ break;
+ case Message::ReportObject::OPFLAG:
+ parseReportSPITObject(message.getAs());
+ break;
+ case Message::RemoveObject::OPFLAG:
+ parseRemoveSPITObject(message.getAs());
+ break;
+ //----- Play SPIT Objects ------
+ case Message::PlayStart::OPFLAG:
+ parsePlaySPITStart(message.getAs());
+ break;
+ case Message::PlayObject::OPFLAG:
+ parsePlaySPITObject(message.getAs());
+ break;
+ case Message::PlayEnd::OPFLAG:
+ parsePlaySPITEnd(message.getAs());
+ break;
+ case Message::ReportPlayStatus::OPFLAG:
+ parseReportPlayStatus(message.getAs());
+ break;
+ default:
+ ESP_LOGD(TAG, "Client::parseMessage: Unknown Message");
+ }
+}
+
+//----- Connection ------
+/**
+ * Tries to connect to a SPITServer.
+ * @param serverIP the ip address of the SPIT server
+ * @param serverPort the port number of the SPIT server
+ * @param clientIP the local IP address of the client
+ * @param clientPort the port number of the Client, if "0" the OS uses any possible port number
+ * @param loginName login user name (liveSHOW does not use this -> mayby ""
+ * @param loginPassword login user password (liveSHOW does not use this -> mayby ""
+ * @return false = an error has occured, true = the connect was sent to the server
+ */
+bool SProcessor::connect(string serverIP, string serverPort, string clientIP, string clientPort, string loginName, string loginPassword) { // @todo
+ disconnect();
+ // mSocket.setConnectionParams(serverIP, serverPort, clientIP, clientPort);
+ // if (mSocket.bindSocket(clientIP, clientPort) < 0) {
+ // mStopReceiveMessages = true;
+ // return false;
+ // }
+ Message::Connect sMConnect(mComputerName, mName);
+ sMConnect.setLoginName(loginName);
+ sMConnect.setLoginPassword(loginPassword);
+ sMConnect.setServerIP(serverIP);
+ if (serverPort.length() <= 0) {
+ serverPort = "0";
+ }
+ int intServerPort = stoi(serverPort);
+ sMConnect.setServerPort(intServerPort);
+
+ // if (startReceiveSPITMessages() == false) {
+ // mStopReceiveMessages = true;
+ // return false;
+ // }
+ resetMessageNumberReceived();
+ Connection intOldConnectionStatus = mConnectionStatus;
+
+ mConnectionStatus = Connection::TryConnection;
+ mCallbacks.onConnectionStatus(mServerID, mServerComputerName, mServerName, mServerStepTime,
+ mConnectionStatus, intOldConnectionStatus);
+
+ // sleep a little to make sure that the reception of the messages is started
+ // fos::Task::delayMs(500);
+ // if (sendSPITMessage(sMConnect) < 0) {
+ // mConnectionStatus = Connection::None;
+ // mStopReceiveMessages = true;
+ // return false;
+ // }
+ return true;
+}
+
+/**
+ * Terminates the connection to the SPITServer.
+ */
+void SProcessor::disconnect() { // @todo
+ disconnectInternal(Connection::None);
+}
+
+void SProcessor::disconnectInternal(Connection cause) { // @todo
+ Connection intOldConnectionStatus = mConnectionStatus;
+
+ mConnectionStatus = cause;
+ switch (mConnectionStatus) {
+ case Connection::Lost:
+ break;
+ case Connection::None: {
+ Message::Disconnect sMDisconnect;
+ // sendSPITMessage(sMDisconnect);
+ } break;
+ case Connection::NoneServer:
+ break;
+ default:
+ break;
+ }
+
+ // stopReceiveSPITMessages();
+ mCallbacks.onConnectionStatus(mServerID, mServerComputerName, mServerName, mServerStepTime,
+ mConnectionStatus, intOldConnectionStatus);
+
+ if (intOldConnectionStatus != Connection::None && intOldConnectionStatus != Connection::NoneServer) {
+ ESP_LOGI(TAG, "eventConnectionStatus %d ", (int)mConnectionStatus);
+ switch (mConnectionStatus) {
+ case SProcessor::Connection::None: // @todo
+ ESP_LOGD(TAG, "not connected");
+ break;
+ case SProcessor::Connection::NoneServer: // @todo
+ ESP_LOGD(TAG, "connection terminated by server");
+ // call eventProjectClosed because this may not be sended by the server,
+ // when the connection is closed
+ mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, mServerProjectID);
+
+ // Server has terminated the connection -> start a new game
+ // _doReconnect = false;
+ startServerAutoDetect();
+ break;
+ case SProcessor::Connection::Lost: // @todo
+ ESP_LOGD(TAG, "connection lost");
+ // Maybe you want to reconnect, see eventServerDetected(...)
+ // We have lost the connection -> set the flag to true and start the autodetection to reconnect at eventServerDetected(...)
+ // _doReconnect = true;
+ startServerAutoDetect();
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void SProcessor::parseConnectAnswer(Message::ConnectAnswer &message) { // @todo
+ if (message.getClientID() != mGuid)
+ return;
+
+ mServerID = message.getServerID();
+ mServerComputerName = message.getServerComputerName();
+ mServerName = message.getServerName();
+ mServerStepTime = message.getStepTime();
+
+ if (message.getConnected() == false) {
+ disconnectInternal(Connection::NoneServer);
+ } else {
+ message.getStepTime();
+ mConnectionStatus = Connection::Ok;
+ mDisconnectedByServer = false;
+ ESP_LOGD(TAG, "connection established");
+ stopServerAutoDetect(); // normally you should stop the autodetection before you try a connection
+ // This is redundand
+ // mStopReceiveMessages = false;
+
+ // Maybe you want to reconnect, see eventServerDetected(...)
+ // Here the connection is established -> don't reconnect at eventServerDetected(...)
+ // _doReconnect = false;
+ }
+}
+
+/**
+ * The SPIT server was closed
+ * @param message
+ */
+void SProcessor::parseDisconnect(Message::Disconnect &message) { // @todo
+ Connection intCauseDisconnect = Connection::NoneServer;
+ /*
+ function o_Callable = bind(&SProcessor::disconnectInternal, this, intCauseDisconnect); // @todo
+ SPIT_Handler::addCallable(o_Callable);
+ */
+ mDisconnectedByServer = true;
+ SProcessor::disconnectInternal(intCauseDisconnect); // @todo
+}
+
+//----- Watchdog ------
+/**
+ * The SPIT server sends a watchdog message at regular intervals. The client responds immediately with WatchdogAnswer
+ * Conversely, the client also sends a watchdog message at regular intervals and waits for a WatchdogAnswer message.
+ * This is used to check if the other side is still present.
+ * @param message
+ */
+void SProcessor::parseWatchdog(Message::Watchdog &message) { // @todo
+ // ESP_LOGD(TAG, "parse Watchdog ");
+ Message::WatchdogAnswer o_WatchdogAnswer;
+ // sendSPITMessage(o_WatchdogAnswer);
+}
+/**
+ * The SPIT server sends a watchdog message at regular intervals. The client responds immediately with WatchdogAnswer
+ * Conversely, the client also sends a watchdog message at regular intervals and waits for a WatchdogAnswer message.
+ * This is used to check if the other side is still present.
+ * @param message
+ */
+void SProcessor::parseWatchdogAnswer(Message::WatchdogAnswer &message) { // @todo
+ answerWatchdog(); // is also done by parseMessage
+}
+void SProcessor::sendWatchdog() { // @todo
+ int intResult{};
+ Message::Watchdog message;
+ // intResult = sendSPITMessage(message);
+ if (intResult < 0) {
+ ESP_LOGW("WDT", "Failed to send Watchdog msg");
+ }
+}
+void SProcessor::eventWatchdogLost() { // @todo
+ if (mConnectionStatus == Connection::TryConnection) {
+ disconnectInternal(Connection::NoneServer);
+ } else {
+ disconnectInternal(Connection::Lost);
+ }
+}
+
+//----- SPIT Project ------
+void SProcessor::parseReportProject(Message::ReportProject &message) { // @todo
+ ESP_LOGD(TAG, "parse ReportProject");
+ mServerProjectID = message.getProjectID();
+ mServerProjectName = message.getProjectName();
+ mServerFramesPerSecond = message.getFramesPerSecond();
+ mCallbacks.onProjectUpdate(ProjUpdate::ServerLoaded, mServerProjectID);
+
+ // Set all SPITTypes and SPITObjects confirmed = false
+ SType::setConfirmedFalse(mSpitTypes);
+ SObject::setConfirmedFalse(mSpitObjects);
+
+ // Send RequestProjectTransfer
+ Message::RequestProjectTransfer sMRequestProjectTransfer;
+ // if (sendSPITMessage(sMRequestProjectTransfer) < 0) {
+ // ESP_LOGD(TAG, "Client::parseReportProject could not send RequestProjectTransfer");
+ // }
+
+ // todo Don't send the ReportProject here it should be sended after parseEndProjectTransfer
+ // Send client's ReportProject
+ Message::ReportProject reportProject(mProjName, mProjName);
+ reportProject.setFramesPerSecond(0);
+ // if (sendSPITMessage(reportProject) < 0) {
+ // ESP_LOGD(TAG, "Client::parseReportProject could not send Client's ReportProject");
+ // }
+}
+void SProcessor::parseCloseProject(Message::CloseProject &p_CloseSPITProject) { // @todo
+ ESP_LOGD(TAG, "parse CloseProject");
+ string stringProjectID;
+ mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, p_CloseSPITProject.getProjectID());
+ SPlayer::clearPlayers();
+}
+
+string SProcessor::getServerProjectID() { return mServerProjectID; } // @todo
+string SProcessor::getServerProjectName() { return mServerProjectName; } // @todo
+int SProcessor::getServerFramesPerSecond() { return mServerFramesPerSecond; } // @todo
+
+void SProcessor::parseRequestProjectTransfer(Message::RequestProjectTransfer &message) { // @todo
+ ESP_LOGD(TAG, "parse RequestProjectTransfer");
+ // StartProjectTransfer
+ Message::StartProjectTransfer sMStartProjectTransfer;
+ // if (sendSPITMessage(sMStartProjectTransfer) < 0) {
+ // return;
+ // }
+
+ // send all listes SPITTypes
+ for (const auto& [key, value] : mSpitTypes.getRepo()) {
+ sendSPITTypeInternal(*value);
+ // fos::Task::delayMs(10);
+ }
+ for (auto& [key, value] : mSpitObjects.getRepo()) {
+ sendSPITObjectInternal(value.get());
+ // fos::Task::delayMs(10);
+ }
+
+ // EndProjectTransfer
+ Message::EndProjectTransfer sMEndProjectTransfer;
+ // sendSPITMessage(sMEndProjectTransfer);
+}
+
+/* NEW IMPLEMENTATION
+
+void SProcessor::parseRequestProjectTransfer(Message::RequestProjectTransfer* message) { // @todo
+// ESP_LOGD(TAG, "parse RequestProjectTransfer");
+ thread* o_ThreadSend;
+ o_ThreadSend = new thread(&this->sendProject, this);
+ // int intResult;
+ // Message::StartProjectTransfer* ptrSMStartProjectTransfer;
+ // Message::EndProjectTransfer* ptrSMEndProjectTransfer;
+ // int intCount;
+ // SPITType* ptrSPITType;
+ // SObject* ptrSPITObject;
+
+
+ // //StartProjectTransfer
+ // NotifyStartProjectTransfer_Client* o_RunnableStart = new NotifyStartProjectTransfer_Client(mSPITClientInterface);
+ // SPIT_Handler::addRunnable(o_RunnableStart);
+
+ // ptrSMStartProjectTransfer = new Message::StartProjectTransfer();
+ // intResult = sendSPITMessage(ptrSMStartProjectTransfer);
+ // if (intResult < 0) {
+ // return;
+ // }
+ // mWatchdog->answerWatchdog();
+ // {
+ // //send all listes SPITTypes
+ // unique_lock o_LockType(*SPITType::getMutex());
+ // intCount = SPITType::getSPITTypeCount();
+ // for (int i = 0; i < intCount; i++) {
+ // ptrSPITType = mSpitTypes.getEntry(i);
+ // if (ptrSPITType == nullptr) continue;
+ // intResult = sendSPITTypeInternal(ptrSPITType);
+ // if (intResult < 0) return;
+ // mWatchdog->answerWatchdog();
+ // this_thread::sleep_for(chrono::milliseconds(7));
+ // }
+ // }
+
+ // {
+ // unique_lock o_LockObject(*SObject::getMutex());
+ // intCount = mSpitObjects.getEntryCount();
+ // for (int i = 0; i < intCount; i++) {
+ // ptrSPITObject = mSpitObjects.getEntry(i);
+ // if (ptrSPITObject == nullptr) continue;
+ // intResult = sendSPITObjectInternal(ptrSPITObject);
+ // if (intResult < 0) return;
+ // mWatchdog->answerWatchdog();
+ // this_thread::sleep_for(chrono::milliseconds(7));
+ // }
+ // }
+
+ // //EndProjectTransfer
+ // ptrSMEndProjectTransfer = new Message::EndProjectTransfer();
+ // intResult = sendSPITMessage(ptrSMEndProjectTransfer);
+ // if (intResult < 0) {
+ // return;
+ // }
+ // mWatchdog->answerWatchdog();
+ // NotifyEndProjectTransfer_Client* o_RunnableEnd = new NotifyEndProjectTransfer_Client(mSPITClientInterface);
+ // SPIT_Handler::addRunnable(o_RunnableEnd);
+
+ // //Send act
+}
+*/
+
+// void SProcessor::sendProject(SClient *p_PtrSPIT_Client) { // @todo
+ // int intResult;
+ // Message::StartProjectTransfer* ptrSMStartProjectTransfer;
+ // Message::EndProjectTransfer* ptrSMEndProjectTransfer;
+ // int intCount;
+ // SPITType* ptrSPITType;
+ // SObject* ptrSPITObject;
+
+ // //StartProjectTransfer
+ // NotifyStartProjectTransfer_Client* o_RunnableStart = new NotifyStartProjectTransfer_Client(p_PtrSPIT_Client->getSPITClientInterface());
+ // SPIT_Handler::addRunnable(o_RunnableStart);
+
+ // ptrSMStartProjectTransfer = new Message::StartProjectTransfer();
+ // intResult = p_PtrSPIT_Client->sendSPITMessage(ptrSMStartProjectTransfer);
+ // if (intResult < 0) {
+ // return;
+ // }
+
+ // // mWatchdog->answerWatchdog();
+ // // {
+ // //send all listes SPITTypes
+ // // unique_lock o_LockType(*SPITType::getMutex());
+ // intCount = SPITType::getSPITTypeCount();
+ // for (int i = 0; i < intCount; i++) {
+ // ptrSPITType = mSpitTypes.getEntry(i);
+ // if (ptrSPITType == nullptr) continue;
+ // if (ptrSPITType->getCreatedByClient() == false) continue;
+ // intResult = p_PtrSPIT_Client->sendSPITTypeInternal(ptrSPITType);
+ // if (intResult < 0) return;
+ // // mWatchdog->answerWatchdog();
+ // this_thread::sleep_for(chrono::milliseconds(7));
+ // }
+ // // }
+
+ // // {
+ // // unique_lock o_LockObject(*SObject::getMutex());
+ // intCount = mSpitObjects.getEntryCount();
+ // for (int i = 0; i < intCount; i++) {
+ // ptrSPITObject = mSpitObjects.getEntry(i);
+ // if (ptrSPITObject == nullptr) continue;
+ // if (ptrSPITObject->getCreatedByClient() == false) continue;
+ // intResult = p_PtrSPIT_Client->sendSPITObjectInternal(ptrSPITObject);
+ // if (intResult < 0) return;
+ // // mWatchdog->answerWatchdog();
+ // this_thread::sleep_for(chrono::milliseconds(7));
+ // }
+ // // }
+
+ // //EndProjectTransfer
+ // ptrSMEndProjectTransfer = new Message::EndProjectTransfer();
+ // intResult = p_PtrSPIT_Client->sendSPITMessage(ptrSMEndProjectTransfer);
+ // if (intResult < 0) {
+ // return;
+ // }
+ // // mWatchdog->answerWatchdog();
+ // NotifyEndProjectTransfer_Client* o_RunnableEnd = new NotifyEndProjectTransfer_Client(p_PtrSPIT_Client->getSPITClientInterface());
+ // SPIT_Handler::addRunnable(o_RunnableEnd);
+
+ // //Send act
+// }
+
+void SProcessor::parseStartProjectTransfer(Message::StartProjectTransfer &message) { // @todo
+ mCallbacks.onProjectUpdate(ProjUpdate::StartTransfer, mServerProjectID);
+}
+void SProcessor::parseEndProjectTransfer(Message::EndProjectTransfer &message) { // @todo
+ SObject::clearUnconfirmedObjects(mSpitObjects);
+ mCallbacks.onProjectUpdate(ProjUpdate::EndTransfer, mServerProjectID);
+
+ // Send Message::ReportProject after the mSPITClientInterface is notfied of EndProjectTransfer
+ Message::ReportProject reportSPITProject(mProjName, mProjName);
+ reportSPITProject.setFramesPerSecond(0);
+ // if (sendSPITMessage(reportSPITProject) < 0) {
+ // ESP_LOGD(TAG, "Client::parseReportProject could not send Client's ReportProject");
+ // }
+}
+
+//----- SPIT Types ------
+void SProcessor::parseReportType(Message::ReportType &message) { // @todo
+ ESP_LOGD(TAG, "parse ReportType ID %s Name %s",message.getID().c_str(), message.getName().c_str());
+ SType *sType;
+ bool boolNew = false;
+ bool boolChanged = false;
+ {
+ if (message.getServerRemote() == false) {
+ sType = mSpitTypes.getEntry(message.getID());
+ if (sType == nullptr) {
+ // The user's app may veto the SPITType
+ bool createdByClient = false;
+ if (sType) {
+ createdByClient = sType->getCreatedByClient();
+ }
+
+ if (mCallbacks.onCheckSpitTypeVeto(false, createdByClient) == false) {
+ ESP_LOGW(TAG, "TypeVeto %s / %s", message.getID().c_str(), message.getName().c_str());
+ return;
+ }
+ auto spitType = make_unique(message.getID());
+ sType = spitType.get();
+ mSpitTypes.addEntry(move(spitType));
+ boolNew = true;
+ }
+ } else {
+ sType = mRemoteSpitTypes.getEntry(message.getID());
+ if (sType == nullptr) {
+ auto spitType = make_unique(message.getID());
+ sType = spitType.get();
+ mRemoteSpitTypes.addEntry(move(spitType));
+ boolNew = true;
+ }
+ }
+ if (!sType->setMessageOP(message)) {
+ // SPITType is not changable -> send back to the server
+ sendSPITTypeInternal(*sType);
+ return;
+ }
+
+ auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed;
+ // add or change SPITType
+ mCallbacks.onSpitType(eventType, sType->ServerRemote.get(), *sType);
+
+ if (sType != nullptr) {
+ if (sType->setConfirmed(true) == true || boolChanged == true) {
+ sendSPITTypeInternal(*sType);
+ }
+ }
+ }
+}
+void SProcessor::parseRemoveSPITType(Message::RemoveType &message) { // @todo
+ ESP_LOGD(TAG, "parse RemoveType %s", message.getID().c_str());
+ bool boolRemote = false;
+ string stringSPITTypeID = message.getID();
+
+ SType *ptrSPITType = mRemoteSpitTypes.getEntry(stringSPITTypeID);
+ if (!ptrSPITType) {
+ boolRemote = true;
+ } else {
+ ptrSPITType = mSpitTypes.getEntry(stringSPITTypeID);
+ if (!ptrSPITType) {
+ boolRemote = false;
+ } else {
+ // No SPITType with stringSPITTypeID is listet
+ return;
+ }
+ }
+
+ if (ptrSPITType->getCreatedByClient() && ptrSPITType->Fixed.get()) {
+ // the SPITyte is created by client himself and it is fixed -> don't remove the SPITType!!
+ // Send the SPITTyp back to the server
+ sendSPITTypeInternal(*ptrSPITType);
+ return;
+ }
+
+ mCallbacks.onSpitType(ObjectEvent::Deleted, boolRemote, *ptrSPITType);
+ if (boolRemote == false) {
+ mSpitTypes.removeEntry(*ptrSPITType);
+ } else {
+ mRemoteSpitTypes.removeEntry(*ptrSPITType);
+ }
+}
+
+/**
+ * If a client has changed a SPITType, it should send it to the server to transmit the changes.
+ * If the SPITType is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the changes.
+ * @param p_SPITType the pointer to the changed SPITType
+ * @return 0 = is sended, -1 = is not sended
+ */
+int SProcessor::sendSPITTypeInternal(SType &p_SPITType) { // @todo
+ Message::ReportType sMReportSPITType;
+ p_SPITType.fillMessageOP(sMReportSPITType);
+ // return sendSPITMessage(sMReportSPITType);
+ return 1;
+}
+
+/**
+ * Change an existing SPIT_Type.
+ * @param p_SPITType the SPITType vont
+ * @return true = changed, false = not changed maybe p_SPITType is NULL or the SPITType doesn't exists
+ */
+bool SProcessor::changeSPITType(SType *p_SPITType) { // @todo
+ if (p_SPITType == nullptr)
+ return false;
+ SType *ptrSPITType = mSpitTypes.getEntry(p_SPITType->getID());
+ if (ptrSPITType == nullptr)
+ return false;
+
+ ptrSPITType->DefaultDelay.set(p_SPITType->DefaultDelay.get());
+ ptrSPITType->DefaultDuration.set(p_SPITType->DefaultDuration.get());
+ ptrSPITType->Fixed.set(p_SPITType->Fixed.get());
+ ptrSPITType->GroupName.set(p_SPITType->GroupName.get());
+ ptrSPITType->Name.set(p_SPITType->Name.get());
+ ptrSPITType->ProjectIndepended.set(p_SPITType->ProjectIndepended.get());
+
+ mCallbacks.onSpitType(ObjectEvent::Changed, false, *ptrSPITType);
+ sendSPITTypeInternal(*ptrSPITType);
+
+ return true;
+}
+
+/**
+ * If a client has removed a SPITType where id == p_SPITTypeID, it should send it to the server.
+ * The corresponding SPITType if listet in SPITType will be deleted.
+ * An eventRemoveSPITType will occur.
+ * If a connection to a SPITServer is established, the SPITServer may dicard the deletion an an eventSPITType will occur
+ * -> the SPITType will be listet again.
+ * @param p_SPITType the id of the SPITType ro remove
+ * @return 0 = is sended, -1 = is not sended
+ */
+int SProcessor::removeSPITType(string p_SPITTypeID) { // @todo
+ if (p_SPITTypeID.length() <= 0)
+ return -1;
+ SType *ptrSPITType;
+ {
+ ptrSPITType = mSpitTypes.getEntry(p_SPITTypeID);
+ if (ptrSPITType == nullptr)
+ return -1;
+ Message::RemoveType sMRemoveSPITType;
+ ptrSPITType->fillMessageOP(sMRemoveSPITType);
+ mCallbacks.onSpitType(ObjectEvent::Deleted, false, *ptrSPITType);
+ mSpitTypes.removeEntry(*ptrSPITType);
+ // return sendSPITMessage(sMRemoveSPITType);
+ return 1;
+ }
+ return -1;
+}
+
+SType *SProcessor::createTypeFixed(string iD, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration) { // @todo
+ return createType(iD, p_GroupName, p_Name, p_DefaultDelay, p_DefaultDuration, true, true);
+}
+
+SType *SProcessor::createType(string p_ID, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration, bool p_FIxed, bool p_ProjectIndepended) { // @todo
+ bool boolNew;
+ SType *ptrSPITType = mSpitTypes.getEntry(p_ID);
+ if (ptrSPITType == nullptr) {
+ auto spitType = make_unique(p_ID, p_GroupName, p_Name, p_FIxed, p_ProjectIndepended, p_DefaultDelay, p_DefaultDuration);
+ ptrSPITType = spitType.get();
+ mSpitTypes.addEntry(move(spitType));
+ ptrSPITType->setCreatedByClient(true);
+ boolNew = true;
+ } else {
+ ptrSPITType->GroupName.set(p_GroupName);
+ ptrSPITType->Name.set(p_Name);
+ ptrSPITType->Fixed.set(p_FIxed);
+ ptrSPITType->ProjectIndepended.set(p_ProjectIndepended);
+ ptrSPITType->DefaultDelay.set(p_DefaultDelay);
+ ptrSPITType->DefaultDuration.set(p_DefaultDuration);
+ boolNew = false;
+ }
+
+ auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed;
+ mCallbacks.onSpitType(eventType, false, *ptrSPITType);
+ sendSPITTypeInternal(*ptrSPITType);
+ return ptrSPITType;
+}
+
+//----- SPIT Objects ------
+void SProcessor::parseReportSPITObject(Message::ReportObject &message) { // @todo
+ ESP_LOGD(TAG, "parse ReportObject %s", message.getID().c_str());
+ SObject *ptrSPITObject;
+ SType *ptrSPITType;
+ bool boolNew = false;
+ bool boolRemote = false;
+ bool boolChanged = false;
+ {
+ ESP_LOGD(TAG, "parse ReportObject %s / %s", message.getID().c_str(), message.getName().c_str());
+ if (message.getServerRemote() == false) {
+ boolRemote = false;
+ ptrSPITObject = mSpitObjects.getEntry(message.getID());
+ ptrSPITType = mSpitTypes.getEntry(message.getSPITTypeID());
+
+ if (ptrSPITType == nullptr) {
+ // No associated SPITType found
+ if (ptrSPITObject != nullptr) {
+ // SpitObject exists but has no corresponding SPITType -> remove the SPITObject without sending a message
+ // Maybe the SPITObject has changed the SPITTypeID to a SPITTypeID of another board
+ mSpitObjects.removeEntry(*ptrSPITObject);
+ }
+ return;
+ }
+ bool isKnownType = ptrSPITType != nullptr;
+ if (ptrSPITObject == nullptr) {
+ // The user's app my veto the SPITType
+ if (mCallbacks.onCheckSpitObjectVeto(isKnownType) == false) {
+ ESP_LOGW(TAG, "ObjectVeto %s / %s", message.getID().c_str(), message.getName().c_str());
+ return;
+ }
+ auto spitObj = make_unique(message.getID());
+ ptrSPITObject = spitObj.get();
+ mSpitObjects.addEntry(move(spitObj));
+ boolNew = true;
+ } else {
+ // The user's app my veto the SPITType
+ if (mCallbacks.onCheckSpitObjectVeto(isKnownType) == false) {
+ // SpitObject exists and User APp denied the SPITObject -> remove the SPITObject without sending a message
+ mSpitObjects.removeEntry(*ptrSPITObject);
+ ESP_LOGW(TAG, "TypeVeto %s / %s", message.getID().c_str(), message.getName().c_str());
+ return;
+ }
+ }
+ } else {
+ boolRemote = true;
+ ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID());
+ ptrSPITType = mRemoteSpitTypes.getEntry(message.getSPITTypeID());
+ if (ptrSPITType == nullptr) {
+ // No associated SPITType found
+ return;
+ }
+ if (ptrSPITObject == nullptr) {
+ auto spitObj = make_unique(message.getID());
+ ptrSPITObject = spitObj.get();
+ mRemoteSpitObjects.addEntry(move(spitObj));
+ boolNew = true;
+ }
+ }
+
+ if (!ptrSPITObject->setMessageOP(&message)) {
+ ESP_LOGE(TAG, "Change not allowed");
+ // setMessageOP error - the SPITObject can't be changed, it may be fixed and crated by this client
+ sendSPITObjectInternal(ptrSPITObject);
+ return;
+ }
+
+ if (boolRemote == false) {
+ // set the virtual action assignment
+ ptrSPITObject->setActionAssignedType(ptrSPITType->ActionAssigned.get());
+ }
+
+ auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed;
+ mCallbacks.onSpitObject(eventType, boolRemote, *ptrSPITType, *ptrSPITObject);
+
+ if (ptrSPITObject->setConfirmed(true) == true || boolChanged == true) {
+ // Confirmation has changed
+ sendSPITObjectInternal(ptrSPITObject);
+ }
+ }
+}
+void SProcessor::parseRemoveSPITObject(Message::RemoveObject &message) { // @todo
+ ESP_LOGD(TAG, "parse RemoveObject %s", message.getID().c_str());
+ SObject *ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID());
+ if (ptrSPITObject != nullptr) {
+ SType *ptrSPITType = mRemoteSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get());
+ if (ptrSPITType != nullptr) {
+ mCallbacks.onSpitObject(ObjectEvent::Deleted, true, *ptrSPITType, *ptrSPITObject);
+ }
+ mRemoteSpitObjects.removeEntry(*ptrSPITObject);
+ } else {
+ // call removeSPITObject, this will notify the server that the object is removed
+ removeSPITObject(message.getID());
+ }
+}
+
+int SProcessor::sendSPITObjectInternal(SObject *ptrSPITObject) { // @todo
+ if (ptrSPITObject == nullptr)
+ return -1;
+ Message::ReportObject sMReportSPITObject;
+ ptrSPITObject->fillMessageOP(sMReportSPITObject);
+
+ // return sendSPITMessage(sMReportSPITObject);
+ return 1;
+}
+/**
+ * When the client changes an existing SPITObject (normally the client should not do this), then he should send the changes to the SPITServer.
+ * An eventSPITObject occurs.
+ * The SPITServer may discard the changes and a second eventSPITObject occurs to correct the changes.
+ * @param obj the pointer to the changed SPITObject.
+ * CAUTION: The SPITObject must already exist.
+ * @return true = SPITObject is changed, false = not changed, maybe obj is NULL or the SPITObject doesn't exists
+ */
+bool SProcessor::changeSPITObject(SObject *obj) { // @todo
+ if (obj == nullptr)
+ return false;
+ SObject *ptrSPITObject;
+ SType *ptrSPITType;
+ {
+ ptrSPITObject = mSpitObjects.getEntry(obj->getID());
+ if (ptrSPITObject == nullptr)
+ return false;
+ ptrSPITType = mSpitTypes.getEntry(obj->getID());
+ if (ptrSPITObject == nullptr)
+ return false;
+
+ ptrSPITObject->setActionAssigned(obj->getActionAssigned());
+ ;
+ ptrSPITObject->Delay.set(obj->Delay.get());
+ ptrSPITObject->Duration.set(obj->Delay.get());
+ ptrSPITObject->Fixed.set(obj->Fixed.get());
+ ptrSPITObject->FrameFadeInLength.set(obj->FrameFadeInLength.get());
+ ptrSPITObject->FrameFadeOutLength.set(obj->FrameFadeOutLength.get());
+ ptrSPITObject->FrameLength.set(obj->FrameLength.get());
+ ptrSPITObject->FrameStart.set(obj->FrameStart.get());
+ ptrSPITObject->Name.set(obj->Name.get());
+ ptrSPITObject->Remark.set(obj->Remark.get());
+ ptrSPITObject->SPITTypeID.set(obj->SPITTypeID.get());
+ ptrSPITObject->ServerParams.set(obj->ServerParams.get());
+ ptrSPITObject->Track.set(obj->Track.get());
+ ptrSPITObject->ValueFactor.set(obj->ValueFactor.get());
+ ptrSPITObject->ValueUse.set(obj->ValueUse.get());
+
+ mCallbacks.onSpitObject(ObjectEvent::Changed, false, *ptrSPITType, *ptrSPITObject);
+ sendSPITObjectInternal(ptrSPITObject);
+ }
+ return true;
+}
+
+/**
+ * When the client wants to remove a SPITObject with id == p_SPITObjectID (normally the client should not do this), then he should send it to the SPITServer.
+ * The corresponding SPITObject if listet in SPITObject will be deleted.
+ * An eventRemoveSPITType will occur.
+ * If an connection to a SPITServer is established, the SPITServer may discard the deletion and an eventSPITObject occurs
+ * -> the SPITObject is listet again.
+ * @param objId the id of the SPITObject to remove.
+ * @return 0 = sended to the SPITServer, -1 = not sended to the SPITServer or nos SPITObject with id == objId exists.
+ */
+int SProcessor::removeSPITObject(string objId) { // @todo
+ if (objId.length() <= 0)
+ return -1;
+ SType *ptrSPITType;
+ SObject *ptrSPITObject;
+ {
+ Message::RemoveObject sMRemoveSPITObject;
+
+ ptrSPITObject = mSpitObjects.getEntry(objId);
+ if (ptrSPITObject == nullptr)
+ return -1;
+ ptrSPITType = mSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get());
+ if (ptrSPITType == nullptr)
+ return -1;
+ ptrSPITObject->fillMessageOP(sMRemoveSPITObject);
+ mCallbacks.onSpitObject(ObjectEvent::Deleted, false, *ptrSPITType, *ptrSPITObject);
+ mSpitObjects.removeEntry(*ptrSPITObject);
+ // return sendSPITMessage(sMRemoveSPITObject);
+ return 1;
+ }
+ return -1;
+}
+
+//----- Play SPIT Objects ------
+
+void SProcessor::parsePlaySPITStart(Message::PlayStart &message) { // @todo
+ ESP_LOGD(TAG, "parse PlayStart ID: %s Name: %s Running: %d", message.getPlayerID().c_str(), message.getPlayerName().c_str(), (int)message.getPlayerIsRunning());
+ SPlayer &spitPlayer = SPlayer::getSPITPlayer(message.getPlayerID());
+ spitPlayer.setIsRunning(message.getPlayerIsRunning());
+ spitPlayer.setName(message.getPlayerName());
+ spitPlayer.setType(message.getPlayerType());
+ spitPlayer.setTime(message.getTime());
+ spitPlayer.startPlaySequence();
+
+ mCallbacks.onPlay(spitPlayer.getID(), spitPlayer.getName(), spitPlayer.getType(), spitPlayer.getIsRunning(), spitPlayer.getTime());
+}
+void SProcessor::parsePlaySPITObject(Message::PlayObject &message) { // @todo
+
+ SPlayer &ptrSPITPlayer = SPlayer::getSPITPlayer(message.getPlayerID());
+ SObject *ptrSPITObject = mSpitObjects.getEntry(message.getSPITObjectID());
+
+ if (ptrSPITObject == nullptr) {
+ return;
+ }
+ SPlayer::PlayType *ptrPlaySPITType = ptrSPITPlayer.addTypePlaying(ptrSPITObject->SPITTypeID.get());
+ if (ptrPlaySPITType == nullptr) {
+ return;
+ }
+ ptrPlaySPITType->setPlayerIsRunning(ptrSPITPlayer.getIsRunning());
+ ptrPlaySPITType->addValue(((double)message.getValue() / 1000000), ((double)ptrSPITObject->ValueFactor.get() / 1000000));
+}
+
+void SProcessor::parsePlaySPITEnd(Message::PlayEnd &message) { // @todo
+ SPlayer &ptrSPITPlayer = SPlayer::getSPITPlayer(message.getPlayerID());
+
+ auto &ptrPlaySPITTypes = ptrSPITPlayer.getPlaySPITTypes();
+ for (auto i = ptrPlaySPITTypes.begin(); i != ptrPlaySPITTypes.end(); i++) {
+ SPlayer::PlayType *ptrPlaySPITType = i->second.get();
+ bool boolStarted = ptrPlaySPITType->getIsNew();
+ bool boolStopped = (ptrPlaySPITType->getIsPlayed() == false);
+ SType *ptrSPITType = mSpitTypes.getEntry(ptrPlaySPITType->getSPITTypeID());
+ if (ptrSPITType == nullptr) {
+ // set isplayed to false, the ptrPlayObject will be removed by ptrSPITPlayer.endPlaySequence()
+ ptrPlaySPITType->setIsPlayed(false);
+ continue;
+ }
+ mCallbacks.onPlaySpitType(ptrPlaySPITType->getPlayerID(), ptrPlaySPITType->getSPITTypeID(), ptrPlaySPITType->getPlayerIsRunning(), boolStarted, boolStopped, ptrPlaySPITType->getValue());
+ }
+ ptrSPITPlayer.endPlaySequence();
+}
+
+void SProcessor::parseReportPlayStatus(Message::ReportPlayStatus &message) { // @todo
+ SType *ptrSPITType = NULL;
+
+ SObject *ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID());
+ if (ptrSPITObject == nullptr) {
+ ptrSPITObject = mSpitObjects.getEntry(message.getID());
+ if (ptrSPITObject == nullptr) {
+ return;
+ }
+ }
+ if (ptrSPITObject->ServerRemote.get() == false) {
+ ptrSPITType = mSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get());
+ } else {
+ ptrSPITType = mRemoteSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get());
+ }
+
+ if (ptrSPITType == nullptr) {
+ return;
+ }
+ mCallbacks.onPlayRemoteObjectStatus(*ptrSPITType, *ptrSPITObject, message.getFrameInsideObject(), message.getValue());
+}
+
+//--------- Remote ----------
+
+/**
+ * Send a remote control command to the SPITServer.
+ * There may be different command types:
+ * a) Some don't use value e.g. go to next scene, olay a jingle
+ * b) Some use values e.g. the main sound fader
+ * @param p_SPITObjectID the id of the remote SPITObject (this represents the remote control command)
+ * @param valuePpm the value in ppm
+ * in case a) the value is ignored
+ * in case b) the value is used
+ * @param valueFlag indicates how the server should use valuePpm:
+ * VALUEFLAG_DIRECT (0x00) The server overwrites its existing value with p_Value
+ * VALUEFLAG_INCREASE (0x01) The server increases his existing value by valuePpm
+ * VALUEFLAG_DECREASE (0x01) The server decreases his existing value by valuePpm
+ */
+void SProcessor::sendRemoteObject(string p_SPITObjectID, int valuePpm, char valueFlag) { // @todo
+ SObject *ptrRemoteSPITObject = mRemoteSpitObjects.getEntry(p_SPITObjectID);
+ if (ptrRemoteSPITObject == nullptr)
+ return;
+
+ Message::PlayStart playSPITStart(mGuid, mProjName, PLAYERTYPE_DISCRETE);
+ playSPITStart.setPlayerIsRunning(false);
+ playSPITStart.setTime(0);
+ // sendSPITMessage(playSPITStart);
+
+ Message::PlayObject playSPITObject;
+ playSPITObject.setID(ptrRemoteSPITObject->getID());
+ playSPITObject.setPlayPrePosition(false);
+ playSPITObject.setPlayerID(mGuid);
+ playSPITObject.setValue(valuePpm);
+ playSPITObject.setValueFlag(valueFlag);
+ // sendSPITMessage(playSPITObject);
+
+ Message::PlayEnd playSPITEnd(mGuid);
+ // sendSPITMessage(playSPITEnd);
+}
+
+
+
+}
\ No newline at end of file
diff --git a/components/spit/test/CMakeLists.txt b/components/spit/test/CMakeLists.txt
new file mode 100644
index 0000000..1edbbf9
--- /dev/null
+++ b/components/spit/test/CMakeLists.txt
@@ -0,0 +1,5 @@
+idf_component_register(
+ SRC_DIRS "."
+ INCLUDE_DIRS "."
+ REQUIRES cmock spit
+)
diff --git a/components/spit/test/test_spit_client.cpp b/components/spit/test/test_spit_client.cpp
new file mode 100644
index 0000000..254eff8
--- /dev/null
+++ b/components/spit/test/test_spit_client.cpp
@@ -0,0 +1,123 @@
+/**
+ * @file test_mean.cpp
+ * @author Gustice
+ * @brief Hardware bound unit-Test example device
+ */
+
+#include "spit_client.hpp"
+#include "unity.h"
+#include
+#include
+#include
+
+using namespace spit;
+using namespace std;
+
+queue callbackEvents;
+
+class ClientMock {
+ public:
+ void onServerEvent(SClient::ServerEvent event, const SadDetectedServer &detectedServer) {
+ }
+ void onConnectionStatus(string serverID, string serverComputerName, string serverName, int serverStepTime, SClient::Connection connectionStatus, SClient::Connection oldConnectionStatus) {
+ }
+ void onProjectUpdate(SClient::ProjUpdate state, string projectId) {
+ }
+ void onSpitType(SClient::ObjectEvent event, bool isRemote, const SType &spitType) {
+ }
+ void onSpitObject(SClient::ObjectEvent event, bool isRemote, const SType &spitType, const SObject &spitObject) {
+ }
+ void onPlay(string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) {
+ }
+ void onPlaySpitType(string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value) {
+ }
+ void onPlayRemoteObjectStatus(const SType &spitType, const SObject &spitObject, uint64_t p_FrameInsideObject, int value) {
+ }
+ bool onCheckSpitTypeVeto(bool knownType, bool createdByClient) {
+ return true;
+ }
+ bool onCheckSpitObjectVeto(bool knownType) {
+ return true;
+ }
+};
+
+class SocketMock : public ISocket {
+ public:
+ SocketMock(IpAddress ip) : ISocket(ip) {}
+
+ int sendMessage(const char *message, int length) override {
+ return 0;
+ }
+ int receiveMessage(char *bu1ffer, int bufferLength, string *serverIp) const override {
+ return 0;
+ }
+ void setConnectionParams(const string &serverIp, const string &serverPort, const string &clientIp, const string &clientPort) override {
+ }
+ int bindSocket(string clientIp, string clientPort) override {
+ return 0;
+ }
+ int setBroadcast(bool broadcast) const override {
+ return 0;
+ }
+ int sendMessageTo(const string &ip, const string &port, const char *message, int msgLength) override {
+ return 0;
+ }
+};
+
+// class SpitClientFix {
+// protected:
+// static ClientMock client;
+// ISocket::IpAddress ip{"10.10.0.1", "255.255.255.0"};
+// SocketMock socket{ip};
+// SClient::Callbacks callbacks{
+// .onServerEvent = [&](SClient::ServerEvent event, const SadDetectedServer &detectedServer){client.onServerEvent(event, detectedServer);} ,
+// .onConnectionStatus = [&](string serverID, string serverComputerName, string serverName, int serverStepTime, SClient::Connection connectionStatus, SClient::Connection oldConnectionStatus){client.onConnectionStatus(serverID, serverComputerName, serverName, serverStepTime, connectionStatus, oldConnectionStatus);} ,
+// .onProjectUpdate = [&](SClient::ProjUpdate state, string projectId){client.onProjectUpdate(state, projectId);} ,
+// .onSpitType = [&](SClient::ObjectEvent event, bool isRemote, const SType &spitType){client.onSpitType(event, isRemote, spitType);} ,
+// .onSpitObject = [&](SClient::ObjectEvent event, bool isRemote, const SType &spitType, const SObject &spitObject){client.onSpitObject(event, isRemote, spitType, spitObject);} ,
+// .onPlay = [&](string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames){client.onPlay(playerID, playerName, playerType, playerIsRunning, timeFrames);} ,
+// .onPlaySpitType = [&](string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value){client.onPlaySpitType(playerID, spitTypeID, playerIsRunning, started, ended, value);} ,
+// .onPlayRemoteObjectStatus = [&](const SType &spitType, const SObject &spitObject, uint64_t p_FrameInsideObject, int value){client.onPlayRemoteObjectStatus( spitType, spitObject, p_FrameInsideObject, value);} ,
+// .onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient){return client.onCheckSpitTypeVeto(knownType, createdByClient);} ,
+// .onCheckSpitObjectVeto = [&](bool knownType){return client.onCheckSpitObjectVeto(knownType);}
+// };
+// SClient sut{"sut", "sutProj", socket, callbacks};
+// };
+
+TEST_CASE("Full Connect precedure", "[spit][init]") {
+ static ClientMock client;
+ ISocket::IpAddress ip{"10.10.0.1", "255.255.255.0"};
+ SocketMock socket{ip};
+ SClient::Callbacks callbacks{
+ .onServerEvent = [&](SClient::ServerEvent event, const SadDetectedServer &detectedServer) { client.onServerEvent(event, detectedServer); },
+ .onConnectionStatus = [&](string serverID, string serverComputerName, string serverName, int serverStepTime, SClient::Connection connectionStatus, SClient::Connection oldConnectionStatus) { client.onConnectionStatus(serverID, serverComputerName, serverName, serverStepTime, connectionStatus, oldConnectionStatus); },
+ .onProjectUpdate = [&](SClient::ProjUpdate state, string projectId) { client.onProjectUpdate(state, projectId); },
+ .onSpitType = [&](SClient::ObjectEvent event, bool isRemote, const SType &spitType) { client.onSpitType(event, isRemote, spitType); },
+ .onSpitObject = [&](SClient::ObjectEvent event, bool isRemote, const SType &spitType, const SObject &spitObject) { client.onSpitObject(event, isRemote, spitType, spitObject); },
+ .onPlay = [&](string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) { client.onPlay(playerID, playerName, playerType, playerIsRunning, timeFrames); },
+ .onPlaySpitType = [&](string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value) { client.onPlaySpitType(playerID, spitTypeID, playerIsRunning, started, ended, value); },
+ .onPlayRemoteObjectStatus = [&](const SType &spitType, const SObject &spitObject, uint64_t p_FrameInsideObject, int value) { client.onPlayRemoteObjectStatus(spitType, spitObject, p_FrameInsideObject, value); },
+ .onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient) { return client.onCheckSpitTypeVeto(knownType, createdByClient); },
+ .onCheckSpitObjectVeto = [&](bool knownType) { return client.onCheckSpitObjectVeto(knownType); }};
+ SClient sut{"sut", "sutProj", socket, callbacks};
+
+ // tood connect - Response - Request project
+
+ // Transfer items liveSHOW -> Device
+
+ {
+ Message::ReportType t1;
+ t1.setConfirmed(false);
+ t1.setID("type1Id#");
+ t1.setFixed(true);
+ t1.setServerRemote("serverId");
+ t1.setServerProjectIndepended(true);
+ t1.setGroupName("sGroup");
+ t1.setName("type1Name");
+ t1.setDelay(100);
+ t1.setDuration(200);
+
+
+ socket.
+ }
+}
\ No newline at end of file
diff --git a/components/spit/uTest/spitClientTest.cpp b/components/spit/uTest/spitClientTest.cpp
deleted file mode 100644
index 55dc430..0000000
--- a/components/spit/uTest/spitClientTest.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @file spitRepoTest.cpp
- * @author Gustice
- * @brief
- */
-
-#include "doctest/doctest.h"
-#include
-#include
-
-#include "spit_client.hpp"
-
-using namespace spit;
-using namespace std;
-
-class ClientMock {
- public:
- void onServerEvent(SClient::ServerEvent event, const SadDetectedServer &detectedServer) {
- }
- void onConnectionStatus(string serverID, string serverComputerName, string serverName, int serverStepTime, SClient::Connection connectionStatus, SClient::Connection oldConnectionStatus) {
- }
- void onProjectUpdate(SClient::ProjUpdate state, string projectId) {
- }
- void onSpitType(SClient::ObjectEvent event, bool isRemote, const SType &spitType) {
- }
- void onSpitObject(SClient::ObjectEvent event, bool isRemote, const SType &spitType, const SObject &spitObject) {
- }
- void onPlay(string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) {
- }
- void onPlaySpitType(string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value) {
- }
- void onPlayRemoteObjectStatus(const SType &spitType, const SObject &spitObject, uint64_t p_FrameInsideObject, int value) {
- }
- bool onCheckSpitTypeVeto(bool knownType, bool createdByClient) {
- }
- bool onCheckSpitObjectVeto(bool knownType) {
- }
-};
-
-class SocketMock : public ISocket {
- public:
- SocketMock(IpAddress ip) : ISocket(ip) {}
-
- int sendMessage(const char *message, int length) override {
- }
- int receiveMessage(char *bu1ffer, int bufferLength, string *serverIp) const override {
- }
- void setConnectionParams(const string &serverIp, const string &serverPort, const string &clientIp, const string &clientPort) override {
- }
- int bindSocket(string clientIp, string clientPort) override {
- }
- int setBroadcast(bool broadcast) const override {
- }
- int sendMessageTo(const string &ip, const string &port, const char *message, int msgLength) override {
- }
-};
-
-class SpitClientFix {
- protected:
- static ClientMock client;
- ISocket::IpAddress ip{"10.10.0.1", "255.255.255.0"};
- SocketMock socket{ip};
- SClient::Callbacks callbacks{
- .onServerEvent = [&](SClient::ServerEvent event, const SadDetectedServer &detectedServer){client.onServerEvent(event, detectedServer);} ,
- .onConnectionStatus = [&](string serverID, string serverComputerName, string serverName, int serverStepTime, SClient::Connection connectionStatus, SClient::Connection oldConnectionStatus){client.onConnectionStatus(serverID, serverComputerName, serverName, serverStepTime, connectionStatus, oldConnectionStatus);} ,
- .onProjectUpdate = [&](SClient::ProjUpdate state, string projectId){client.onProjectUpdate(state, projectId);} ,
- .onSpitType = [&](SClient::ObjectEvent event, bool isRemote, const SType &spitType){client.onSpitType(event, isRemote, spitType);} ,
- .onSpitObject = [&](SClient::ObjectEvent event, bool isRemote, const SType &spitType, const SObject &spitObject){client.onSpitObject(event, isRemote, spitType, spitObject);} ,
- .onPlay = [&](string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames){client.onPlay(playerID, playerName, playerType, playerIsRunning, timeFrames);} ,
- .onPlaySpitType = [&](string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value){client.onPlaySpitType(playerID, spitTypeID, playerIsRunning, started, ended, value);} ,
- .onPlayRemoteObjectStatus = [&](const SType &spitType, const SObject &spitObject, uint64_t p_FrameInsideObject, int value){client.onPlayRemoteObjectStatus( spitType, spitObject, p_FrameInsideObject, value);} ,
- .onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient){return client.onCheckSpitTypeVeto(knownType, createdByClient);} ,
- .onCheckSpitObjectVeto = [&](bool knownType){return client.onCheckSpitObjectVeto(knownType);}
- };
- SClient sut{"sut", "sutProj", socket, callbacks};
-};
-
-TEST_CASE_FIXTURE(SpitClientFix, "Typical use case") {
-}
diff --git a/components/spit/uTest/spitProcessorTest.cpp b/components/spit/uTest/spitProcessorTest.cpp
new file mode 100644
index 0000000..0195019
--- /dev/null
+++ b/components/spit/uTest/spitProcessorTest.cpp
@@ -0,0 +1,170 @@
+/**
+ * @file spitRepoTest.cpp
+ * @author Gustice
+ * @brief
+ */
+
+#include "doctest/doctest.h"
+#include
+#include
+#include
+
+#include "spit_processor.hpp"
+
+using namespace spit;
+using namespace std;
+static queue cbEvents;
+
+class ClientMock {
+ public:
+ void onServerEvent(SProcessor::ServerEvent event, const SadDetectedServer &detectedServer) {
+ }
+ void onConnectionStatus(string serverID, string serverComputerName, string serverName, int serverStepTime, SProcessor::Connection connectionStatus, SProcessor::Connection oldConnectionStatus) {
+ }
+ void onProjectUpdate(SProcessor::ProjUpdate state, string projectId) {
+ }
+ void onSpitType(SProcessor::ObjectEvent event, bool isRemote, const SType &sType) {
+ cbEvents.push(fmt::format("{}: {} {} {} {}", (int)event, isRemote, sType.getID(), sType.Name.get(), sType.GroupName.get()));
+ }
+ void onSpitObject(SProcessor::ObjectEvent event, bool isRemote, const SType &sType, const SObject &sObject) {
+ cbEvents.push(fmt::format("{}: {} {} {} {} {}", (int)event, isRemote, sType.getID(), sType.Name.get(), sObject.Name.get(), sObject.getID()));
+ }
+ void onPlay(string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) {
+ }
+ void onPlaySpitType(string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value) {
+ }
+ void onPlayRemoteObjectStatus(const SType &sType, const SObject &sObject, uint64_t p_FrameInsideObject, int value) {
+ }
+ bool onCheckSpitTypeVeto(bool knownType, bool createdByClient) {
+ cbEvents.push(fmt::format("veto check {}/{}", knownType, createdByClient));
+ return true;
+ }
+ bool onCheckSpitObjectVeto(bool knownType) {
+ return true;
+ }
+};
+
+class SpitClientFix {
+ protected:
+ ClientMock client;
+ SProcessor::Callbacks callbacks{
+ .onServerEvent = [&](SProcessor::ServerEvent event, const SadDetectedServer &detectedServer) { client.onServerEvent(event, detectedServer); },
+ .onConnectionStatus = [&](string serverID, string serverComputerName, string serverName, int serverStepTime, SProcessor::Connection connectionStatus, SProcessor::Connection oldConnectionStatus) { client.onConnectionStatus(serverID, serverComputerName, serverName, serverStepTime, connectionStatus, oldConnectionStatus); },
+ .onProjectUpdate = [&](SProcessor::ProjUpdate state, string projectId) { client.onProjectUpdate(state, projectId); },
+ .onSpitType = [&](SProcessor::ObjectEvent event, bool isRemote, const SType &t) { client.onSpitType(event, isRemote, t); },
+ .onSpitObject = [&](SProcessor::ObjectEvent event, bool isRemote, const SType &t, const SObject &o) { client.onSpitObject(event, isRemote, t, o); },
+ .onPlay = [&](string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) { client.onPlay(playerID, playerName, playerType, playerIsRunning, timeFrames); },
+ .onPlaySpitType = [&](string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value) { client.onPlaySpitType(playerID, spitTypeID, playerIsRunning, started, ended, value); },
+ .onPlayRemoteObjectStatus = [&](const SType &t, const SObject &o, uint64_t p_FrameInsideObject, int value) { client.onPlayRemoteObjectStatus(t, o, p_FrameInsideObject, value); },
+ .onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient) { return client.onCheckSpitTypeVeto(knownType, createdByClient); },
+ .onCheckSpitObjectVeto = [&](bool knownType) { return client.onCheckSpitObjectVeto(knownType); }};
+ SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks};
+};
+
+TEST_CASE_FIXTURE(SpitClientFix, "Spit types") {
+
+ {
+ Message::ReportType t;
+ t.setConfirmed(false);
+ t.setID("type1Id#Rem");
+ t.setFixed(true);
+ t.setServerRemote(true);
+ t.setServerProjectIndepended(true);
+ t.setGroupName("sGroup");
+ t.setName("type1Name");
+ t.setDelay(100);
+ t.setDuration(200);
+ sut.checkParseMessageData(sut.createMessage(t));
+ }
+ CHECK_MESSAGE(cbEvents.front() == "0: true type1Id#Rem type1Name sGroup", cbEvents.front());
+ cbEvents.pop();
+
+ {
+ Message::ReportType t;
+ t.setConfirmed(false);
+ t.setID("type2Id#Rem");
+ t.setFixed(true);
+ t.setServerRemote(true);
+ t.setServerProjectIndepended(true);
+ t.setGroupName("sGroup");
+ t.setName("type2Name");
+ t.setDelay(100);
+ t.setDuration(200);
+ sut.checkParseMessageData(sut.createMessage(t));
+ }
+ CHECK_MESSAGE(cbEvents.front() == "0: true type2Id#Rem type2Name sGroup", cbEvents.front());
+ cbEvents.pop();
+
+ {
+ Message::ReportType t;
+ t.setConfirmed(false);
+ t.setID("type1Id#Rem");
+ t.setFixed(true);
+ t.setServerRemote(true);
+ t.setServerProjectIndepended(true);
+ t.setGroupName("sGroup");
+ t.setName("type1Name");
+ t.setDelay(200);
+ t.setDuration(300);
+ sut.checkParseMessageData(sut.createMessage(t));
+ }
+ CHECK_MESSAGE(cbEvents.front() == "1: true type1Id#Rem type1Name sGroup", cbEvents.front());
+ cbEvents.pop();
+
+ CHECK(cbEvents.empty());
+
+ // Local Objects
+
+ {
+ Message::ReportType t;
+ t.setConfirmed(false);
+ t.setID("type1Id#Loc");
+ t.setFixed(true);
+ t.setServerRemote(false);
+ t.setServerProjectIndepended(true);
+ t.setGroupName("sGroup");
+ t.setName("type1Name");
+ t.setDelay(100);
+ t.setDuration(200);
+ sut.checkParseMessageData(sut.createMessage(t));
+ }
+ CHECK_MESSAGE(cbEvents.front() == "veto check false/false", cbEvents.front());
+ cbEvents.pop();
+ CHECK_MESSAGE(cbEvents.front() == "0: false type1Id#Loc type1Name sGroup", cbEvents.front());
+ cbEvents.pop();
+
+ {
+ Message::ReportType t;
+ t.setConfirmed(false);
+ t.setID("type2Id#Loc");
+ t.setFixed(true);
+ t.setServerRemote(false);
+ t.setServerProjectIndepended(true);
+ t.setGroupName("sGroup");
+ t.setName("type2Name");
+ t.setDelay(100);
+ t.setDuration(200);
+ sut.checkParseMessageData(sut.createMessage(t));
+ }
+ CHECK_MESSAGE(cbEvents.front() == "veto check false/false", cbEvents.front());
+ cbEvents.pop();
+ CHECK_MESSAGE(cbEvents.front() == "0: false type2Id#Loc type2Name sGroup", cbEvents.front());
+ cbEvents.pop();
+
+ {
+ Message::ReportType t;
+ t.setConfirmed(false);
+ t.setID("type1Id#Loc");
+ t.setFixed(true);
+ t.setServerRemote(false);
+ t.setServerProjectIndepended(true);
+ t.setGroupName("sGroup");
+ t.setName("type1Name");
+ t.setDelay(200);
+ t.setDuration(300);
+ sut.checkParseMessageData(sut.createMessage(t));
+ }
+ CHECK_MESSAGE(cbEvents.front() == "1: false type1Id#Loc type1Name sGroup", cbEvents.front());
+ cbEvents.pop();
+ CHECK(cbEvents.empty());
+}
diff --git a/components/spit/uTest/spitProcessor_complexTest.cpp b/components/spit/uTest/spitProcessor_complexTest.cpp
new file mode 100644
index 0000000..2b09b6a
--- /dev/null
+++ b/components/spit/uTest/spitProcessor_complexTest.cpp
@@ -0,0 +1,511 @@
+/**
+ * @file spitRepoTest.cpp
+ * @author Gustice
+ * @brief
+ */
+
+#include "doctest/doctest.h"
+#include
+#include
+#include
+
+#include "spit_processor.hpp"
+
+using namespace spit;
+using namespace std;
+static queue cbEvents;
+
+class ClientMockCmplx {
+ public:
+ void onServerEvent(SProcessor::ServerEvent event, const SadDetectedServer &detectedServer) {
+ }
+ void onConnectionStatus(string serverID, string serverComputerName, string serverName, int serverStepTime, SProcessor::Connection connectionStatus, SProcessor::Connection oldConnectionStatus) {
+ }
+ void onProjectUpdate(SProcessor::ProjUpdate state, string projectId) {
+ }
+ void onSpitType(SProcessor::ObjectEvent event, bool isRemote, const SType &sType) {
+ cbEvents.push(fmt::format("{}: {} {} {} {}", (int)event, isRemote, sType.getID(), sType.Name.get(), sType.GroupName.get()));
+ }
+ void onSpitObject(SProcessor::ObjectEvent event, bool isRemote, const SType &sType, const SObject &sObject) {
+ cbEvents.push(fmt::format("{}: {} {} {} {} {}", (int)event, isRemote, sType.getID(), sType.Name.get(), sObject.Name.get(), sObject.getID()));
+ }
+ void onPlay(string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) {
+ }
+ void onPlaySpitType(string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value) {
+ }
+ void onPlayRemoteObjectStatus(const SType &sType, const SObject &sObject, uint64_t p_FrameInsideObject, int value) {
+ }
+ bool onCheckSpitTypeVeto(bool knownType, bool createdByClient) {
+ cbEvents.push(fmt::format("veto check {}/{}", knownType, createdByClient));
+ return true;
+ }
+ bool onCheckSpitObjectVeto(bool knownType) {
+ return true;
+ }
+};
+
+class SpitClientCmplsFix {
+ protected:
+ ClientMockCmplx client;
+ SProcessor::Callbacks callbacks{
+ .onServerEvent = [&](SProcessor::ServerEvent event, const SadDetectedServer &detectedServer) { client.onServerEvent(event, detectedServer); },
+ .onConnectionStatus = [&](string serverID, string serverComputerName, string serverName, int serverStepTime, SProcessor::Connection connectionStatus, SProcessor::Connection oldConnectionStatus) { client.onConnectionStatus(serverID, serverComputerName, serverName, serverStepTime, connectionStatus, oldConnectionStatus); },
+ .onProjectUpdate = [&](SProcessor::ProjUpdate state, string projectId) { client.onProjectUpdate(state, projectId); },
+ .onSpitType = [&](SProcessor::ObjectEvent event, bool isRemote, const SType &t) { client.onSpitType(event, isRemote, t); },
+ .onSpitObject = [&](SProcessor::ObjectEvent event, bool isRemote, const SType &t, const SObject &o) { client.onSpitObject(event, isRemote, t, o); },
+ .onPlay = [&](string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) { client.onPlay(playerID, playerName, playerType, playerIsRunning, timeFrames); },
+ .onPlaySpitType = [&](string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value) { client.onPlaySpitType(playerID, spitTypeID, playerIsRunning, started, ended, value); },
+ .onPlayRemoteObjectStatus = [&](const SType &t, const SObject &o, uint64_t p_FrameInsideObject, int value) { client.onPlayRemoteObjectStatus(t, o, p_FrameInsideObject, value); },
+ .onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient) { return client.onCheckSpitTypeVeto(knownType, createdByClient); },
+ .onCheckSpitObjectVeto = [&](bool knownType) { return client.onCheckSpitObjectVeto(knownType); }};
+ SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks};
+};
+
+static void spoofMsgCounter(std::vector &msg, uint8_t cnt) {
+ msg.at(11) = cnt;
+}
+
+TEST_CASE_FIXTURE(SpitClientCmplsFix, "Spit types Raw") {
+ int cnt = 1;
+ {
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x41, 0x63, 0x00, 0x00, 0x00, // #spit#.....Ac...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x15, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ........00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x37, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000m70va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x00, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x6c, 0x00, // ....MainScene.l.
+ /*00a0*/ 0x00, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ement..........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x50, 0x6f, 0x73, // ...........InPos
+ /*00c0*/ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x63, 0x65, 0x6e, 0x65, // ition1Scene.cene
+ /*00d0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00e0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00f0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ...........
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000m70va8bom InPosition1Scene MainScene", cbEvents.front());
+ cbEvents.pop();
+ }
+ {
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x42, 0x63, 0x00, 0x00, 0x00, // #spit#.....Bc...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x15, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ........00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x68, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000mh0va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x00, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x6c, 0x00, // ....MainScene.l.
+ /*00a0*/ 0x00, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ement..........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x50, 0x6f, 0x73, // ...........InPos
+ /*00c0*/ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x63, 0x65, 0x6e, 0x65, // ition2Scene.cene
+ /*00d0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00e0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00f0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ...........
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000mh0va8bom InPosition2Scene MainScene", cbEvents.front());
+ cbEvents.pop();
+ }
+ {
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x43, 0x63, 0x00, 0x00, 0x00, // #spit#.....Cc...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x15, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ........00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x72, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000mr0va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x00, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x6c, 0x00, // ....MainScene.l.
+ /*00a0*/ 0x00, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ement..........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x50, 0x6f, 0x73, // ...........InPos
+ /*00c0*/ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x33, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x63, 0x65, 0x6e, 0x65, // ition3Scene.cene
+ /*00d0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00e0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00f0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ...........
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000mr0va8bom InPosition3Scene MainScene", cbEvents.front());
+ cbEvents.pop();
+ }
+ {
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x44, 0x63, 0x00, 0x00, 0x00, // #spit#.....Dc...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x15, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ........00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6e, 0x6b, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000nk0va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x00, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x6c, 0x00, // ....MainScene.l.
+ /*00a0*/ 0x00, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ement..........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x50, 0x6f, 0x73, // ...........InPos
+ /*00c0*/ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x34, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x63, 0x65, 0x6e, 0x65, // ition4Scene.cene
+ /*00d0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00e0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00f0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ...........
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000nk0va8bom InPosition4Scene MainScene", cbEvents.front());
+ cbEvents.pop();
+ }
+ {
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x45, 0x63, 0x00, 0x00, 0x00, // #spit#.....Ec...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x15, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ........00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6e, 0x75, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000nu0va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x00, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x6c, 0x00, // ....MainScene.l.
+ /*00a0*/ 0x00, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ement..........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x50, 0x6f, 0x73, // ...........InPos
+ /*00c0*/ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x35, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x63, 0x65, 0x6e, 0x65, // ition5Scene.cene
+ /*00d0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00e0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00f0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ...........
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000nu0va8bom InPosition5Scene MainScene", cbEvents.front());
+ cbEvents.pop();
+ }
+ {
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x63, 0x00, 0x00, 0x00, // #spit#.....Fc...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x15, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ........00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6f, 0x34, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000o40va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x00, 0x4d, 0x61, 0x69, 0x6e, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x6c, 0x00, // ....MainScene.l.
+ /*00a0*/ 0x00, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .ement..........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x50, 0x6f, 0x73, // ...........InPos
+ /*00c0*/ 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x36, 0x53, 0x63, 0x65, 0x6e, 0x65, 0x00, 0x63, 0x65, 0x6e, 0x65, // ition6Scene.cene
+ /*00d0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00e0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00f0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ...........
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000o40va8bom InPosition6Scene MainScene", cbEvents.front());
+ cbEvents.pop();
+ }
+ CHECK(cbEvents.empty());
+
+ { // In InPosition1Scene
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7b, 0x63, 0x00, 0x00, 0x00, // #spit#.....{c...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x1f, 0x53, 0x01, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ...S....00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x37, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000m70va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x70, 0x6c, 0x61, 0x79, 0x00, 0x2f, 0x20, 0x46, 0x61, 0x64, 0x65, 0x20, 0x4f, // ...play./ Fade O
+ /*00a0*/ 0x75, 0x74, 0x00, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ut.cy...........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00c0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00d0*/ 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, 0x65, 0x64, 0x79, 0x79, 0x74, // ...00000m8uedyyt
+ /*00e0*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // 0000000000000000
+ /*00f0*/ 0x6d, 0x37, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x69, 0x70, 0x00, // m70va8bom....ip.
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0110*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0120*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0130*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0xb9, 0x04, 0x00, // ................
+ /*0140*/ 0x00, 0x00, 0x00, 0x00, 0xed, 0x35, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .....5..........
+ /*0150*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, // ............@B..
+ /*0160*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0170*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0180*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0190*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01a0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ......
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000m70va8bom InPosition1Scene play 00000m8uedyyt0000000000000000m70va8bom", cbEvents.front());
+ cbEvents.pop();
+ }
+ { // In InPosition2Scene
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7d, 0x63, 0x00, 0x00, 0x00, // #spit#.....}c...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x1f, 0x53, 0x01, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ...S....00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x68, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000mh0va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x70, 0x6c, 0x61, 0x79, 0x00, 0x2f, 0x20, 0x46, 0x61, 0x64, 0x65, 0x20, 0x4f, // ...play./ Fade O
+ /*00a0*/ 0x75, 0x74, 0x00, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ut.cy...........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00c0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00d0*/ 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, 0x65, 0x64, 0x79, 0x79, 0x74, // ...00000m8uedyyt
+ /*00e0*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // 0000000000000000
+ /*00f0*/ 0x6d, 0x68, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x69, 0x70, 0x00, // mh0va8bom....ip.
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0110*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0120*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0130*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0xef, 0x06, 0x00, // ............r...
+ /*0140*/ 0x00, 0x00, 0x00, 0x00, 0x26, 0x2d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....&-..........
+ /*0150*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, // ............@B..
+ /*0160*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0170*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0180*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0190*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01a0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ......
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000mh0va8bom InPosition2Scene play 00000m8uedyyt0000000000000000mh0va8bom", cbEvents.front());
+ cbEvents.pop();
+ }
+ { // In InPosition3Scene
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x63, 0x00, 0x00, 0x00, // #spit#......c...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x1f, 0x53, 0x01, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ...S....00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x72, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000mr0va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x70, 0x6c, 0x61, 0x79, 0x00, 0x2f, 0x20, 0x46, 0x61, 0x64, 0x65, 0x20, 0x4f, // ...play./ Fade O
+ /*00a0*/ 0x75, 0x74, 0x00, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ut.cy...........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00c0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00d0*/ 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, 0x65, 0x64, 0x79, 0x79, 0x74, // ...00000m8uedyyt
+ /*00e0*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // 0000000000000000
+ /*00f0*/ 0x6d, 0x72, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x69, 0x70, 0x00, // mr0va8bom....ip.
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0110*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0120*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0130*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0xfc, 0x08, 0x00, // ................
+ /*0140*/ 0x00, 0x00, 0x00, 0x00, 0x52, 0x2e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....R...........
+ /*0150*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, // ............@B..
+ /*0160*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0170*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0180*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0190*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01a0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ......
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000mr0va8bom InPosition3Scene play 00000m8uedyyt0000000000000000mr0va8bom", cbEvents.front());
+ cbEvents.pop();
+ }
+ { // In InPosition4Scene
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x81, 0x63, 0x00, 0x00, 0x00, // #spit#......c...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x1f, 0x53, 0x01, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ...S....00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6e, 0x6b, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000nk0va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x70, 0x6c, 0x61, 0x79, 0x00, 0x2f, 0x20, 0x46, 0x61, 0x64, 0x65, 0x20, 0x4f, // ...play./ Fade O
+ /*00a0*/ 0x75, 0x74, 0x00, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ut.cy...........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00c0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00d0*/ 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, 0x65, 0x64, 0x79, 0x79, 0x74, // ...00000m8uedyyt
+ /*00e0*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // 0000000000000000
+ /*00f0*/ 0x6e, 0x6b, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x69, 0x70, 0x00, // nk0va8bom....ip.
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0110*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0120*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0130*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff, 0x0a, 0x00, // ................
+ /*0140*/ 0x00, 0x00, 0x00, 0x00, 0x36, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....63..........
+ /*0150*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, // ............@B..
+ /*0160*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0170*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0180*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0190*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01a0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ......
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000nk0va8bom InPosition4Scene play 00000m8uedyyt0000000000000000nk0va8bom", cbEvents.front());
+ cbEvents.pop();
+ }
+ { // In InPosition5Scene
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x83, 0x63, 0x00, 0x00, 0x00, // #spit#......c...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x1f, 0x53, 0x01, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ...S....00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6e, 0x75, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000nu0va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x70, 0x6c, 0x61, 0x79, 0x00, 0x2f, 0x20, 0x46, 0x61, 0x64, 0x65, 0x20, 0x4f, // ...play./ Fade O
+ /*00a0*/ 0x75, 0x74, 0x00, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ut.cy...........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00c0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00d0*/ 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, 0x65, 0x64, 0x79, 0x79, 0x74, // ...00000m8uedyyt
+ /*00e0*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // 0000000000000000
+ /*00f0*/ 0x6e, 0x75, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x69, 0x70, 0x00, // nu0va8bom....ip.
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0110*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0120*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0130*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x0d, 0x00, // ................
+ /*0140*/ 0x00, 0x00, 0x00, 0x00, 0x75, 0x29, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....u)..........
+ /*0150*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, // ............@B..
+ /*0160*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0170*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0180*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0190*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01a0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ......
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000nu0va8bom InPosition5Scene play 00000m8uedyyt0000000000000000nu0va8bom", cbEvents.front());
+ cbEvents.pop();
+ }
+ { // In InPosition6Scene
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x85, 0x63, 0x00, 0x00, 0x00, // #spit#......c...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x1f, 0x53, 0x01, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ...S....00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x6f, 0x34, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00000o40va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x70, 0x6c, 0x61, 0x79, 0x00, 0x2f, 0x20, 0x46, 0x61, 0x64, 0x65, 0x20, 0x4f, // ...play./ Fade O
+ /*00a0*/ 0x75, 0x74, 0x00, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ut.cy...........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00c0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00d0*/ 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, 0x65, 0x64, 0x79, 0x79, 0x74, // ...00000m8uedyyt
+ /*00e0*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // 0000000000000000
+ /*00f0*/ 0x6f, 0x34, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x69, 0x70, 0x00, // o40va8bom....ip.
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0110*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0120*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0130*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x05, 0x0f, 0x00, // ................
+ /*0140*/ 0x00, 0x00, 0x00, 0x00, 0x13, 0x36, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .....6..........
+ /*0150*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, // ............@B..
+ /*0160*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0170*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0180*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0190*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01a0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ......
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK_MESSAGE(cbEvents.front() == "0: true 00000m8uedyyt0000000000000000o40va8bom InPosition6Scene play 00000m8uedyyt0000000000000000o40va8bom", cbEvents.front());
+ cbEvents.pop();
+ }
+ { // unknown
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x87, 0x63, 0x00, 0x00, 0x00, // #spit#......c...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x1f, 0x53, 0x01, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ...S....00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x31, 0x61, 0x75, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00001au0va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x70, 0x6c, 0x61, 0x79, 0x00, 0x2f, 0x20, 0x46, 0x61, 0x64, 0x65, 0x20, 0x4f, // ...play./ Fade O
+ /*00a0*/ 0x75, 0x74, 0x00, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ut.cy...........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00c0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00d0*/ 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, 0x65, 0x64, 0x79, 0x79, 0x74, // ...00000m8uedyyt
+ /*00e0*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, // 0000000000000001
+ /*00f0*/ 0x61, 0x75, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x69, 0x70, 0x00, // au0va8bom....ip.
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0110*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0120*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0130*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x06, 0x11, 0x00, // ............2...
+ /*0140*/ 0x00, 0x00, 0x00, 0x00, 0x33, 0x53, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....3S..........
+ /*0150*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, // ............@B..
+ /*0160*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0170*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0180*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0190*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01a0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ......
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK(cbEvents.empty());
+ }
+ { // unknown
+ std::vector msg = {
+ /*0000*/ 0x23, 0x73, 0x70, 0x69, 0x74, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x89, 0x63, 0x00, 0x00, 0x00, // #spit#......c...
+ /*0010*/ 0x34, 0x30, 0x35, 0x63, 0x37, 0x31, 0x30, 0x30, 0x2d, 0x36, 0x34, 0x65, 0x38, 0x2d, 0x34, 0x33, // 405c7100-64e8-43
+ /*0020*/ 0x35, 0x64, 0x2d, 0x38, 0x61, 0x37, 0x62, 0x2d, 0x30, 0x30, 0x63, 0x35, 0x36, 0x32, 0x39, 0x66, // 5d-8a7b-00c5629f
+ /*0030*/ 0x39, 0x63, 0x63, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x30, 0x38, 0x36, 0x36, 0x63, 0x39, // 9ccf.....70866c9
+ /*0040*/ 0x62, 0x2d, 0x61, 0x66, 0x31, 0x63, 0x2d, 0x34, 0x37, 0x36, 0x35, 0x2d, 0x61, 0x31, 0x37, 0x65, // b-af1c-4765-a17e
+ /*0050*/ 0x2d, 0x38, 0x62, 0x34, 0x35, 0x63, 0x39, 0x33, 0x66, 0x33, 0x61, 0x63, 0x61, 0x00, 0x00, 0x00, // -8b45c93f3aca...
+ /*0060*/ 0x00, 0x00, 0x1f, 0x53, 0x01, 0x00, 0x00, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, // ...S....00000m8u
+ /*0070*/ 0x65, 0x64, 0x79, 0x79, 0x74, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, // edyyt00000000000
+ /*0080*/ 0x30, 0x30, 0x30, 0x30, 0x31, 0x66, 0x6a, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, // 00001fj0va8bom..
+ /*0090*/ 0x00, 0x01, 0x01, 0x70, 0x6c, 0x61, 0x79, 0x00, 0x2f, 0x20, 0x46, 0x61, 0x64, 0x65, 0x20, 0x4f, // ...play./ Fade O
+ /*00a0*/ 0x75, 0x74, 0x00, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ut.cy...........
+ /*00b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00c0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*00d0*/ 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6d, 0x38, 0x75, 0x65, 0x64, 0x79, 0x79, 0x74, // ...00000m8uedyyt
+ /*00e0*/ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, // 0000000000000001
+ /*00f0*/ 0x66, 0x6a, 0x30, 0x76, 0x61, 0x38, 0x62, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x69, 0x70, 0x00, // fj0va8bom....ip.
+ /*0100*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0110*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0120*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0130*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x3a, 0x14, 0x00, // .............:..
+ /*0140*/ 0x00, 0x00, 0x00, 0x00, 0xb4, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0150*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x42, 0x0f, 0x00, // ............@B..
+ /*0160*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0170*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0180*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*0190*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01a0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+ /*01b0*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ......
+ };
+ spoofMsgCounter(msg, cnt++);
+ sut.checkParseMessageData(std::vector(msg.begin(), msg.end()));
+ CHECK(cbEvents.empty());
+ }
+}
+
+
+
diff --git a/esp_idf_project_configuration.json b/esp_idf_project_configuration.json
index 774fcde..dd82b06 100644
--- a/esp_idf_project_configuration.json
+++ b/esp_idf_project_configuration.json
@@ -28,7 +28,9 @@
"compileArgs": [],
"ninjaArgs": [],
"buildDirectoryPath": "build_uTest",
- "sdkconfigDefaults": [],
+ "sdkconfigDefaults": [
+ "test/unitOnTarget/sdkconfig.defaults"
+ ],
"sdkconfigFilePath": ""
},
"env": {
diff --git a/main/watchMain.cpp b/main/watchMain.cpp
index b16a0cc..faf2be1 100644
--- a/main/watchMain.cpp
+++ b/main/watchMain.cpp
@@ -833,8 +833,8 @@ void SpitClientApp() {
ProvidedObj.push_back(LocalSpitObj{.iD = provided.startShuffle, .groupName = provided.group, .name = provided.startShuffle});
ExpectedObjects[expected.changingPos] = "";
for (size_t i = 0; i < 6; i++) {
- ProvidedObj.push_back(LocalSpitObj{.iD = provided.moveToX[i], .groupName = provided.group, .name = provided.moveToX[i]});
ProvidedSpitActions[provided.moveToX[i]] = MoveCommand{.type = MoveType::StepTo, .pos = (uint8_t)(i + 1)};
+ ProvidedObj.push_back(LocalSpitObj{.iD = provided.moveToX[i], .groupName = provided.group, .name = provided.moveToX[i]});
ExpectedObjects[expected.inPosX[i]] = "";
}
@@ -855,7 +855,7 @@ void SpitClientApp() {
});
for (auto &obj : ProvidedObj) {
- SType *ptrSPITType1Fix = spitClient.createSPITTypeFixed(obj.iD, obj.groupName, obj.name, 0, 0);
+ SType *ptrSPITType1Fix = spitClient.createTypeFixed(obj.iD, obj.groupName, obj.name, 0, 0);
spitClient.setActionSPITType(ptrSPITType1Fix->getID(), true); // should be executed whenever a SPITObject with this SPITType is played
}
spitClient.clientProjectLoaded();
@@ -924,7 +924,7 @@ void app_main(void) {
static fos::TaskT telnetSocket(telnetSocketTask, ipVersion, "tcpServer", 4096);
static fos::TaskT dmxNode(dmxSocketTask, ipVersion, "dmxNode", 4096);
// static fos::Task spit(SpitClientApp, "SpitClient");
- // static fos::Task mqtt(MqttThread, "MqttEndpoint");
+ static fos::Task mqtt(MqttThread, "MqttEndpoint");
// static Task otaUpdate(SystemFunctions::OtaTaskEntry, "otaTask", 8192);
auto &store = NvsApi::getInstance();
diff --git a/sdkconfig b/sdkconfig
index 55a84cc..1089526 100644
--- a/sdkconfig
+++ b/sdkconfig
@@ -579,6 +579,15 @@ CONFIG_PARTITION_TABLE_OFFSET=0x8000
CONFIG_PARTITION_TABLE_MD5=y
# end of Partition Table
+#
+# Example Configuration
+#
+CONFIG_DEVICE_WIFI_SSID="eth2ap"
+CONFIG_DEVICE_WIFI_PASSWORD="12345678"
+CONFIG_DEVICE_WIFI_CHANNEL=1
+CONFIG_DEVICE_MAX_STA_CONN=4
+# end of Example Configuration
+
#
# Example Ethernet Configuration
#
@@ -2136,6 +2145,17 @@ CONFIG_LITTLEFS_MALLOC_STRATEGY_DEFAULT=y
# CONFIG_LITTLEFS_MALLOC_STRATEGY_INTERNAL is not set
CONFIG_LITTLEFS_ASSERTS=y
# end of LittleFS
+
+#
+# Telnet Server
+#
+CONFIG_TELNET_SERVER_DEFAULT_PORT=23
+CONFIG_TELNET_SERVER_MAX_CONNECTIONS=5
+CONFIG_TELNET_SERVER_STACK_SIZE=4096
+CONFIG_TELNET_SERVER_TASK_PRIORITY=24
+CONFIG_TELNET_SERVER_TASK_CORE=0
+CONFIG_TELNET_SERVER_REDIRECT_LOGS=0
+# end of Telnet Server
# end of Component config
# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set
diff --git a/test/unitOnTarget/CMakeLists.txt b/test/unitOnTarget/CMakeLists.txt
index bc2ba0c..cf204be 100644
--- a/test/unitOnTarget/CMakeLists.txt
+++ b/test/unitOnTarget/CMakeLists.txt
@@ -14,7 +14,7 @@ set(EXTRA_COMPONENT_DIRS
# - when invoking CMake directly: cmake -D TEST_COMPONENTS="xxxxx" ..
# - when using idf.py: idf.py -T xxxxx build
#
-set(TEST_COMPONENTS "testable freeRtosApi hwHal" CACHE STRING "List of components to test")
+set(TEST_COMPONENTS "testable freeRtosApi hwHal spit" CACHE STRING "List of components to test" FORCE)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(unit_test)
diff --git a/test/unitOnTarget/main/unitTest.cpp b/test/unitOnTarget/main/unitTest.cpp
index 5fe007b..90aea1d 100644
--- a/test/unitOnTarget/main/unitTest.cpp
+++ b/test/unitOnTarget/main/unitTest.cpp
@@ -9,6 +9,8 @@
#include "unity.h"
#include
#include
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
extern "C" { // This switch allows the ROS C-implementation to find this main
void app_main(void);
@@ -33,5 +35,9 @@ void app_main(void) {
printf("# - run tagged with [tag], \n");
printf("# - run all other than ![tag])\n");
printf("# Exit with 'Ctrl-]'\n");
- unity_run_menu();
+ // unity_run_menu(); // Watchdog needs to
+
+ while (true) {
+ vTaskDelay(10);
+ }
}