diff --git a/components/spit/include/SAD_ClientInterface.h b/components/spit/include/I_SAD_Client.hpp similarity index 70% rename from components/spit/include/SAD_ClientInterface.h rename to components/spit/include/I_SAD_Client.hpp index a48040b..a1b2561 100644 --- a/components/spit/include/SAD_ClientInterface.h +++ b/components/spit/include/I_SAD_Client.hpp @@ -1,23 +1,9 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * File: SAD_ClientInterface.h - * Author: Hagi - * - * Created on 16. April 2019, 13:08 - */ - -#ifndef SAD_CLIENTINTERFACE_H -#define SAD_CLIENTINTERFACE_H +#pragma once #include using namespace std; -class SAD_ClientInterface { +class I_SAD_Client { public: /** * If a new server was found by the ServerAutoDetect mechanism, this function is called.
@@ -32,11 +18,9 @@ public: * @param p_IP the selected ip address of the SPIT server * @param p_Port the port of the SPIT server * @param p_Addition sometimes server may have additional informations - * @param p_isLoopback the server ip is a loopback address * @param p_IsIP4 the server ip is a ip4 address - * @param p_IsIP6 the server ip is a ip6 address */ - virtual void eventServerDetected(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_CLientIP, bool p_isLoopback, bool p_IsIP4, bool p_IsIP6) = 0; + virtual void eventServerDetected(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_CLientIP, bool p_IsIP4) = 0; /** * 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.
@@ -46,12 +30,7 @@ public: * @param p_IP the selected ip address of the SPIT server * @param p_Port the port of the SPIT server * @param p_Addition sometimes server may have additional informations - * @param p_isLoopback the server ip is a loopback address * @param p_IsIP4 the server ip is a ip4 address - * @param p_IsIP6 the server ip is a ip6 address */ - virtual void eventServerLost(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_CLientIP, bool p_isLoopback, bool p_IsIP4, bool p_IsIP6) = 0; + virtual void eventServerLost(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_CLientIP, bool p_IsIP4) = 0; }; - -#endif /* SAD_CLIENTINTERFACE_H */ - diff --git a/components/spit/include/MyApp.h b/components/spit/include/MyApp.h index 8c279f4..5b0bc6d 100644 --- a/components/spit/include/MyApp.h +++ b/components/spit/include/MyApp.h @@ -4,7 +4,7 @@ * and open the template in the editor. */ -/* +/* * File: MySPITApp.h * Author: Hagi * @@ -15,105 +15,73 @@ #define MYSPITAPP_H #include "SPIT_Client.h" -#include #include +#include +#include "SPITType.h" +#include "SPITObject.h" +#include "SPITPlayer.h" +#include "SAD_DetectedServer.hpp" using namespace std; -class MyApp : SPIT_ClientInterface { -public: - MyApp(); - virtual ~MyApp(); - - //Client's infos is set by the client - static string s_ClientName; - void loadClientProject(); - -private: - SPIT_Client* m_SPIT_Client; //pointer to an instance of the SPIT_Client, which do the main work for you - - //MySPITApp client project infos they are transferred after the server send his project infos, see eventProjectReport - string m_ClientProjectID; //can be an id or simple the project's name - string m_ClientProjectName; //the name of the client's (this) project - - //Server's info filled by eventConnectionStatus when SPIT_Client::CONNECTION_OK - string m_ServerID; - string m_ServerName; - string m_ServerComputerName; - int m_ServerStepTime; - - //Server's project infos filled by eventProjectReport - string m_ServerProjectID; - string m_ServerProjectName; - int m_ServerFramesPerSecond; //set when the server reports his project, see eventProjectReport - //liveSHOWsoftware will use 44100 frames per second as time resolution - //All times are given in frames, +class MyApp { + public: + MyApp(); + // Client's infos is set by the client + static string s_ClientName; + static string s_ProjectName; + void init(); - //Reconnect to the server when connection is lost see eventConnectionStatus and eventServerDetected - bool m_FlagReconnect; //true = on eventServerDetected connect to the server identified by m_ServerID - - - + private: + SPIT_Client _SpitClient; // pointer to an instance of the SPIT_Client, which do the main work for you -public: - //---------- SPIT_ClientInterface ------------- - string getClientProjectID(); //should return the client's project id, maybe the same as project name - string getClientProjectName(); + // Server's project infos filled by eventProjectReport + static string m_ServerProjectID; + static string m_ServerProjectName; + static int m_ServerFramesPerSecond; // set when the server reports his project, see eventProjectReport + // liveSHOWsoftware will use 44100 frames per second as time resolution + // All times are given in frames, - //----- ServerAutoDetection ----- - void startServerAutoDetect(); //starts the autodetection of SPITServers in the local network area (see eventServerDetected) - void stopServerAutoDetect(); //stopps the autodetection - void eventServerDetected(const SAD_DetectedServer& p_DetectedServer); //a SPITServer is detected - void eventServerLost(const SAD_DetectedServer& p_DetectedServer); //a prior detected SPITServer is lost - - //----- Connection ----- - void eventConnectionStatus(string p_ServerID, string p_ServerComputerName, string p_ServerName, int p_ServerStepTime, int p_ConnectionStatus, int p_OldConnectionStatus); - - //----- Project ----- - void eventProjectReport(string p_ProjectID, string p_ProjectName, int p_FramesPerSeoond); - void eventProjectClosed(string p_ProjectID); - - void eventStartProjectTransfer(); - void eventEndProjectTransfer(); - - - //----- SPITType ----- + public: + //----- ServerAutoDetection ----- + static void onServerDetected(const SAD_DetectedServer &p_DetectedServer); // a SPITServer is detected + static void onServerLost(const SAD_DetectedServer &p_DetectedServer); // a prior detected SPITServer is lost + + //----- Connection ----- + void eventConnectionStatus(string p_ServerID, string p_ServerComputerName, string p_ServerName, int p_ServerStepTime, int p_ConnectionStatus, int p_OldConnectionStatus); - void eventSPITType(bool p_New, const SPITType& p_SPITType); - void eventSPITTypeRemote(bool p_New, const SPITType& p_SPITType); - void eventSPITTypeRemoved(const SPITType& p_SPITType); - void eventSPITTypeRemoteRemoved(const SPITType& p_SPITType); + //----- Project ----- + static void onStartProjectTransfer(); + static void onEndProjectTransfer(); + static void onProjectReport(string p_ProjectID, string p_ProjectName, int p_FramesPerSeoond); + static void onProjectClosed(string p_ProjectID); - //----- SPITObject ----- - void eventSPITObject(bool p_New, const SPITType& p_SPITType, const SPITObject& p_SPITObject); - void eventSPITObjectRemote(bool p_New, const SPITType& p_SPITType, const SPITObject& p_SPITObject); - void eventSPITObjectRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject); - void eventSPITObjectRemoteRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject); + //----- SPITType ----- + static void onSpitType(bool p_New, const SPITType &p_SPITType); + static void onSpitTypeRemote(bool p_New, const SPITType &p_SPITType); + static void onSpitTypeRemoved(const SPITType &p_SPITType); + static void onSpitTypeRemoteRemoved(const SPITType &p_SPITType); - //----- Play SPITObjects ----- - void eventPlay(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_PlayerIsRunning, long long p_TimeFrames); - void eventPlayObject(string p_PlayerID, bool p_Started, bool p_Stopped, const SPITType& p_SPITType, const SPITObject& p_SPITObject, const SPITPlayer::PlayObject& p_PlayObject); + //----- SPITObject ----- + static void onSpitObject(bool p_New, const SPITType &p_SPITType, const SPITObject &p_SPITObject); + static void onSpitObjectRemote(bool p_New, const SPITType &p_SPITType, const SPITObject &p_SPITObject); + static void onSpitObjectRemoved(const SPITType &p_SPITType, const SPITObject &p_SPITObject); + static void onSpitObjectRemoteRemoved(const SPITType &p_SPITType, const SPITObject &p_SPITObject); - - //----- Server changes status of one of his REMOTE SPITObjects ----- - //REMOTE only Server->Client RemoteObject's play status - void eventPlayRemoteObjectStatus(const SPITType& p_SPITType, const SPITObject& p_SPITObject, long long p_FrameInsideObject, int p_Value); + //----- Play SPITObjects ----- + static void onPlay(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_PlayerIsRunning, long long p_TimeFrames); + static void onPlayObject(string p_PlayerID, bool p_Started, bool p_Stopped, const SPITType &p_SPITType, const SPITObject &p_SPITObject, const SPITPlayer::PlayObject &p_PlayObject); - void sendRemoteObject(string p_SPITObjectID, int p_Valueppm = 0, char p_ValueFlag = 0x00); - //----- - void testLiveShowRemote(); - - //------ User's options normally should not be used, the server is master of things ------ -public: - //----- SPITType ----- - int removeSPITType(string p_SPITTypeID); - int changeSPITType(SPITType* p_SPITType); - - //----- SPITObject ----- - int removeSPITObject(string p_SPITObjectID); - int changeSPITObject(SPITObject* p_SPITObject); - + //----- Server changes status of one of his REMOTE SPITObjects ----- + // REMOTE only Server->Client RemoteObject's play status + static void onPlayRemoteObjectStatus(const SPITType &p_SPITType, const SPITObject &p_SPITObject, long long p_FrameInsideObject, int p_Value); + + void sendRemoteObject(string p_SPITObjectID, int p_Valueppm = 0, char p_ValueFlag = 0x00); + //----- + void testLiveShowRemote(); + + //------ User's options normally should not be used, the server is master of things ------ + public: }; #endif /* MYSPITAPP_H */ - diff --git a/components/spit/include/SAD_Client.h b/components/spit/include/SAD_Client.h deleted file mode 100644 index 440d2e7..0000000 --- a/components/spit/include/SAD_Client.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * File: ServerAutoDetetc_Client.h - * Author: Hagi - * - * Created on 16. April 2019, 08:57 - */ -#ifndef SERVERAUTODETETC_CLIENT_H -#define SERVERAUTODETETC_CLIENT_H -#include "_SPITMACROS.h" -#include "SPIT_Handler.h" -#include "SPITSocket.h" -#include "SAD_DetectedServer.h" -#include -#include -#include "Mutex.hpp" -#include "Semaphore.hpp" -#include "Task.hpp" - - -static const string SERVERAUTODETECT_PRECODE = "#SAD#"; -static const string SERVERAUTODETECT_SEPERATOR = "#,#"; -static const string SERVERAUTODETECT_TASKID = "#spit#"; -static const string SERVERAUTODETECT_PORT = "15110"; - -class SAD_Client { - -//----- SAD Client Interface ------ -private: - static SAD_ClientInterface* s_SADClientInterface; - -//----- SAD_Client ----- -public: -private: - static fos::Mutex s_MutexSAD; - static fos::Semaphore s_ConditionStopSAD; - static bool s_StopSAD; - static fos::Task* s_ThreadSend; - static fos::Task* s_ThreadReceiveIP4; - - static fos::Mutex s_MutexSocket; - static SPITSocket* s_SPITSocket; - - static void cycleStart(); - static void cycleEnd(); - static void sendAutoDetectServer(); - static void receiveAutoDetectServer_IP4(); - -public: - static void startAutoDetectServer(SAD_ClientInterface* p_SADClientInterface, SPITSocket* p_SPITSocket); - static void stopAutoDetectServer(SAD_ClientInterface* p_SADClientInterface); -}; - -#endif /* SERVERAUTODETETC_CLIENT_H */ - diff --git a/components/spit/include/SAD_DetectedServer.h b/components/spit/include/SAD_DetectedServer.hpp similarity index 51% rename from components/spit/include/SAD_DetectedServer.h rename to components/spit/include/SAD_DetectedServer.hpp index 5cf3705..84dfe26 100644 --- a/components/spit/include/SAD_DetectedServer.h +++ b/components/spit/include/SAD_DetectedServer.hpp @@ -1,32 +1,14 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ +#pragma once -/* - * This class describes a detected SPITServer, found by SAD_Client.
- * File: SAD_DetectedServer.h - * Author: Hagi - * - * Created on 4. Mai 2019, 13:51 - */ - -#ifndef SAD_DETECTEDSERVER_H -#define SAD_DETECTEDSERVER_H - -#include "SAD_ClientInterface.h" +#include "I_SAD_Client.hpp" #include -#include "Mutex.hpp" #include #include using namespace std; - - class SAD_DetectedServer { - + public: SAD_DetectedServer(); SAD_DetectedServer(const SAD_DetectedServer& orig) { @@ -34,9 +16,7 @@ public: m_Name = orig.getName(); m_ComputerName = orig.getComputerName(); m_IP = orig.getIP(); - m_IPIsLoopback = orig.getIpIsLoopback(); m_IPIsIP4 = orig.getIpIsIP4(); - m_IPIsIP6 = orig.getIpIsIP6(); m_ClientIP = orig.getClientIP(); m_Port = orig.getPort(); m_Additions = orig.getAdditions(); @@ -48,9 +28,7 @@ public: string m_Name; string m_ComputerName; string m_IP; - bool m_IPIsLoopback; bool m_IPIsIP4; - bool m_IPIsIP6; string m_ClientIP; string m_Port; string m_Additions; @@ -59,123 +37,40 @@ public: bool m_FoundAgain; public: - /** - * - * @return ID of the SPITServer - */ - string getID() const { - return m_ID; - } - /** - * - * @return name of the SPITServer - */ - string getName() const { - return m_Name; - } - /** - * - * @return name of the computer where the SPITServer runs - */ - string getComputerName() const { - return m_ComputerName; - } - /** - * @return IP address at which the server can be reached - */ - string getIP() const { - return m_IP; - } - /** - * @return true = the SPITServer's IP address is a loopback address - */ - bool getIpIsLoopback() const { - return m_IPIsLoopback; - } - /** - * @return true = the SPITServer's IP address is an IP4 address - */ - bool getIpIsIP4() const { - return m_IPIsIP4; - } - /** - * @return true = the SPITServer's IP address is an IP6 address - */ - bool getIpIsIP6() const { - return m_IPIsIP6; - } - /** - * @return port of the SPITServer - */ - string getPort() const { - return m_Port; - } - /** - * - * @return The IP address of the client under which this client reached the server. - */ - string getClientIP() const { - return m_ClientIP; - } - /** - * Sometimes the SPITServer has additional informations - * @return - */ - string getAdditions() const { - return m_Additions; - } + string getID() const { return m_ID; } + string getName() const { return m_Name; } + string getComputerName() const { return m_ComputerName; } + string getIP() const { return m_IP; } + bool getIpIsIP4() const { return m_IPIsIP4; } + string getPort() const { return m_Port; } + string getClientIP() const { return m_ClientIP; } + string getAdditions() const { return m_Additions; } private: - void setID(string p_ID); - void setName(string p_Name); - void setComputerName(string p_ComputerName); - void setIP(string p_IP); - void setClientIP(string p_IP); - void setPort(string p_Port); - void setAdditions(string p_Additions); - - void setIPIsLoopback(bool p_IsLoopback) { - m_IPIsLoopback = p_IsLoopback; - } - void setIPIsIP4(bool p_IsIP4) { - m_IPIsIP4 = p_IsIP4; - } - void setIPIsIP6(bool p_IsIP6) { - m_IPIsIP6 = p_IsIP6; - } - - bool getNew() const { - return m_New; - } - bool getChanged() const { - return m_Changed; - } - bool getFoundAgain() const { - return m_FoundAgain; - } - - void setChanged() { - m_Changed = true; - } - void setNew(bool p_New) { - m_New = p_New; - } - void setFoundAgain() { - m_FoundAgain = true; - } + void setID(string p_ID) { m_ID = p_ID; } + void setName(string p_Name) { m_Name = p_Name; } + void setComputerName(string p_ComputerName) { m_ComputerName = p_ComputerName; } + void setIP(string p_IP) { m_IP = p_IP; } + void setClientIP(string p_IP) { m_ClientIP = p_IP; } + void setPort(string p_Port) { m_Port = p_Port; } + void setAdditions(string p_Additions) { m_Additions = p_Additions;} + + void setIPIsIP4(bool p_IsIP4) { m_IPIsIP4 = p_IsIP4; } + bool getNew() const { return m_New; } + bool getChanged() const { return m_Changed; } + bool getFoundAgain() const { return m_FoundAgain; } + void setChanged() { m_Changed = true; } + void setNew(bool p_New) { m_New = p_New; } + void setFoundAgain() { m_FoundAgain = true; } + //SAD_Client m_ThreadSend will send to Multicast addresses void startCycleSAD() { - m_IPIsLoopback = false; m_IPIsIP4 = false; - m_IPIsIP6 = false; m_Changed = false; m_FoundAgain = false; } //SAD_Client m_Thread_Send has paused in the meantime m_ThreadReceive may received messages from servers - void endCycleSAD() { - - } + void endCycleSAD() { } private: - static fos::Mutex s_MutexDetectedServer; static unordered_map s_DetectedServers; public: static const int PARAMINDEX_PRECODE = 0; @@ -211,7 +106,7 @@ public: * Used by SAD_Client internally -don't use this manually * @param p_SADClientInterface */ - static void cycleEnd(SAD_ClientInterface* p_SADClientInterface); + static void cycleEnd(I_SAD_Client& p_SADClientInterface); /** * Returns a reference of the DetectedServer with the id p_ServerID.
@@ -222,7 +117,6 @@ public: static const SAD_DetectedServer& getRefDetectedServer(string p_ServerID) { SAD_DetectedServer* ptrDetectedServer = NULL; { - fos::MutexGuard o_Lock(s_MutexDetectedServer); auto i = s_DetectedServers.find(p_ServerID); if (i != s_DetectedServers.end()) { ptrDetectedServer = i->second; @@ -237,6 +131,3 @@ public: }; - -#endif /* SAD_DETECTEDSERVER_H */ - diff --git a/components/spit/include/SPITObject.h b/components/spit/include/SPITObject.h index 51414e5..0d8b667 100644 --- a/components/spit/include/SPITObject.h +++ b/components/spit/include/SPITObject.h @@ -18,7 +18,6 @@ #include "SPITType.h" #include #include -#include "Mutex.hpp" using namespace std; @@ -27,13 +26,9 @@ class SPITObjectListener; class SPITObject { private: - static fos::Mutex s_MutexSPITObject; static unordered_map s_SPITObjects; static unordered_map s_SPITObjectsRemote; public: - static fos::Mutex* getMutex() { - return &s_MutexSPITObject; - } static SPITObject* getSPITObject(string p_ID); static const SPITObject& getSPITObjectRef(string p_ID); static bool addSPITObject(SPITObject* p_ptrSpitObject); diff --git a/components/spit/include/SPITPlayer.h b/components/spit/include/SPITPlayer.h index d15f870..62bdfd4 100644 --- a/components/spit/include/SPITPlayer.h +++ b/components/spit/include/SPITPlayer.h @@ -119,10 +119,6 @@ public: //----- SPITPlayer ------ public: - static fos::Mutex s_Mutex; - static fos::Mutex* getMutex() { - return &s_Mutex; - } //list the SPITPlayers static unordered_map s_SPITPlayers; //all actual played objects static SPITPlayer* getSPITPlayer(string p_PlayerID); //if a player does not exist creates a new one diff --git a/components/spit/include/SPITSocket.h b/components/spit/include/SPITSocket.h index a9cc8b7..8617371 100644 --- a/components/spit/include/SPITSocket.h +++ b/components/spit/include/SPITSocket.h @@ -5,7 +5,7 @@ */ /* - * SPITSocket is the base class for WindowsSocket, UnixSocket,..
+ * SPITSocket is the base class for WindowsSocket, UnixSocket,. * Used by SPIT_Client and SAD_Client. * File: SPITSocket.h * Author: Hagi @@ -15,66 +15,92 @@ #ifndef SPITSOCKET_H #define SPITSOCKET_H -#include "_SPITMACROS.h" -#include "Mutex.hpp" -#include + #include +#include "esp_netif.h" +#include +#include +#include +#include +#include +#include +#include +#include "Task.hpp" +#include "esp_log.h" using namespace std; +/** Returns an guid */ +string createGUID(); +/** Returns the name of the client's host computer*/ +string getClientHostName(); + class SPITSocket{ public: - static int FAMILY_IP4; - static int FAMILY_IP6; - - //-------- nested classes -------------- - -public: + static const int FAMILY_IP4 = AF_INET; + /** - * IPAddress class is used to fetch all available IP addresses of the computer.
- * This is for internal usage.
+ * IPAddress class is used to fetch all available IP addresses of the computer + * This is for internal usage */ - class IPAddress { + struct IPAddress { public: - IPAddress(); - ~IPAddress(); - private: - string m_IPAddress; - string m_SubnetMask; - bool m_Found; - public: - const string& getIPAddress() { - return m_IPAddress; + IPAddress(const string& p_IPAddress, const string& p_SubnetMask) + : m_IPAddress(p_IPAddress), m_SubnetMask(p_SubnetMask) { } + const string m_IPAddress; + const string m_SubnetMask; + + /** + * Calculates the broadcast address from a ip4 address + * @param p_IPAddress the ip4 address + * @return returns the broadcast address + */ + string getBroadcastIP4() const { + struct in_addr broadcast; + unsigned long ulIPAddress; + unsigned long ulSubnetMask; + + ulIPAddress = inet_addr(m_IPAddress.data()); + ulSubnetMask = inet_addr(m_SubnetMask.data()); + broadcast.s_addr = ulIPAddress | ~ulSubnetMask; + + return inet_ntoa(broadcast); } - const string& getSubnetMask() { - return m_SubnetMask; - } - bool getFound() { - return m_Found; - } - - void setIPAddress(const string& p_IPAddress); - void setSubnetMask(const string& p_SubnetMask); - void setFound(bool p_Found); }; - + const IPAddress mOwnIp; + static IPAddress getAdaptersInfo(); + bool createSocket_UDP(); + static const int INVALID_SOCKET = -1; + private: - static fos::Mutex s_MutexIPAddresses; + int m_UDPSocketIP4; + public: - static unordered_map s_IPAddresses; - static void addIPAddress(string p_IPAddress, string p_SubnetMask); - static void removeIPAddress(string p_IPAddress); - static int getIPAddressCount(); - static IPAddress* getIPAddress(int p_Index); - static void clearIPAddresses(); - static void resetFoundIPAddresses(); - static void removeNotFoundIPAddresses(); - - //-------- class -------------- - - SPITSocket(); - virtual ~SPITSocket(); + SPITSocket(IPAddress ip) : mOwnIp(ip) { + m_UDPSocketIP4 = INVALID_SOCKET; + + m_ServerIP = ""; + m_ServerPort = ""; + m_ClientIP = ""; + m_ClientPort = ""; + m_BoundClientPort = ""; + m_BoundClientFamily = 0; + m_IsBound = false; + createSocket_UDP(); + + } + virtual ~SPITSocket() { + ESP_LOGD("UDP", "Shutting down ..."); + + if (m_UDPSocketIP4 != INVALID_SOCKET) { + shutdown(m_UDPSocketIP4, 2); + close(m_UDPSocketIP4); + m_UDPSocketIP4 = INVALID_SOCKET; + } + fos::Task::delayMs(100); + m_IsBound = false; + } private: string m_ServerIP; string m_ServerPort; @@ -83,7 +109,7 @@ private: string m_BoundClientPort; //port set after bind int m_BoundClientFamily; bool m_IsBound; - fos::Mutex m_MutexSocket; + public: /** * Sets the ip address and port for server and client. @@ -92,79 +118,49 @@ public: * @param p_ClientIP * @param p_ClientPort */ - void setConnectionParams(string p_ServerIP, string p_ServerPort, string p_ClientIP, string p_ClientPort); + void setConnectionParams(string p_ServerIP, string p_ServerPort, string p_ClientIP, string p_ClientPort) { + m_ServerIP = p_ServerIP; + m_ServerPort = p_ServerPort; + m_ClientIP = p_ClientIP; + m_ClientPort = p_ClientPort; + } /** - * Send a message to the server as set by setConnectionParams.
+ * Send a message to the server as set by setConnectionParams * @param p_MessageBytes byte buffer containing the message * @param p_MessageLength length of the messaeg * @return */ - int sendMessage(const char* p_MessageBytes, int p_MessageLength); - /** - * Call this for receiving a message.
- * This will block until a message is received or the underlying socket is closed.
- * @param p_InetFamily either AF_INET or AF_INET6
- * The SPITSocket creates two udp sockets, one for IP4 and one for IP6.
- * This parameter decides from which socket should a message recieved.
- * @param p_Buffer the buffer containing the received message later. - * @param p_BufferLength the size of the buffer - * @param p_ServerIP a pointer to a string, when a messages is received the string will contain the ip address of the sender/server.
- * if p_ServerIP is NULL - no detection of the server will be done. - * @return - */ - virtual int receiveMessage(int p_InetFamily, char* p_Buffer, int p_BufferLength, string* p_ServerIP) = 0; - - - /** - * Returns the broadcast address of an ip4 address.
- * @param p_IPAdress - * @return - */ - virtual string getBroadcastIP4(IPAddress* p_IPAdress) = 0; - /** - * Set whether the sockat are brodcast sockets or not - * @param p_Broadcast true = the sockets are broadcast sockets - * @return 0 = ok, -1 = error - */ - virtual int setBroadcast(bool p_Broadcast) = 0; - /** - * Bind the client's udp socket to an ip address and port.
- * @param p_ClientIP the ip address either IP4 or IP6 - * @param p_ClientPort the client port number.
- * "0" = bind to any free port.
- * @return - */ - virtual int bindSocket(string p_ClientIP, string p_ClientPort) = 0; - /** - * Internal usage - don't use this manually.
- * Use sendMessage instead.
- * @param p_InetFamily - * @param p_ServerIP - * @param p_Port - * @param p_MessageBytes - * @param p_MessageLength - * @return - */ - virtual int sendMessageTo(int p_InetFamily, string p_ServerIP, string p_Port, const char* p_MessageBytes, int p_MessageLength) = 0; - /** - * Internal usage - don't use this manually.
- */ - virtual void getAdaptersInfo() = 0; - - - string getServerIP(); - string getServerPort(); - string getClientIP(); - string getClientPort(); - string getBoundClientPort(); - void setBoundClientPort(string p_Port); - void setBoundClientFamily(int p_Family); - int getBoundClientFamily(); - void setIsBound(bool p_IsBound); - bool getIsBound(); - + int sendMessage(const char* p_MessageBytes, int p_MessageLength) { + if (m_ServerPort.length() <= 0) + return -1; + int intResult; + { + if (m_IsBound == false) + return -1; + intResult = sendMessageTo(m_BoundClientFamily, m_ServerIP, m_ServerPort, p_MessageBytes, p_MessageLength); + } + return intResult; + } + int receiveMessage(int p_InetFamily, char* p_Buffer, int p_BufferLength, string* p_ServerIP); + int setBroadcast(bool p_Broadcast); + int bindSocket(string p_ClientIP, string p_ClientPort); + + // * Internal usage - don't use this manually + // * Use sendMessage instead + int sendMessageTo(int p_InetFamily, string p_ServerIP, string p_Port, const char* p_MessageBytes, int p_MessageLength); + + string getServerIP() { return m_ServerIP; } + string getServerPort(){ return m_ServerPort; } + string getClientIP() { return m_ClientIP; } + string getClientPort() { return m_ClientPort; } + string getBoundClientPort() { return m_BoundClientPort; } + void setBoundClientPort(string p_Port) { m_BoundClientPort = p_Port; } + void setBoundClientFamily(int p_Family) { m_BoundClientFamily = p_Family; } + int getBoundClientFamily() { return m_BoundClientFamily; } + void setIsBound(bool p_IsBound) { m_IsBound = p_IsBound; } + bool getIsBound() { return m_IsBound; } }; #endif /* SPITSOCKET_H */ diff --git a/components/spit/include/SPITType.h b/components/spit/include/SPITType.h index 713e67d..2315a71 100644 --- a/components/spit/include/SPITType.h +++ b/components/spit/include/SPITType.h @@ -14,12 +14,10 @@ #ifndef SPITTYPE_H #define SPITTYPE_H -#include "_SPITMACROS.h" +#include "SPITSocket.h" #include "SPIT_Message.h" #include #include -#include "Mutex.hpp" - using namespace std; @@ -27,16 +25,10 @@ class SPITTypeListener; class SPITType { private: - static fos::Mutex s_MutexSPITType; static unordered_map s_SPITTypes; static unordered_map s_SPITTypesRemote; - - public: - static fos::Mutex* getMutex() { - return &s_MutexSPITType; - } static SPITType* getSPITType(string p_ID); static const SPITType& getSPITTypeRef(string p_ID); static bool addSPITType(SPITType* p_ptrSpitType); @@ -82,15 +74,9 @@ private: void initMembers(); public: - string getID() const{ - return m_ID; - } - string getGroupName() const { - return m_GroupName; - } - string getName() const { - return m_Name; - } + string getID() const{ return m_ID; } + string getGroupName() const { return m_GroupName; } + string getName() const { return m_Name; } /** * Returns if the SPITType triggers an action on the Server or on the client. * @return false = the action is triggered on the client The client waits for the server to play objects of this SPITType
@@ -107,22 +93,11 @@ public: * This is used by the server and client to tell if the other side has registered the changes. * @return true = other side has registered the changes. */ - bool getConfirmed() const { - return m_Confirmed; - } - bool getFixed() const { - return m_Fixed; - } - long long getDefaultDelay() const { - return m_DefaultDelay; - } - long long getDefaultDuration() const { - return m_DefaultDuration; - } - - bool getCreatedByClient() const { - return m_CreatedByClient; - } + bool getConfirmed() const { return m_Confirmed; } + bool getFixed() const { return m_Fixed; } + long long getDefaultDelay() const { return m_DefaultDelay; } + long long getDefaultDuration() const { return m_DefaultDuration; } + bool getCreatedByClient() const { return m_CreatedByClient; } /** * Virtual construct - means ActionAssigned for SPITTypes is is not implemented in SPITProtocol.
diff --git a/components/spit/include/SPIT_Client.h b/components/spit/include/SPIT_Client.h index 69a65dd..f062bdf 100644 --- a/components/spit/include/SPIT_Client.h +++ b/components/spit/include/SPIT_Client.h @@ -14,30 +14,42 @@ #ifndef SPIT_CLIENT_H #define SPIT_CLIENT_H -#include "_SPITMACROS.h" -#include "UnixSocket.h" - #include "SPITSocket.h" -#include "SAD_Client.h" -#include "SAD_ClientInterface.h" -#include "SAD_DetectedServer.h" -#include "SPIT_ClientInterface.h" +#include "SAD_DetectedServer.hpp" #include "SPIT_Message.h" -#include "Watchdog.h" #include "SPITType.h" #include "SPITObject.h" -#include "SPIT_Handler.h" #include "SPITPlayer.h" +#include using namespace std; -//static char nullChar[] = "\0"; +class SPIT_Client : I_SAD_Client { -class SPIT_Client : SAD_ClientInterface, Watchdog::Listener { public: /** Maximal length of a SPITMessage*/ static const int MAXSPITMESSAGEBYTECOUNT = 512; + struct Callbacks { + void(*onServerDetect)(const SAD_DetectedServer &p_DetectedServer); + void(*onServerLost)(const SAD_DetectedServer &p_DetectedServer); + void(*onStartProjectTransfer)(); + void(*onEndProjectTransfer)(); + void(*onProjectClosed)(string); + void(*onProjectReport)(string p_ProjectID, string p_ProjectName, int p_FramesPerSeoond); + void(*onSpitType)(bool p_New, const SPITType &p_SPITType); + void(*onSpitTypeRemote)(bool p_New, const SPITType &p_SPITType); + void(*onSpitObject)(bool p_New, const SPITType &p_SPITType, const SPITObject &p_SPITObject); + void(*onSpitObjectRemote)(bool p_New, const SPITType &p_SPITType, const SPITObject &p_SPITObject); + void(*onSpitTypeRemoved)(const SPITType &p_SPITType); + void(*onSpitTypeRemoteRemoved)(const SPITType &p_SPITType); + void(*onSpitObjectRemoved)(const SPITType &p_SPITType, const SPITObject &p_SPITObject); + void(*onSpitObjectRemoteRemoved)(const SPITType &p_SPITType, const SPITObject &p_SPITObject); + void(*onPlay)(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_PlayerIsRunning, long long p_TimeFrames); + void(*onPlayObject)(string p_PlayerID, bool p_Started, bool p_Stopped, const SPITType &p_SPITType, const SPITObject &p_SPITObject, const SPITPlayer::PlayObject &p_PlayObject); + void(*onPlayRemoteObjectStatus)(const SPITType &p_SPITType, const SPITObject &p_SPITObject, long long p_FrameInsideObject, int p_Value); + }; + //----- Connection Status ----- public: /** No Connection established.
Either no connect tried or disconnected*/ @@ -46,7 +58,7 @@ public: static const int CONNECTION_NONESERVER = 1; /** The connection is lost
Either because of a network crash or because the server no longer responds.*/ static const int CONNECTION_LOST = 2; - /** Connection to the server is established.*/ + /** Connection to the serv er is established.*/ static const int CONNECTION_OK = 3; /** A connection to the server is tried.*/ static const int CONNECTION_TRYCONNECTION = 4; @@ -72,48 +84,38 @@ public: //----- SPIT_Client ----- public: - static SPITSocket* createSPITSocket(); -public: - SPIT_Client(SPIT_ClientInterface* p_SPITClientInterface); + SPIT_Client(string name, string projName, Callbacks calls); virtual ~SPIT_Client(); private: - /** SPITClientInterface, normally the user app should implement this*/ - SPIT_ClientInterface* m_SPITClientInterface; - SPITSocket* m_SPITSocket; - fos::Mutex m_MutexSPITSocket; - fos::TaskT * m_ThreadReceive; + Callbacks mCallbacks; + + fos::TaskT * m_ThreadReceive{}; bool m_StopReceiveSPITMessages; - + int m_ConnectionStatus; - bool m_DisconnectedByServer; //flag true = when server disconnects + bool m_DisconnectedByServer{}; //flag true = when server disconnects string m_ID; string m_Name; + string m_ProjName; string m_ComputerName; //Server's info filled by parseConnectAnswer - string m_ServerID; - string m_ServerName; - string m_ServerComputerName; - int m_ServerStepTime; - - - Watchdog* m_Watchdog; + string m_ServerID{}; + string m_ServerName{}; + string m_ServerComputerName{}; + int m_ServerStepTime{-1}; + unsigned char m_MessageNumber_Send; + int m_MessageNumber_Received; + //--- Server Project --- string m_ServerProjectID; string m_ServerProjectName; int m_ServerFramesPerSecond; -public: - SPIT_ClientInterface* getSPITClientInterface() { - return m_SPITClientInterface; - } - public: /** The ID of the client.
Every client instance should set an unique id*/ string getID(); - /** Set the name of the client, should be done by the user app*/ - void setName(string p_Name); /** The name of the client, should be set by the user app*/ string getName(); //----- Computer Params ----- @@ -153,10 +155,12 @@ private: bool startReceiveSPITMessages(); void stopReceiveSPITMessages(); static void receiveSPITMessage(SPIT_Client& rM); - int sendSPITMessage(SPIT_Message::OPPart* p_SPITMessageOPPart); + int sendSPITMessage(SPIT_Message::OPPart& p_SPITMessageOPPart); void fillHeader(SPIT_Message::Header* p_Header); - + // Reconnect to the server when connection is lost see eventConnectionStatus and eventServerDetected + bool _doReconnect{}; // true = on eventServerDetected connect to the server identified by m_ServerID + //--------------- ServerAutoDetection SAD --------------- public: /** Starts the autodetection of SPITServers in the local network. If a connection is tried, the autodetection should be stopped before.*/ @@ -164,48 +168,10 @@ public: /** 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(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_ClientIP, bool p_isLoopback, bool p_IsIP4, bool p_IsIP6); + void eventServerDetected(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_ClientIP, bool p_IsIP4); /** Called every time a prior detected SPITServer is is no longer found.*/ - void eventServerLost(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_ClientIP, bool p_isLoopback, bool p_IsIP4, bool p_IsIP6); + void eventServerLost(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_ClientIP, bool p_IsIP4); -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyServerDetected: virtual public SPIT_Handler::Runnable { - private: - SPIT_ClientInterface* m_SPITClientInterface; - SAD_DetectedServer m_DetectedServer; - public: - NotifyServerDetected(SPIT_ClientInterface* p_SPITClientInterface, const SAD_DetectedServer& p_DetetctedServer) { - m_SPITClientInterface = p_SPITClientInterface; - m_DetectedServer = p_DetetctedServer; - } - ~NotifyServerDetected(){} - void run() { - if (m_SPITClientInterface != NULL) { - m_SPITClientInterface->eventServerDetected(m_DetectedServer); - } - } - }; -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyServerLost: virtual public SPIT_Handler::Runnable { - private: - SPIT_ClientInterface* m_SPITClientInterface; - SAD_DetectedServer m_DetectedServer; - public: - NotifyServerLost(SPIT_ClientInterface* p_SPITClientInterface, const SAD_DetectedServer& p_DetetctedServer) { - m_SPITClientInterface = p_SPITClientInterface; - m_DetectedServer = p_DetetctedServer; - } - ~NotifyServerLost() {} - void run() { - if (m_SPITClientInterface != NULL) { - m_SPITClientInterface->eventServerLost(m_DetectedServer); - } - } - }; - - //--------------- Connection --------------- public: @@ -228,7 +194,7 @@ public: private: void disconnectInternal(int p_Cause); - void parseSPIT_Message(SPIT_Message* p_SPITMessage); + void parseSPIT_Message(unique_ptr p_SPITMessage); void parseConnectAnswer(SPIT_Message::ConnectAnswer* p_ConnectAnswer); void parseDisconnect(SPIT_Message::Disconnect* p_Disconnect); void parseWatchdog(SPIT_Message::Watchdog* p_Watchdog); @@ -238,36 +204,6 @@ public: void sendWatchdog(); /** Used internally. When the connection to the SPITServer is lost an eventConnectionStatus will occur*/ void eventWatchdogLost(); -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyConnectionStatus : public SPIT_Handler::Runnable { - public: - NotifyConnectionStatus(SPIT_ClientInterface* p_SPITClientInterface, string p_ServerID, string p_ServerComputerName, string p_ServerName, int p_ServerStepTime, - int p_NewConnectionStatus, int p_OldConnectionStatus) { - m_SPITClientInterface = p_SPITClientInterface; - m_ServerID = p_ServerID; - m_ServerComputerName = p_ServerComputerName; - m_ServerName = p_ServerName; - m_ServerStepTime = p_ServerStepTime; - m_NewConnectionStatus = p_NewConnectionStatus; - m_OldConnectionStatus = p_OldConnectionStatus; - } - ~NotifyConnectionStatus() {} - void run (){ - if (m_SPITClientInterface != NULL) { - m_SPITClientInterface->eventConnectionStatus(m_ServerComputerName, m_ServerID, m_ServerName, m_ServerStepTime, m_NewConnectionStatus, m_OldConnectionStatus); - } - } - private: - SPIT_ClientInterface* m_SPITClientInterface; - string m_ServerID; - string m_ServerComputerName; - string m_ServerName; - int m_ServerStepTime; - int m_NewConnectionStatus; - int m_OldConnectionStatus; - }; - //--------------- SPIT Project --------------- private: void parseReportSPITProject(SPIT_Message::ReportSPITProject* p_ReportSPITProject); @@ -279,84 +215,11 @@ public: 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(); - -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyReportProject : public SPIT_Handler::Runnable { - public: - NotifyReportProject(SPIT_ClientInterface* p_SPITClientInterface, string p_ProjectID, string p_ProjectName, int p_FramesPerSecond) { - m_SPITClientInterface = p_SPITClientInterface; - m_ProjectID = p_ProjectID; - m_ProjectName = p_ProjectName; - m_FramesPerSecond = p_FramesPerSecond; - } - ~NotifyReportProject() {} - void run() { - if (m_SPITClientInterface != NULL) { - m_SPITClientInterface->eventProjectReport(m_ProjectID, m_ProjectName, m_FramesPerSecond); - } - } - private: - SPIT_ClientInterface* m_SPITClientInterface; - string m_ProjectID; - string m_ProjectName; - int m_FramesPerSecond; - }; -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyProjectClosed : public SPIT_Handler::Runnable { - public: - NotifyProjectClosed(SPIT_ClientInterface* p_SPITClientInterface, string p_ProjectID) { - m_SPITClientInterface = p_SPITClientInterface; - m_ProjectID = p_ProjectID; - } - ~NotifyProjectClosed() {} - void run() { - if (m_SPITClientInterface != NULL) { - m_SPITClientInterface->eventProjectClosed(m_ProjectID); - } - } - private: - SPIT_ClientInterface* m_SPITClientInterface; - string m_ProjectID; - }; - + private: void parseRequestProjectTransfer(SPIT_Message::RequestProjectTransfer* p_RequestProjectTransfer); void parseStartProjectTransfer(SPIT_Message::StartProjectTransfer* p_StartProjectTransfer); void parseEndProjectTransfer(SPIT_Message::EndProjectTransfer* p_EndProjectTransfer); -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyStartProjectTransfer : public SPIT_Handler::Runnable { - public: - NotifyStartProjectTransfer(SPIT_ClientInterface* p_SPITClientInterface) { - m_SPITClientInterface = p_SPITClientInterface; - } - ~NotifyStartProjectTransfer() {} - void run() { - if (m_SPITClientInterface != NULL) { - m_SPITClientInterface->eventStartProjectTransfer(); - } - } - private: - SPIT_ClientInterface* m_SPITClientInterface; - }; -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyEndProjectTransfer : public SPIT_Handler::Runnable { - public: - NotifyEndProjectTransfer(SPIT_ClientInterface* p_SPITClientInterface) { - m_SPITClientInterface = p_SPITClientInterface; - } - ~NotifyEndProjectTransfer() {} - void run() { - if (m_SPITClientInterface != NULL) { - m_SPITClientInterface->eventEndProjectTransfer(); - } - } - private: - SPIT_ClientInterface* m_SPITClientInterface; - }; // --------------- SPIT Types --------------- @@ -408,60 +271,6 @@ public: */ int removeSPITType(string p_SPITTypeID); public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyReportSPITType : public SPIT_Handler::Runnable { - public: - NotifyReportSPITType(bool p_Remote, bool p_New, SPIT_ClientInterface* p_SPITClientInterface, const SPITType& p_SPITType) { - m_SPITClientInterface = p_SPITClientInterface; - m_Remote = p_Remote; - m_New = p_New; - m_SPITType = p_SPITType; - } - ~NotifyReportSPITType() {} - void run() { - if (m_SPITClientInterface != NULL) { - if (m_Remote == false) { - m_SPITClientInterface->eventSPITType(m_New, m_SPITType); - } - else { - m_SPITClientInterface->eventSPITTypeRemote(m_New, m_SPITType); - } - } - } - private: - SPIT_ClientInterface* m_SPITClientInterface; - bool m_Remote; - bool m_New; - SPITType m_SPITType; - }; - - -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyRemoveSPITType : public SPIT_Handler::Runnable { - public: - NotifyRemoveSPITType(bool p_Remote, SPIT_ClientInterface* p_SPITClientInterface, const SPITType& p_SPITType) { - m_SPITClientInterface = p_SPITClientInterface; - m_Remote = p_Remote; - m_SPITType = p_SPITType; - } - ~NotifyRemoveSPITType() {} - void run() { - if (m_SPITClientInterface != NULL) { - if (m_Remote == false) { - m_SPITClientInterface->eventSPITTypeRemoved(m_SPITType); - } - else { - m_SPITClientInterface->eventSPITTypeRemoteRemoved(m_SPITType); - } - } - } - private: - SPIT_ClientInterface* m_SPITClientInterface; - bool m_Remote; - SPITType m_SPITType; - }; - //--------------- SPIT Objects --------------- private: @@ -484,63 +293,6 @@ public: */ int removeSPITObject(string p_SPITObjectID); public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyReportSPITObject : public SPIT_Handler::Runnable { - public: - NotifyReportSPITObject(bool p_Remote, bool p_New, SPIT_ClientInterface* p_SPITClientInterface, const SPITType& p_SPITType, const SPITObject& p_SPITObject) { - m_SPITClientInterface = p_SPITClientInterface; - m_Remote = p_Remote; - m_New = p_New; - m_SPITType = p_SPITType; - m_SPITObject = p_SPITObject; - } - ~NotifyReportSPITObject() {} - void run() { - if (m_SPITClientInterface != NULL) { - if (m_Remote == false) { - m_SPITClientInterface->eventSPITObject(m_New, m_SPITType, m_SPITObject); - } - else { - m_SPITClientInterface->eventSPITObjectRemote(m_New, m_SPITType, m_SPITObject); - } - } - } - private: - SPIT_ClientInterface* m_SPITClientInterface; - bool m_Remote; - bool m_New; - SPITType m_SPITType; - SPITObject m_SPITObject; - }; -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyRemoveSPITObject : public SPIT_Handler::Runnable { - public: - NotifyRemoveSPITObject(bool p_Remote, SPIT_ClientInterface* p_SPITClientInterface, const SPITType& p_SPITType, const SPITObject& p_SPITObject) { - m_SPITClientInterface = p_SPITClientInterface; - m_Remote = p_Remote; - m_SPITType = p_SPITType; - m_SPITObject = p_SPITObject; - } - ~NotifyRemoveSPITObject() {} - void run() { - if (m_SPITClientInterface != NULL) { - if (m_Remote == false) { - m_SPITClientInterface->eventSPITObjectRemoved(m_SPITType, m_SPITObject); - } - else { - m_SPITClientInterface->eventSPITObjectRemoteRemoved(m_SPITType, m_SPITObject); - } - } - } - private: - SPIT_ClientInterface* m_SPITClientInterface; - bool m_Remote; - SPITType m_SPITType; - SPITObject m_SPITObject; - }; - - //--------------- Play SPIT Objects --------------- private: @@ -548,91 +300,22 @@ private: void parsePlaySPITObject(SPIT_Message::PlaySPITObject* p_PlaySPITObject); void parsePlaySPITEnd(SPIT_Message::PlaySPITEnd* p_PlaySPITEnd); void parseReportPlayStatus(SPIT_Message::ReportPlayStatus* p_ReportPlayStatus); - -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyPlaySPITStart : public SPIT_Handler::Runnable { - public: - NotifyPlaySPITStart(SPIT_ClientInterface* p_SPITClientInterface, string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_IsRunning, long long p_TimeFrame) { - m_SPITClientInterface = p_SPITClientInterface; - m_PlayerID = p_PlayerID; - m_PlayerName = p_PlayerName; - m_PlayerType = p_PlayerType; - m_IsRunning = p_IsRunning; - m_TimeFrames = p_TimeFrame; - } - ~NotifyPlaySPITStart() {} - void run() { - if (m_SPITClientInterface != NULL) { - m_SPITClientInterface->eventPlay(m_PlayerID, m_PlayerName, m_PlayerType, m_IsRunning, m_TimeFrames); - } - } - private: - SPIT_ClientInterface* m_SPITClientInterface; - string m_PlayerID; - string m_PlayerName; - char m_PlayerType; - bool m_IsRunning; - long long m_TimeFrames; - }; -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyPlaySPITObject : public SPIT_Handler::Runnable { - public: - NotifyPlaySPITObject(bool p_Started, bool p_Stopped, - SPIT_ClientInterface* p_SPITClientInterface, const SPITType& p_SPITType, const SPITObject& p_SPITObject, const SPITPlayer::PlayObject& p_PlayObject) { - m_Started = p_Started; - m_Stopped = p_Stopped; - m_SPITClientInterface = p_SPITClientInterface; - m_SPITType = p_SPITType; - m_SPITObject = p_SPITObject; - m_PlayObject = p_PlayObject; - } - ~NotifyPlaySPITObject() {} - void run() { - if (m_SPITClientInterface != NULL) { - m_SPITClientInterface->eventPlayObject(m_PlayObject.getPlayerID(), m_Started, m_Stopped, m_SPITType, m_SPITObject, m_PlayObject); - } - } - private: - bool m_Started; - bool m_Stopped; - SPIT_ClientInterface* m_SPITClientInterface; - SPITObject m_SPITObject; - SPITType m_SPITType; - SPITPlayer::PlayObject m_PlayObject; - }; -public: - /** Helper class to notify the SPITClientInterface/user's app*/ - class NotifyReportPlayStatus: public SPIT_Handler::Runnable { - public: - NotifyReportPlayStatus(SPIT_ClientInterface* p_SPITClientInterface, const SPITType& p_SPITType, const SPITObject& p_SPITObject, - long long p_FrameInsideObject, int p_Value) { - m_SPITClientInterface = p_SPITClientInterface; - m_SPITObject = p_SPITObject; - m_SPITType = p_SPITType; - m_FrameInsideObject = p_FrameInsideObject; - m_Value = p_Value; - } - ~NotifyReportPlayStatus() {} - private: - SPIT_ClientInterface* m_SPITClientInterface; - SPITObject m_SPITObject; - SPITType m_SPITType; - long long m_FrameInsideObject; - int m_Value; - public: - void run() { - if (m_SPITClientInterface != NULL) { - m_SPITClientInterface->eventPlayRemoteObjectStatus(m_SPITType, m_SPITObject, m_FrameInsideObject, m_Value); - } - } - }; - - + public: //--------- Remote ---------- void sendRemoteObject(string p_SPITObjectID, int p_Valueppm = 0, char p_ValueFlag = 0x00); + + private: + static void processSocketTask(SPIT_Client & instance); + fos::TaskT* sThread{}; + bool abortSearch{}; + bool sAnswered{}; + static fos::Semaphore sStartSad; + SPITSocket * mSPITSocket; + void answerWatchdog() { + sAnswered = true; + } + }; #endif /* SPIT_CLIENT_H */ diff --git a/components/spit/include/SPIT_ClientInterface.h b/components/spit/include/SPIT_ClientInterface.h deleted file mode 100644 index 66de2e1..0000000 --- a/components/spit/include/SPIT_ClientInterface.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * File: SPIT_ClientInterface.h - * Author: Hagi - * - * Created on 17. April 2019, 16:15 - */ - -#ifndef SPIT_CLIENTINTERFACE_H -#define SPIT_CLIENTINTERFACE_H - -//#include - -#include "SPITType.h" -#include "SPITObject.h" -#include "SPITPlayer.h" -#include "SAD_DetectedServer.h" - -using namespace std; - -class SPIT_ClientInterface { -public: - - virtual string getClientProjectID() = 0; - virtual string getClientProjectName() = 0; - - /** - * If a new server was found by the ServerAutoDetect mechanism, this function is called. - * If a server can be reached via several IP addresses, the IP address is selected according to the following preference:
- * 1.) If a loopback address is available, it is used.
- * 2.) If an IP4 address is available, it is used.
- * 3.) In the other cases the IP6 address is used.
- * @param p_ID the id of the server (every started server should generate an id) - * @param p_Name the name of the SPIT server - * @param p_ComputerName the Hostname of the cpmputer on which the SPIT server is running - * @param p_IP the selected ip address of the SPIT server - * @param p_Port the port of the SPIT server - * @param p_Addition sometimes server may have additional informations - * @param p_isLoopback the server ip is a loopback address - * @param p_IsIP4 the server ip is a ip4 address - * @param p_IsIP6 the server ip is a ip6 address - */ - virtual void eventServerDetected(const SAD_DetectedServer& p_DetectedServer) = 0; - virtual void eventServerLost(const SAD_DetectedServer& p_DetectedServer) = 0; - - virtual void eventConnectionStatus(string p_ServerID, string p_ServerComputerName, string p_ServerName, int p_ServerStepTime, int p_ConnectionStatus, int p_OldConnectionStatus) = 0; - - virtual void eventProjectReport(string p_ProjectID, string p_ProjectName, int p_FramesPerSeoond) = 0; - virtual void eventProjectClosed(string p_ProjectID) = 0; - - - virtual void eventStartProjectTransfer() = 0; - virtual void eventEndProjectTransfer() = 0; - - virtual void eventSPITType(bool p_New, const SPITType& p_SPITType) = 0; - virtual void eventSPITTypeRemote(bool p_New, const SPITType& p_SPITType) = 0; - - virtual void eventSPITTypeRemoved(const SPITType& p_SPITType) = 0; - virtual void eventSPITTypeRemoteRemoved(const SPITType& p_SPITType) = 0; - - - virtual void eventSPITObject(bool p_New, const SPITType& p_SPITType, const SPITObject& p_SPITObject) = 0; - virtual void eventSPITObjectRemote(bool p_New, const SPITType& p_SPITType, const SPITObject& p_SPITObject) = 0; - virtual void eventSPITObjectRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject) = 0; - virtual void eventSPITObjectRemoteRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject) = 0; - - virtual void eventPlay(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_PlayerIsRunning, long long p_TimeFrames) = 0; - - virtual void eventPlayObject(string p_PlayerID, bool p_Started, bool p_Stopped, const SPITType& p_SPITType, const SPITObject& p_SPITObject, const SPITPlayer::PlayObject& p_PlayObject) = 0; - - - //REMOTE Server->Client - virtual void eventPlayRemoteObjectStatus(const SPITType& p_SPITType, const SPITObject& p_SPITObject, long long p_FrameInsideObject, int p_Value) = 0; -}; - -#endif /* SPIT_CLIENTINTERFACE_H */ - diff --git a/components/spit/include/SPIT_Handler.h b/components/spit/include/SPIT_Handler.h deleted file mode 100644 index 43be675..0000000 --- a/components/spit/include/SPIT_Handler.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * File: SPIT_Handler.h - * Author: Hagi - * - * Created on 24. April 2019, 11:17 - */ - -#ifndef SPIT_HANDLER_H -#define SPIT_HANDLER_H - -#include "Mutex.hpp" -#include "Semaphore.hpp" -#include "Task.hpp" -#include - -using namespace std; - -class SPIT_Handler { -public: - class Runnable { - public: - Runnable() {}; - virtual ~Runnable(); - virtual void run() = 0; - }; - -private: - static list s_Runnables; - static fos::Mutex s_MutexLock; - static fos::Semaphore s_ConditionVariable; - static fos::Task* s_HandlerThread; - - static bool s_WakeUp; - static bool s_Close; - static void run(); -public: - static void addRunnable(Runnable* p_Runnable); - static void closeHandler(); -}; - -#endif /* SPIT_HANDLER_H */ - diff --git a/components/spit/include/UnixSocket.h b/components/spit/include/UnixSocket.h deleted file mode 100644 index 1cd2aa5..0000000 --- a/components/spit/include/UnixSocket.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * File: UnixSocket.h - * Author: Hagi - * - * Created on 12. April 2019, 15:58 - */ - -#ifndef UNIXSOCKET_H -#define UNIXSOCKET_H - -#include "_SPITMACROS.h" -#include -#include -#include -#include -#include -#include -#include - -#include "SPITSocket.h" - -class UnixSocket : public SPITSocket{ -public: - static const int INVALID_SOCKET = -1; -public: - UnixSocket(); - virtual ~UnixSocket(); -private: - int m_UDPSocketIP4; - int m_UDPSocketIP6; -public: - void getAdaptersInfo(); - string getBroadcastIP4(IPAddress* p_IPAdress); - int setBroadcast(bool p_Broadcast); - - static int init(); - static int cleanUp(); - bool createSocket_UDP(); - int bindSocket(string p_ClientIP, string p_ClientPort); - int sendMessageTo(int p_InetFamily, string p_ServerIP, string p_ServerPort, const char* p_MessageBytes, int p_MessageLength); - int receiveMessage(int p_InetFamily, char* p_Buffer, int p_BufferLength, string* p_ServerIP); -}; - -#endif /* UNIXSOCKET_H */ - diff --git a/components/spit/include/Watchdog.h b/components/spit/include/Watchdog.h deleted file mode 100644 index e354705..0000000 --- a/components/spit/include/Watchdog.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * File: Watchdog.h - * Author: Hagi - * - * Created on 22. April 2019, 13:02 - */ - -#ifndef WATCHDOG_H -#define WATCHDOG_H - -#include "_SPITMACROS.h" -#include "Mutex.hpp" -#include "Semaphore.hpp" -#include "Task.hpp" - -using namespace std; - - -class Watchdog { -public: - class Listener { - public: - virtual void sendWatchdog()=0; - virtual void eventWatchdogLost()=0; - }; - - static int WATCHDOGTIME; - static bool s_StopWatchdog; - - Watchdog(Listener* p_Listener); - virtual ~Watchdog(); - -private: - Listener* m_Listener; - - fos::Mutex m_MutexLock; - fos::Semaphore m_ConditionVariable; - fos::TaskT* m_WatchdogThread; - - bool m_Answered; - - static void runWatchdog(Watchdog& wd); -public: - void startWatchdog(); - void answerWatchdog(); - void stopWatchdog(); -}; - -#endif /* WATCHDOG_H */ - diff --git a/components/spit/include/_SPITMACROS.h b/components/spit/include/_SPITMACROS.h deleted file mode 100644 index fe10572..0000000 --- a/components/spit/include/_SPITMACROS.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include -// #include - -// To output debug information (printf calls in the code) -// you must set or comment out this precompiler definition - -#include -using namespace std; - -/** Returns an guid */ -string createGUID(); -/** Returns the name of the client's host computer*/ -string getClientHostName(); diff --git a/components/spit/src/MyApp.cpp b/components/spit/src/MyApp.cpp index 58b093c..4ae2924 100644 --- a/components/spit/src/MyApp.cpp +++ b/components/spit/src/MyApp.cpp @@ -2,556 +2,294 @@ #include "MyApp.h" #include "Task.hpp" #include "esp_log.h" -#include "SPIT_Handler.h" +#include "Semaphore.hpp" +#include "Queue.hpp" +#include -string MyApp::s_ClientName = "MySPITApp_Client"; //Name of this Client -const char * TAG = "SPIT"; +const char *TAG = "SPIT"; +MyApp::MyApp() : + _SpitClient ( + s_ClientName, s_ProjectName, + { + .onServerDetect = onServerDetected, + .onServerLost = onServerLost, + .onStartProjectTransfer = onStartProjectTransfer, + .onEndProjectTransfer = onEndProjectTransfer, + .onProjectClosed = onProjectClosed, + .onProjectReport = onProjectReport, + .onSpitType = onSpitType, + .onSpitTypeRemote = onSpitTypeRemote, + .onSpitObject = onSpitObject, + .onSpitObjectRemote = onSpitObjectRemote, + .onSpitTypeRemoved = onSpitTypeRemoved, + .onSpitTypeRemoteRemoved = onSpitTypeRemoteRemoved, + .onSpitObjectRemoved = onSpitObjectRemoved, + .onSpitObjectRemoteRemoved = onSpitObjectRemoteRemoved, + .onPlay = onPlay, + .onPlayObject = onPlayObject, + .onPlayRemoteObjectStatus = onPlayRemoteObjectStatus, + }) { -void SpitClientApp() { - ESP_LOGI(TAG, "Starting SPIT task"); - // fos::Task spit(SPIT_Handler::run,"SpitHandl"); + } - auto ptrMyApp = std::make_unique(); +string MyApp::m_ServerProjectID{}; +string MyApp::m_ServerProjectName{}; +int MyApp::m_ServerFramesPerSecond{44100}; // set when the server reports his project, see eventProjectReport - //load a client project - //the client project may belong to a server's project or may be independend of server's projects - //if the client project belongs to a specific server project - // -> add some code in the function eventProjectReport(..) (for excample create special SPITTypes or Actions - //if the client project is independend od server's project - // -> use loadClientProject() to create all SPITypes and actions - //An action is bound to a SPITType and called when the server plays a SPITObject that references the SPITType - // see eventPlayObject - ptrMyApp->loadClientProject(); - - //start autodetection of SPITServers - //autodetection of SPITServers ends automaticallay when this SPITClient is connected to a SPITServer - ptrMyApp->startServerAutoDetect(); +void MyApp::init() { + SPITType *ptrSPITType1Fix; + ptrSPITType1Fix = _SpitClient.createSPITTypeFixed("MySPITAPP_Action1ID", "ActionGroupName", "Action1Name", 0, 0); + SPITType *ptrSPITType2Fix; + ptrSPITType2Fix = _SpitClient.createSPITTypeFixed("MySPITAPP_Action2ID", "ActionGroupName", "Action2Name", 0, 0); - while (true) { - fos::Task::delayMs(10000); - ptrMyApp->testLiveShowRemote(); //This is an excample how to remote control the liveSHOWsoftware - } + // When an action exist which should be done whenever a SPITObject with this SPITType is played, + // then you should 'setAssignedActionType' to true + _SpitClient.setActionSPITType(ptrSPITType1Fix->getID(), true); + _SpitClient.setActionSPITType(ptrSPITType2Fix->getID(), true); + _SpitClient.clientProjectLoaded(); + _SpitClient.startServerAutoDetect(); } -MyApp::MyApp() { - m_SPIT_Client = new SPIT_Client(this); - //You need to give your application a descriptive name - m_SPIT_Client->setName(s_ClientName); - - //The following members are set in loadClientProject function. - m_ClientProjectID = ""; - - //The following members are set in the eventConnectionStatus - m_ServerID = ""; - m_ServerComputerName = ""; - m_ServerName = ""; - m_ServerStepTime = -1; - - //The follwing members are set in eventProjectReport - m_ServerProjectID = ""; - m_ServerProjectName = ""; - m_ServerFramesPerSecond = 44100; //is reset in eventProjectReport. - - //Used to decide if a reconnection is tried after the connection is lost - m_FlagReconnect = false; +void MyApp::onServerDetected(const SAD_DetectedServer &p_DetectedServer) { + ESP_LOGI(TAG, "SERVER DETECTED"); + ESP_LOGD(TAG, " Name: %s", p_DetectedServer.getName().data()); + ESP_LOGD(TAG, " ID: %s", p_DetectedServer.getID().data()); + ESP_LOGD(TAG, " Computer: %s", p_DetectedServer.getComputerName().data()); + ESP_LOGD(TAG, " IP: %s", p_DetectedServer.getIP().data()); + ESP_LOGD(TAG, " Port: %s", p_DetectedServer.getPort().data()); + ESP_LOGD(TAG, " Addition: %s", p_DetectedServer.getAdditions().data()); + ESP_LOGD(TAG, " ClientIP: %s", p_DetectedServer.getClientIP().data()); } - -MyApp::~MyApp() { - //To close the connection and all other stuff delete the SPIT_Client instance - if (m_SPIT_Client != NULL) { - delete m_SPIT_Client; - } +void MyApp::onServerLost(const SAD_DetectedServer &p_DetectedServer) { + ESP_LOGW(TAG, "Server lost Name: %s IP: %s", p_DetectedServer.getName().data(), p_DetectedServer.getIP().data()); } -//Following functions fullfill the SPIT_ClientInterface -//They are needed when the server sends his project, see eventProjectReport -string MyApp::getClientProjectID() { - return m_ClientProjectID; -} - -//Following functions fullfill the SPIT_ClientInterface -//They are needed when the server sends his project, see eventProjectReport -string MyApp::getClientProjectName() { - return m_ClientProjectName; -} - -void MyApp::loadClientProject() { - //----- close current client project ----- - if (m_SPIT_Client != NULL) { - m_SPIT_Client->clientProjectClose(); - } - - if (m_SPIT_Client != NULL) { - //Create SPITTypes for all discrete and unchangable functions of this client. Fixed means the server can't change or remove the SPITType. - SPITType* ptrSPITType1Fix; - ptrSPITType1Fix = m_SPIT_Client->createSPITTypeFixed("MySPITAPP_Action1ID", "ActionGroupName", "Action1Name", 0, 0); - - SPITType* ptrSPITType2Fix; - ptrSPITType2Fix = m_SPIT_Client->createSPITTypeFixed("MySPITAPP_Action2ID", "ActionGroupName", "Action2Name", 0, 0); - - //When an action exist which should be done whenever a SPITObject with this SPITType is played,
- //then you should 'setAssignedActionType' to true - m_SPIT_Client->setActionSPITType(ptrSPITType1Fix->getID(), true); - m_SPIT_Client->setActionSPITType(ptrSPITType2Fix->getID(), true); - //later in the eventPlayObject you can react with your action code for "Action1" and "Action2" - } - - if (m_SPIT_Client != NULL) { - m_SPIT_Client->clientProjectLoaded(); - } -} - -//----------------------------------------- -//---------- ServerAutoDetection ---------- - -void MyApp::startServerAutoDetect() { - if (m_SPIT_Client != NULL) { - m_SPIT_Client->startServerAutoDetect(); - } -} -void MyApp::stopServerAutoDetect() { - if (m_SPIT_Client != NULL) { - m_SPIT_Client->stopServerAutoDetect(); - } -} - -//------------------------------------------------------ -//----- All events are delegated to the SPIT_Handler. -//----- The follwoing event functions are called -//----- by the one thread s_HandlerThread of the SPIT_Handler -//------------------------------------------------------ - -/** - * Is always called when a new SPIT server is found.
- * For this you have to call SPIT_Client::startServerAutoDetect.
- * @param p_DetectedServer a reference to a copy of a SAD_DetectedServer instance.
- * After this function call the copy of the SAD_DetectedServer will be deleted!!
- */ -void MyApp::eventServerDetected(const SAD_DetectedServer& p_DetectedServer) { - //fetch the infoemations from the p_DetectedServer - ESP_LOGD(TAG, "SERVER DETECTED"); - ESP_LOGD(TAG, " Name: %s", p_DetectedServer.getName().data()); - ESP_LOGD(TAG, " ID: %s", p_DetectedServer.getID().data()); - ESP_LOGD(TAG, " Computer: %s", p_DetectedServer.getComputerName().data()); - ESP_LOGD(TAG, " IP: %s", p_DetectedServer.getIP().data()); - ESP_LOGD(TAG, " Port: %s", p_DetectedServer.getPort().data()); - ESP_LOGD(TAG, " Addition: %s", p_DetectedServer.getAdditions().data()); - ESP_LOGD(TAG, " ClientIP: %s", p_DetectedServer.getClientIP().data()); - - bool boolSuccess = false; - //---------- RECONNECTION ---------- - //If a connection has been established and the connection is lost -> reconnect - if (m_FlagReconnect == true) { - //check if the server is the same as prior connected - if (m_ServerID == p_DetectedServer.getID()) { - if (m_SPIT_Client != NULL) { - stopServerAutoDetect(); - ESP_LOGI(TAG,"reconnect to %s", p_DetectedServer.getIP().data()); - boolSuccess = m_SPIT_Client->connect(p_DetectedServer.getIP(), p_DetectedServer.getPort(), p_DetectedServer.getClientIP(), "0"); //ClientPort = "0" meeans use any port - if (boolSuccess == true) { - return; - } - } - } - } - - //Excample use the first detected LOOPBACK server, means the server runs on the same computer as this client - if (p_DetectedServer.getIpIsLoopback() == true) { //omit the if condition if you want to use the first server found - return; - } - boolSuccess = false; - //Stop auto detection because a suitable server was found - stopServerAutoDetect(); - if (m_SPIT_Client != NULL) { - ESP_LOGI(TAG,"connect to %s", p_DetectedServer.getIP().data()); - boolSuccess = m_SPIT_Client->connect(p_DetectedServer.getIP(), p_DetectedServer.getPort(), p_DetectedServer.getClientIP(), "0"); //ClientPort = "0" meeans use any port - } - if (boolSuccess == false) { - //connection message could not be sent -> better to restart AutoDetection - startServerAutoDetect(); - } -} - - -/** - * Is always called when a SPIT server does not respond anymore.
- * For this you have to call SPIT_Client::startServerAutoDetect.
- * This is an information used by autodetection and not by an established connection.
- *
- * When a connection to a SPITServer is established, the autodetection should be stopped.
- * The connection lost event is detected by eventConnectionStatus
- *
- * @param p_DetectedServer a reference to a copy of a SAD_DetectedServer instance.
- * After this function call the copy of the SAD_DetectedServer will be deleted!!
- */ -void MyApp::eventServerLost(const SAD_DetectedServer& p_DetectedServer) { - ESP_LOGW(TAG, "Server lost Name: %s IP: %s", p_DetectedServer.getName().data(), p_DetectedServer.getIP().data()); -} - - //--------------------------------------- //---------- Connecting event ---------- void MyApp::eventConnectionStatus(string p_ServerID, string p_ServerComputerName, string p_ServerName, int p_ServerStepTime, int p_ConnectionStatus, int p_OldConnectionStatus) { - ESP_LOGD(TAG, "eventConnectionStatus %d ", p_ConnectionStatus); - switch(p_ConnectionStatus) { - case SPIT_Client::CONNECTION_NONE: - ESP_LOGD(TAG, "not connected"); - break; - case SPIT_Client::CONNECTION_NONESERVER: - ESP_LOGD(TAG, "connection terminated by server"); - //call eventProjectClosed because this may not be sended by the server, - //when the connstion is closed - eventProjectClosed(m_ServerProjectID); - - //Server has terminated the connection -> start a new game - m_FlagReconnect = false; - startServerAutoDetect(); - break; - case SPIT_Client::CONNECTION_OK: - ESP_LOGD(TAG, "connection established"); - stopServerAutoDetect(); //normally you should stop the autodetection before you try a connection - //This is redundand - m_ServerID = p_ServerID; - m_ServerComputerName = p_ServerComputerName; - m_ServerName = p_ServerName; - m_ServerStepTime = p_ServerStepTime; - - //Maybe you want to reconnect, see eventServerDetected(...) - //Here the connection is established -> don't reconnect at eventServerDetected(...) - m_FlagReconnect = false; - break; - case SPIT_Client::CONNECTION_LOST: - 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(...) - m_FlagReconnect = true; - startServerAutoDetect(); - break; - } } - //----------------------------------------------------------- //---------- Server's Project events ------------------------ /** * The Server reports his loaded project - * Called when
- * a) the connection to the server is established.
- * b) server load a new project
- * c) server saves the project under a new name
- * @param p_ProjectID the server project's id
- * (maybe the filename of the project or a part o it or the same as p_ProjectName) + * Called when + * a) the connection to the server is established. + * b) server load a new project + * c) server saves the project under a new name + * @param p_ProjectID the server project's id (maybe the filename of the project or a part o it or the same as p_ProjectName) * @param p_ProjectName the server project's name * @param p_FramesPerSeoond All times in SPIT are given in frames. FramesPerSecond can be used to convert frames to seconds.... */ -void MyApp::eventProjectReport(string p_ProjectID, string p_ProjectName, int p_FramesPerSeoond) { - ESP_LOGD(TAG, "eventProjectReport ID: %s Name: %s FramesPerSecond: %d", p_ProjectID.data(), p_ProjectName.data(), p_FramesPerSeoond); - m_ServerProjectID = p_ProjectID; - m_ServerProjectName = p_ProjectName; - m_ServerFramesPerSecond = p_FramesPerSeoond; - - //set the frames per second as the server - perhaps the client's time values have to be recalculated. - m_ServerFramesPerSecond = p_FramesPerSeoond; - - //When the this client's project depends on the server's project -> load some specific informations here +void MyApp::onProjectReport(string p_ProjectID, string p_ProjectName, int p_FramesPerSeoond) { + ESP_LOGI(TAG, "eventProjectReport ID: %s Name: %s FramesPerSecond: %d", p_ProjectID.data(), p_ProjectName.data(), p_FramesPerSeoond); + m_ServerProjectID = p_ProjectID; + m_ServerProjectName = p_ProjectName; + m_ServerFramesPerSecond = p_FramesPerSeoond; + // set the frames per second as the server - perhaps the client's time values have to be recalculated. } /** - * Called when the server closes his project.
- * @param p_ProjectID the id of the project
+ * Called when the server closes his project. + * @param p_ProjectID the id of the project * The server loads only one project at time-> the ID is not actually necessary */ -void MyApp::eventProjectClosed(string p_ProjectID) { - ESP_LOGD(TAG, "eventProjectClosed ID: %s", p_ProjectID.data()); - //If we don't save SPITServer's project specific information - //perhaps close all SPITObjects and RemoteSPITObjects to avoid conflicts, when the SPITServer loads a new project - //SPITObject::clearSPITObjects(); - //SPITObject::clearSPITObjectsRemote(); +void MyApp::onProjectClosed(string p_ProjectID) { + ESP_LOGI(TAG, "eventProjectClosed ID: %s", p_ProjectID.data()); + // If we don't save SPITServer's project specific information + // perhaps close all SPITObjects and RemoteSPITObjects to avoid conflicts, when the SPITServer loads a new project + // SPITObject::clearSPITObjects(); + // SPITObject::clearSPITObjectsRemote(); } -/** - * The server starts the transfer of its project, that means:.
- * All SPITTypes and SPITObjects available on the server are transferred in the following.
- * Several calls of eventSPITType and eventSPITObject will occur.
- * At the end eventEndProjectTransfer is called. - */ -void MyApp::eventStartProjectTransfer() { - ESP_LOGD(TAG, "eventStartProjectTransfer"); +// The server starts the transfer of its project, that means +// All SPITTypes and SPITObjects available on the server are transferred in the following. +void MyApp::onStartProjectTransfer() { + ESP_LOGI(TAG, "eventStartProjectTransfer"); } -/** - * The transfer of the server's SPITTypes and SPITObjects is finished.
- * AFter this all eventSPITType and eventSPITObject means that new types , objects are created or changed. - */ -void MyApp::eventEndProjectTransfer() { - ESP_LOGD(TAG, "eventEndProjectTransfer"); +// The transfer of the server's SPITTypes and SPITObjects is finished. +void MyApp::onEndProjectTransfer() { + ESP_LOGI(TAG, "eventEndProjectTransfer"); } - //---------------------------------------------------- //--------- SPITType events ---------- -// SPITTypes describing an action or a type of an action. -// To trigger an action SPITObjects are used. Every SPITObject has one of the SPITTypes assigned.
-// There are two ways action can be triggered, either the server triggers an action on the client, -// or the client sends remote control commands to the server. -// a) normal types that are comitted to the client and played per SPITObjects by server, so the client can react with actions. -// b) Remote types are used for remote control of the server and are played by the client via SPIT objects. -//All normal SPITTypes are listet in a static unordered_map in the SPITType class. -//All remote SPITTypes are listet in a seperate static unordered_map in the SPITType class. -//You can use the SPITType::get... functions to deal with them. -//The SPITType class has a static recursive_mutex, you get a pointer of the mutex by: SPITType::getMutex(); -//To be thread save you should cover your code with a lock sequence: -/* - { //start of the lock sequence - unique_lock o_LockType(*SPITType::getMutex()); - //got the lock - - //fetch SPITType and deal with, but don't waste time while you holding the lock - //Excample - SPITType* ptrSPITType; - for (int i = 0; i < SPITType::getSPITTypeCount(); i ++) { - ptrSPITType = SPITType::getSPITType(i); - if (ptrSPITType == NULL) break; - //Do something with ptrSPITType - //bew aware after you leave the lock sequence the ptrSPITType is no longer save!! - } - } //end of the lock sequence - - //For Remote Types you can use the getSPITTypeRemote... functions -*/ - /** - * Called when the server has created, loaded or changed a SPITType.
- * May also occur when the server confirms a SPITType created or changed by the client.
- * @param p_New true = server created a new SPITType
- * false = server changed a existing SPITType
- * @param p_SPITType a reference to a copy of the SPITType instance.
- * The reference is deleted after this function call!! + * Called when the server has created, loaded or changed a SPITType. + * May also occur when the server confirms a SPITType created or changed by the client. + * @param p_New true = server created a new SPITType + * false = server changed a existing SPITType + * @param p_SPITType a reference to a copy of the SPITType instance. */ -void MyApp::eventSPITType(bool p_New, const SPITType& p_SPITType) { - //fetch information of the SPITType - if (p_New) { - //a new SPITType is created - ESP_LOGD(TAG, "eventSPITType NEW"); - } - else { - //an existing SPITType is changed - ESP_LOGD(TAG, "eventSPITType CHANGED"); - } - ESP_LOGD(TAG, " ID: %s GroupName: %s Name: %s confirmed: %d", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data(), p_SPITType.getConfirmed()); +void MyApp::onSpitType(bool p_New, const SPITType &p_SPITType) { + // fetch information of the SPITType + if (p_New) { + ESP_LOGD(TAG, "eventSPITType NEW"); + } else { + ESP_LOGD(TAG, "eventSPITType CHANGED"); + } + ESP_LOGI(TAG, " ID: %s GroupName: %s Name: %s confirmed: %d", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data(), p_SPITType.getConfirmed()); - //Check your actions - //Whenever you provide an action for this SPITType take this over in your code. - //call m_SPIT_Client->setActionSPITType(p_SPITType.getID(), true); - - //for our little excample as described in loadClientProject we do following - if (m_SPIT_Client != NULL) { - //This may be redundand, because we defined the SPITTypes as fixed, so the server can't change them - //But foe all SPITTypes which are not fixed we need to setActionSPITType - if ("MySPITAPP_Action1ID" == p_SPITType.getID()) { - m_SPIT_Client->setActionSPITType(p_SPITType.getID(), true); - } - if ("MySPITAPP_Action2ID" == p_SPITType.getID()) { - m_SPIT_Client->setActionSPITType(p_SPITType.getID(), true); - } - } + // Check your actions + // Whenever you provide an action for this SPITType take this over in your code. + // call _SpitClient.setActionSPITType(p_SPITType.getID(), true); + + // for our little excample as described in loadClientProject we do following + // This may be redundand, because we defined the SPITTypes as fixed, so the server can't change them + // But foe all SPITTypes which are not fixed we need to setActionSPITType + + // if ("MySPITAPP_Action1ID" == p_SPITType.getID()) { + // _SpitClient.setActionSPITType(p_SPITType.getID(), true); + // } + // if ("MySPITAPP_Action2ID" == p_SPITType.getID()) { + // _SpitClient.setActionSPITType(p_SPITType.getID(), true); + // } } /** - * Called when the server has created or changed a Remote SPITType.
+ * Called when the server has created or changed a Remote SPITType. * Remote SPITType are used in Remote SPITObjects. A Remote SPITObject is used to remote control the SPITServer. - * @param p_New true = server created a new SPITType
- * false = server changed a existing SPITType
- * @param p_SPITType a reference to a copy of the SPITType instance.
- * The reference is deleted after this function call!! + * @param p_New true = server created a new SPITType / false = server changed a existing SPITType */ -void MyApp::eventSPITTypeRemote(bool p_New, const SPITType& p_SPITType) { - if (p_New) { - ESP_LOGD(TAG, "eventSPITTypeRemote NEW"); - } - else { - //we had to inform all Remote SPITObjects using the p_SPITType - //perhaps the SPITObject uses information from the SPITType - SPITObject* ptrSPITObject; - int intSPITObjectCount; - intSPITObjectCount = SPITObject::getSPITObjectRemoteCount(); - for (int intObject = 0; intObject < intSPITObjectCount; intObject++) { - ptrSPITObject = SPITObject::getSPITObjectRemote(intObject); - if (ptrSPITObject == NULL) continue; - if (ptrSPITObject->getSPITTypeID() == p_SPITType.getID()) { - //call ecentSPITObjectRemote - eventSPITObjectRemote(false, p_SPITType, *ptrSPITObject); - } - } - ESP_LOGD(TAG, "eventSPITTypeRemote CHANGED"); - } - ESP_LOGD(TAG, "ID: %s GroupName: %s Name: %s confirmed: %d", - p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data(), p_SPITType.getConfirmed()); - //this is a remote SPITType, if you want you can list this for later remote use. +void MyApp::onSpitTypeRemote(bool p_New, const SPITType &p_SPITType) { + if (p_New) { + ESP_LOGD(TAG, "eventSPITTypeRemote NEW"); + } else { + // we had to inform all Remote SPITObjects using the p_SPITType + // perhaps the SPITObject uses information from the SPITType + SPITObject *ptrSPITObject; + int intSPITObjectCount; + intSPITObjectCount = SPITObject::getSPITObjectRemoteCount(); + for (int intObject = 0; intObject < intSPITObjectCount; intObject++) { + ptrSPITObject = SPITObject::getSPITObjectRemote(intObject); + if (ptrSPITObject == NULL) + continue; + if (ptrSPITObject->getSPITTypeID() == p_SPITType.getID()) { + // call ecentSPITObjectRemote + onSpitObjectRemote(false, p_SPITType, *ptrSPITObject); + } + } + ESP_LOGD(TAG, "eventSPITTypeRemote CHANGED"); + } + ESP_LOGD(TAG, "ID: %s GroupName: %s Name: %s confirmed: %d", + p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data(), p_SPITType.getConfirmed()); + // this is a remote SPITType, if you want you can list this for later remote use. } /** - * Called when the server has removed a SPITType.
- * After this function has been exited the SPITType is emeoved from the SPITType-List and the pointer is deleted.
+ * Called when the server has removed a SPITType. + * After this function has been exited the SPITType is emeoved from the SPITType-List and the pointer is deleted. * So use the pointer immediately or use the copyconstructor to make a copy for extended use. * You have to release the copy yourself later (delete ptr...) - * @param p_SPITType a reference to a copy of the SPITType instance.
- * The reference is deleted after this function call!! */ -void MyApp::eventSPITTypeRemoved(const SPITType& p_SPITType) { - ESP_LOGD(TAG, "eventSPITType Removed"); - ESP_LOGD(TAG, " ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data()); +void MyApp::onSpitTypeRemoved(const SPITType &p_SPITType) { + ESP_LOGD(TAG, "eventSPITType Removed"); + ESP_LOGD(TAG, " ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data()); - //Check your actions - //take the removal of the SPITType over in your code - - //CAUTION: Deleted SPIT types can be added later again (perhaps per UNDO on the SPITServer) - //-> don't remove your assigned action immediately - keep it to reassign it later + // Check your actions + // take the removal of the SPITType over in your code + + // CAUTION: Deleted SPIT types can be added later again (perhaps per UNDO on the SPITServer) + //-> don't remove your assigned action immediately - keep it to reassign it later } /** - * Called when the server has removed a Remote SPITType.
+ * Called when the server has removed a Remote SPITType. * Remote SPITType are used in Remote SPITObjects. A Remote SPITObject is used to remote control the SPITServer. - * After this function has been exited the SPITType is emeoved from the Remote SPITType-List and the pointer is deleted.
+ * After this function has been exited the SPITType is emeoved from the Remote SPITType-List and the pointer is deleted. * So use the pointer immediately or use the copyconstructor to make a copy for extended use. * You have to release the copy yourself later (delete ptr...) - * @param p_SPITType a reference to a copy of the SPITType instance.
- * The reference is deleted after this function call!! + * @param p_SPITType a reference to a copy of the SPITType instance. */ -void MyApp::eventSPITTypeRemoteRemoved(const SPITType& p_SPITType) { - ESP_LOGD(TAG, "eventSPITTypeRemote Removed"); - ESP_LOGD(TAG, " ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data()); +void MyApp::onSpitTypeRemoteRemoved(const SPITType &p_SPITType) { + ESP_LOGD(TAG, "eventSPITTypeRemote Removed"); + ESP_LOGD(TAG, " ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data()); - //This is a remote SPITType - //If you have listet this prior you should remove it from the list + // This is a remote SPITType + // If you have listet this prior you should remove it from the list } - - - -//---------------------------------------------------- -//--------- SPITObject events ---------- -// Every SPITObjects has one one SPITType assigned. -// Whenever an action is to be triggered, play events are sent with the corresponding SPITObject. -// All SPITObjects are listet in a static unordered_map in the SPITObject class. -// All Remote SPITObjects are listet in a seperate unordered_map in the SPITObject class; -// You can use the SPITObject::get... functions to deal with them. -// The SPITObject class has a static recursive_mutex, you get a pointer of the mutex by: SPITObject::getMutex(); -// To be thread save you should cover your code with a lock sequence: -/* - { //start of the lock sequence - unique_lock o_LockObject(*SPITObject::getMutex()); - //got the lock - - //fetch SPITObjects and deal with, but don't waste time while you holding the lock - //Excample - SPITObject* ptrSPITObject; - for (int i = 0; i < SPITObject::getSPITObjectCount(); i++) { - ptrSPITObject = SPITObject::getSPITObject(i); - if (ptrSPITObject == NULL) break; - //Do something with ptrSPITObject - //bew aware after you leave the lock sequence the ptrSPITObject is no longer save!! - } - } //end of the lock sequence - - //For Remote Objects you can use the getSPITObjectRemote... functions -*/ - - /** - * Called when the server has created, loaded or changed a SPITObject.
- * May also occur when the server confirms a SPITObject created by the client, what the client should never do!!.
- * @param p_New true = server created a new SPITObject
- * false = server changed a existing SPITObject
- * @param p_SPITType a reference to a copy of the associated SPITType instance.
- * The reference is deleted after this function call!! - * @param p_SPITObject a reference to a copy of the SPITObject instance.
- * The reference is deleted after this function call!! + * Called when the server has created, loaded or changed a SPITObject. + * May also occur when the server confirms a SPITObject created by the client, what the client should never do!!. + * @param p_New true = server created a new SPITObject + * false = server changed a existing SPITObject + * @param p_SPITType a reference to a copy of the associated SPITType instance. + * @param p_SPITObject a reference to a copy of the SPITObject instance. */ -void MyApp::eventSPITObject(bool p_New, const SPITType& p_SPITType, const SPITObject& p_SPITObject) { - if (p_New) { - ESP_LOGD(TAG, "eventSPITObject NEW"); - } - else { - ESP_LOGD(TAG, "eventSPITObject CHANGED"); - } - ESP_LOGD(TAG, " ID: %s Name: %s -> SPITType: %s", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data()); - - //check your actions - //Whenever you provide an action for this SPITObject take this over in your code. - //call m_SPIT_Client->setActionSPITObject(p_SPITObject.getID(), true); - - //for our little excample as described in loadClientProject: - //We have only actions for SPITTypes - means every SPITObject with the associated "Actionx"-SPITTypes will trigger the action when it is played - //-> no need to do something here, because setActionSPITType has been set prior and the SPITObject will automatically inherits this - //SPITObjects with other SPITTypes asscciated will trigger no actions - +void MyApp::onSpitObject(bool p_New, const SPITType &p_SPITType, const SPITObject &p_SPITObject) { + if (p_New) { + ESP_LOGI(TAG, "eventSPITObject NEW"); + } else { + ESP_LOGD(TAG, "eventSPITObject CHANGED"); + } + ESP_LOGI(TAG, " ID: %s Name: %s -> SPITType: %s", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data()); + + // check your actions + // Whenever you provide an action for this SPITObject take this over in your code. + // call _SpitClient.setActionSPITObject(p_SPITObject.getID(), true); + + // for our little excample as described in loadClientProject: + // We have only actions for SPITTypes - means every SPITObject with the associated "Actionx"-SPITTypes will trigger the action when it is played + //-> no need to do something here, because setActionSPITType has been set prior and the SPITObject will automatically inherits this + // SPITObjects with other SPITTypes asscciated will trigger no actions } /** - * Called when the server has created or changed a Remote SPITObject.
+ * Called when the server has created or changed a Remote SPITObject. * A Remote SPITObject is used to remote control the SPITServer. - * @param p_New true = server created a new remote SPITObject
- * false = server changed a existing remote SPITObject
- * @param p_SPITType a reference to a copy of the associated SPITType instance.
- * The reference is deleted after this function call!! - * @param p_SPITObject a reference to a copy of the SPITObject instance.
- * The reference is deleted after this function call!! + * @param p_New true = server created a new remote SPITObject + * false = server changed a existing remote SPITObject + * @param p_SPITType a reference to a copy of the associated SPITType instance. + * @param p_SPITObject a reference to a copy of the SPITObject instance. */ -void MyApp::eventSPITObjectRemote(bool p_New, const SPITType& p_SPITType, const SPITObject& p_SPITObject) { - if (p_New) { - ESP_LOGD(TAG, "eventSPITObjectRemote NEW"); - } - else { - ESP_LOGD(TAG, "eventSPITObjectRemote CHANGED"); - } - ESP_LOGD(TAG, " ID: %s Name: %s -> SPITType: %s", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data()); - - //This is a remote SPITObject which can be used to remote control the server. - //If you want you can list this for later use +void MyApp::onSpitObjectRemote(bool p_New, const SPITType &p_SPITType, const SPITObject &p_SPITObject) { + if (p_New) { + ESP_LOGI(TAG, "eventSPITObjectRemote NEW"); + } else { + ESP_LOGD(TAG, "eventSPITObjectRemote CHANGED"); + } + ESP_LOGI(TAG, " ID: %s Name: %s -> SPITType: %s", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data()); + + // This is a remote SPITObject which can be used to remote control the server. + // If you want you can list this for later use } /** - * Called when the server has removed a SPITObject.
- * After this function has been exited the SPITObject is emeoved from the SPITObject-List and the pointer is deleted.
+ * Called when the server has removed a SPITObject. + * After this function has been exited the SPITObject is emeoved from the SPITObject-List and the pointer is deleted. * So use the pointer immediately or use the copyconstructor to make a copy for extended use. * You have to release the copy yourself later (delete ptr...) - * @param p_SPITType a reference to a copy of the associated SPITType instance.
- * The reference is deleted after this function call!! - * @param p_SPITObject a reference to a copy of the SPITObject instance.
- * The reference is deleted after this function call!! + * @param p_SPITType a reference to a copy of the associated SPITType instance. + * @param p_SPITObject a reference to a copy of the SPITObject instance. */ -void MyApp::eventSPITObjectRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject) { - ESP_LOGD(TAG, "eventSPITObject Removed"); - ESP_LOGD(TAG, " ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data()); +void MyApp::onSpitObjectRemoved(const SPITType &p_SPITType, const SPITObject &p_SPITObject) { + ESP_LOGD(TAG, "eventSPITObject Removed"); + ESP_LOGD(TAG, " ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data()); - //Check your actions - //take the removal of the SPITObject over in your code - - //CAUTION: Deleted SPITObjects can be added later again (perhaps per UNDO on the SPITServer) - //-> don't remove your assigned action immediately - keep it to reassign it later + // Check your actions + // take the removal of the SPITObject over in your code + + // CAUTION: Deleted SPITObjects can be added later again (perhaps per UNDO on the SPITServer) + //-> don't remove your assigned action immediately - keep it to reassign it later } /** - * Called when the server has removed a Remote SPITObject.
+ * Called when the server has removed a Remote SPITObject. * A Remote SPITObject is used to remote control the SPITServer. - * After this function has been exited the SPITObject is emeoved from the SPITObject-List and the pointer is deleted.
+ * After this function has been exited the SPITObject is emeoved from the SPITObject-List and the pointer is deleted. * So use the pointer immediately or use the copyconstructor to make a copy for extended use. * You have to release the copy yourself later (delete ptr...) - * @param p_SPITType a reference to a copy of the associated SPITType instance.
- * The reference is deleted after this function call!! - * @param p_SPITObject a reference to a copy of the SPITObject instance.
- * The reference is deleted after this function call!! + * @param p_SPITType a reference to a copy of the associated SPITType instance. + * @param p_SPITObject a reference to a copy of the SPITObject instance. */ -void MyApp::eventSPITObjectRemoteRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject) { - ESP_LOGD(TAG, "eventSPITObjectRemote Removed"); - ESP_LOGD(TAG, " ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data()); +void MyApp::onSpitObjectRemoteRemoved(const SPITType &p_SPITType, const SPITObject &p_SPITObject) { + ESP_LOGD(TAG, "eventSPITObjectRemote Removed"); + ESP_LOGD(TAG, " ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data()); - //This is a remote SPITObject - //If you have listet this prior you should remove it from the list + // This is a remote SPITObject + // If you have listet this prior you should remove it from the list } - - - //-------------------------------------------------------------- //---------------- Playing SPITObjects ---------------- // Following is called when the SPITServer play SPITObjects. @@ -567,87 +305,80 @@ void MyApp::eventSPITObjectRemoteRemoved(const SPITType& p_SPITType, const SPITO // e.g. liveSHOWsoftware has the timeline and jingles which plays objects, where the timeline the main player is. // SPIT distinguishes between the different players. All eventPlay... functions contain the information which player plays the SPIT object. -void MyApp::eventPlay(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_PlayerIsRunning, long long p_TimeFrames) { - ESP_LOGD(TAG, "eventPlay Player: %s Runs: %d Time: %lld", p_PlayerName.data(), p_PlayerIsRunning, p_TimeFrames); - - switch(p_PlayerType) { - case SPIT_Client::PLAYERTYPE_MAIN: - //p_FrameTimes contains the position inside the server's project, we can use it like a timecode - int intMilliseconds; - intMilliseconds= (int)(((double)p_TimeFrames / (double)m_ServerFramesPerSecond) * 1000); - break; - case SPIT_Client::PLAYERTYPE_CONTINOUS: - //The olayer is playing only single Object sequences sometime during the project - break; - case SPIT_Client::PLAYERTYPE_DISCRETE: - //Only discrete values where submitted, e.g the fader position of remote faders. - break; - } +void MyApp::onPlay(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_PlayerIsRunning, long long p_TimeFrames) { + ESP_LOGD(TAG, "eventPlay Player: %s Runs: %d Time: %lld", p_PlayerName.data(), p_PlayerIsRunning, p_TimeFrames); + + switch (p_PlayerType) { + case SPIT_Client::PLAYERTYPE_MAIN: + // p_FrameTimes contains the position inside the server's project, we can use it like a timecode + int intMilliseconds; + intMilliseconds = (int)(((double)p_TimeFrames / (double)m_ServerFramesPerSecond) * 1000); + break; + case SPIT_Client::PLAYERTYPE_CONTINOUS: + // The olayer is playing only single Object sequences sometime during the project + break; + case SPIT_Client::PLAYERTYPE_DISCRETE: + // Only discrete values where submitted, e.g the fader position of remote faders. + break; + } } /** - * Called when the SPITServer plays a SPITObject. For every played SPITObject one eventPlayObject is called.
- * You can decide here which action should be done or not.
- * + * Called when the SPITServer plays a SPITObject. For every played SPITObject one eventPlayObject is called. + * You can decide here which action should be done or not. + * * @param p_Started true = The SPITObject is newly played (e.g. in liveSHOWsoftware the cursor enters the SPITObject) * @param p_Ended Das true = Playback of SPITObject finished (e.g. in liveSHOWsoftware the cursor has exited the SPIT object) * @param p_SPITType the associated SPITType of p_SPITObject * @param p_SPITObject the actual played or stopped SPITObject - * @param p_PlayObject contains information about the play status:
- * frame where the cursor is inside the SPITObject
- * whether the player is running or not
- * the actual value of the SPITObject (in liveSHOWsoftware objects ma faded in or out or the main value is decreased, ..
+ * @param p_PlayObject contains information about the play status: + * frame where the cursor is inside the SPITObject + * whether the player is running or not + * the actual value of the SPITObject (in liveSHOWsoftware objects ma faded in or out or the main value is decreased, .. */ -void MyApp::eventPlayObject(string p_PlayerID, bool p_Started, bool p_Ended, const SPITType& p_SPITType, const SPITObject& p_SPITObject, const SPITPlayer::PlayObject& p_PlayObject) { - // p_PlayObject.getValue() contain the value in ppm (we can calculate value between 0.0 and 1.0) - // p_SPITObject.getValueFactor() or redundand p_PlayObject.getValueFactor() - // contains the factor the above value should be multiplicated to get the end value. - double doubleValue = ((double)p_PlayObject.getValue()/1000000)*((double)p_PlayObject.getValueFactor()/1000000); - - //Other factors besides value may be of interest - //p_PlayObject.getFrameInside() contains the play position inside the SPITObject - //p_SPITObject.getFrameLength() contains the length of the SPITObject - //-> we can calculate the position 0.0 to 1.0 where the Object is played - - //in liveSHOWsoftware the player may play two different position in the SPITObject to mix them down, e.g. a SceneBridge is played - //We can get the second (pre played) position: p_PlayObject.getFrameInsidePrePosition(); - - ESP_LOGD(TAG, "eventPlayObject Player: %s is running: %d Object Started: %d Stopped: %d", p_PlayObject.getPlayerName().data(), p_PlayObject.getPlayerIsRunning(), p_Started, p_Ended); - ESP_LOGD(TAG, " SPITType: %s SPITObject: %s Position: %lld Value: %f\n", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_PlayObject.getFrameInside(), doubleValue); +void MyApp::onPlayObject(string p_PlayerID, bool p_Started, bool p_Ended, const SPITType &p_SPITType, const SPITObject &p_SPITObject, const SPITPlayer::PlayObject &p_PlayObject) { + // p_PlayObject.getValue() contain the value in ppm (we can calculate value between 0.0 and 1.0) + // p_SPITObject.getValueFactor() or redundand p_PlayObject.getValueFactor() + // contains the factor the above value should be multiplicated to get the end value. + double doubleValue = ((double)p_PlayObject.getValue() / 1000000) * ((double)p_PlayObject.getValueFactor() / 1000000); - //check for your actions to do - - //In our little excample decribed in loadClientProject: - //We want to react to SPIT types, no matter which SPIT object is currently being played. - //-> check not the SPITObject itself but the associated SPITType - bool boolPLayerIsRunning = p_PlayObject.getPlayerIsRunning(); - if (p_SPITType.getID() == "MySPITAPP_Action1ID") { //do Action 1 - //we can get some information about the play status - if (p_Started == true) { - ESP_LOGD(TAG, "MyApp AKTION 1 started Value: %f and running: %d", doubleValue, boolPLayerIsRunning); - } - else if (p_Ended == true) { - ESP_LOGD(TAG, "MyApp AKTION 1 ended"); //p_PlayObject.getFrameInside() is -1 - } - else { - ESP_LOGD(TAG, "MyApp AKTION 1 is played Value: %f and running: %d", doubleValue, boolPLayerIsRunning); - } - } - else if (p_SPITType.getID() == "MySPITAPP_Action2ID") { //do Action 2 - if (p_Started == true) { - ESP_LOGD(TAG, "AKTION 2 started Value: %f and running: %d", doubleValue, boolPLayerIsRunning); - } - else if (p_Ended == true) { - ESP_LOGD(TAG, "AKTION 2 ended"); //p_PlayObject.getFrameInside() is -1 - } - else { - ESP_LOGD(TAG, "AKTION 2 is played Value: %f and running: %d", doubleValue, boolPLayerIsRunning); - } - } + // Other factors besides value may be of interest + // p_PlayObject.getFrameInside() contains the play position inside the SPITObject + // p_SPITObject.getFrameLength() contains the length of the SPITObject + //-> we can calculate the position 0.0 to 1.0 where the Object is played + + // in liveSHOWsoftware the player may play two different position in the SPITObject to mix them down, e.g. a SceneBridge is played + // We can get the second (pre played) position: p_PlayObject.getFrameInsidePrePosition(); + + ESP_LOGD(TAG, "eventPlayObject Player: %s is running: %d Object Started: %d Stopped: %d", p_PlayObject.getPlayerName().data(), p_PlayObject.getPlayerIsRunning(), p_Started, p_Ended); + ESP_LOGD(TAG, " SPITType: %s SPITObject: %s Position: %lld Value: %f\n", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_PlayObject.getFrameInside(), doubleValue); + + // check for your actions to do + + // In our little excample decribed in loadClientProject: + // We want to react to SPIT types, no matter which SPIT object is currently being played. + //-> check not the SPITObject itself but the associated SPITType + bool boolPLayerIsRunning = p_PlayObject.getPlayerIsRunning(); + if (p_SPITType.getID() == "MySPITAPP_Action1ID") { // do Action 1 + // we can get some information about the play status + if (p_Started == true) { + ESP_LOGI(TAG, "MyApp AKTION 1 started Value: %f and running: %d", doubleValue, boolPLayerIsRunning); + } else if (p_Ended == true) { + ESP_LOGI(TAG, "MyApp AKTION 1 ended"); // p_PlayObject.getFrameInside() is -1 + } else { + ESP_LOGD(TAG, "MyApp AKTION 1 is played Value: %f and running: %d", doubleValue, boolPLayerIsRunning); + } + } else if (p_SPITType.getID() == "MySPITAPP_Action2ID") { // do Action 2 + if (p_Started == true) { + ESP_LOGI(TAG, "AKTION 2 started Value: %f and running: %d", doubleValue, boolPLayerIsRunning); + } else if (p_Ended == true) { + ESP_LOGI(TAG, "AKTION 2 ended"); // p_PlayObject.getFrameInside() is -1 + } else { + ESP_LOGD(TAG, "AKTION 2 is played Value: %f and running: %d", doubleValue, boolPLayerIsRunning); + } + } } - - //-------------------------------------------------------------- //---------------- Remote Control SPITServer ---------------- // The SPITServer has sent all possibilities to control it remotely - remote SPITObjects - see eventSPITObjectRemote @@ -655,89 +386,36 @@ void MyApp::eventPlayObject(string p_PlayerID, bool p_Started, bool p_Ended, con // When the server changes one of these value objects, it sends an eventPlayRemoteObjectStatus. /** - * Called when a remote SpitObject which value function is changed by the server.
- * This allows the Client to adjust its display for the remote command.
+ * Called when a remote SpitObject which value function is changed by the server. + * This allows the Client to adjust its display for the remote command. * @param p_SPITType the assigned remote SPITType of p_SPITObject * @param p_SPITObject the remote SPITObject which is changed * @param p_FrameInsideObject can be discarded * @param p_Value the new value */ -void MyApp::eventPlayRemoteObjectStatus(const SPITType& p_SPITType, const SPITObject& p_SPITObject, long long p_FrameInsideObject, int p_Value) { - ESP_LOGD(TAG, "eventPlayRemoteObjectStatus RemoteSPITType: %s RemoteSPITObject: %s Position: %lld Value: %d", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_FrameInsideObject, p_Value); +void MyApp::onPlayRemoteObjectStatus(const SPITType &p_SPITType, const SPITObject &p_SPITObject, long long p_FrameInsideObject, int p_Value) { + ESP_LOGD(TAG, "eventPlayRemoteObjectStatus RemoteSPITType: %s RemoteSPITObject: %s Position: %lld Value: %d", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_FrameInsideObject, p_Value); } /** - * Send a remote control command to the SPITServer.
+ * 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 p_Valueppm the value in ppm
- * in case a) the value is ignored
+ * @param p_Valueppm the value in ppm + * in case a) the value is ignored * in case b) the value is used - * @param p_ValueFlag indicates how the server should use p_Valueppm:
- * VALUEFLAG_DIRECT (0x00) The server will overwrite his existing value with p_Value
+ * @param p_ValueFlag indicates how the server should use p_Valueppm: + * VALUEFLAG_DIRECT (0x00) The server will overwrite his existing value with p_Value * VALUEFLAG_INCREASE (0x01) The server increases his existing value by p_Valueppm * VALUEFLAG_DECREASE (0x01) The server decreases his existing value by p_Valueppm */ void MyApp::sendRemoteObject(string p_SPITObjectID, int p_Valueppm, char p_ValueFlag) { - if (m_SPIT_Client != NULL) { - m_SPIT_Client->sendRemoteObject(p_SPITObjectID, p_Valueppm, p_ValueFlag); - } + _SpitClient.sendRemoteObject(p_SPITObjectID, p_Valueppm, p_ValueFlag); } -//liveSHOWsoftware excample for sending remote control -//the liveSHOW software has the remote control commands (SPITObjects) among other things: -// + next secenebridge with id "nextSceneBridge" -// + main mixer sound width id = "mainmixerSound_Volume00" -//You can detect this in eventSPITObjectRemote(...) void MyApp::testLiveShowRemote() { - //We jump to the next Scenebridge - no Value is needed - m_SPIT_Client->sendRemoteObject("nextSceneBridge"); - //we set the main sound volume to 0.1, SPIT uses ppm -> 0.1 = 100000 - m_SPIT_Client->sendRemoteObject("mainmixerSound_Volume00", 100000, SPIT_Client::VALUEFLAG_DIRECT); - //we increase the main sound volume by 0.1, SPIT uses ppm -> 0.1 = 100000 - m_SPIT_Client->sendRemoteObject("mainmixerSound_Volume00", 100000, SPIT_Client::VALUEFLAG_INCREASE); -} - - - -//------------------------------------------------- -//---------- Options for the client user ---------- -//Normally this should not be used, because because the server is master of things -//In some situations, however, it may be helpful - -/** - * Removes the SPITType with id == p_SPITTypeID - * @param p_SPITTypeID the id of the SPITType - * @return - */ -int MyApp::removeSPITType(string p_SPITTypeID) { - if (m_SPIT_Client == NULL) return -1; - return m_SPIT_Client->removeSPITType(p_SPITTypeID); -} -/** - * Removes the SPITObject with id == p_SPITObjectID - * @param p_SPITObjectID the id of the SPITObject - * @return - */ -int MyApp::removeSPITObject(string p_SPITObjectID) { - if (m_SPIT_Client == NULL) return -1; - return m_SPIT_Client->removeSPITObject(p_SPITObjectID); -} -/** - * Changes the SPITType - * @param p_SPITType a pointer to a SPITType instance whith changed members - * @return - */ -int MyApp::changeSPITType(SPITType* p_SPITType) { - return m_SPIT_Client->changeSPITType(p_SPITType); -} -/** - * Changes the SPITObject - * @param p_SPITObject a pointer to a SPITObject with changed members - * @return - */ -int MyApp::changeSPITObject(SPITObject* p_SPITObject) { - return m_SPIT_Client->changeSPITObject(p_SPITObject); + // We jump to the next Scenebridge - no Value is needed + _SpitClient.sendRemoteObject("playControlStart"); } diff --git a/components/spit/src/SAD_Client.cpp b/components/spit/src/SAD_Client.cpp deleted file mode 100644 index 5fc1929..0000000 --- a/components/spit/src/SAD_Client.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * SAD_Client is used for ServerAutoDetection (SAD). - * - * File: ServerAutoDetetc_Client.cpp - * Author: Hagi - * - * Created on 16. April 2019, 08:57 - */ - -#include "SAD_Client.h" - -//----- initialze static members ----- -bool SAD_Client::s_StopSAD = true; -fos::Mutex SAD_Client::s_MutexSAD; -fos::Semaphore SAD_Client::s_ConditionStopSAD; -fos::Task* SAD_Client::s_ThreadSend = NULL; -fos::Task* SAD_Client::s_ThreadReceiveIP4 = NULL; - -SAD_ClientInterface* SAD_Client::s_SADClientInterface = NULL; - -fos::Mutex SAD_Client::s_MutexSocket; -SPITSocket* SAD_Client::s_SPITSocket = NULL; - - - -void SAD_Client::startAutoDetectServer(SAD_ClientInterface* p_SADClientInterface, SPITSocket* p_SpitSocket) { - if (p_SADClientInterface == NULL) return; - if (p_SpitSocket == NULL) return; - - s_SADClientInterface = p_SADClientInterface; - { - fos::MutexGuard o_UniqueLock(s_MutexSAD); - if (s_StopSAD == false) return; - s_StopSAD = false; - SAD_DetectedServer::clearDetectedServers(); - } - - s_SPITSocket = p_SpitSocket; - - s_ThreadSend = new fos::Task(SAD_Client::sendAutoDetectServer, "sendDetect"); - s_ThreadReceiveIP4 = new fos::Task(SAD_Client::receiveAutoDetectServer_IP4, "getDetect"); -} - -void SAD_Client::stopAutoDetectServer(SAD_ClientInterface* p_SADClientInterface) { - if (s_SADClientInterface != p_SADClientInterface) return; - - { - fos::MutexGuard o_UniqueLock(s_MutexSAD); - if (s_StopSAD == true) return; - s_StopSAD = true; - } - s_ConditionStopSAD.give(); - if (s_ThreadSend != NULL) { - delete s_ThreadSend; - s_ThreadSend = NULL; - } - - //wait for receiving threads - if (s_ThreadReceiveIP4 != NULL) { - delete s_ThreadReceiveIP4; - s_ThreadReceiveIP4 = NULL; - } - { - fos::MutexGuard o_LockSocket(s_MutexSocket); - if (s_SPITSocket != NULL) { - delete s_SPITSocket; - s_SPITSocket = NULL; - } - } - { - fos::MutexGuard o_UniqueLock(s_MutexSAD); - SAD_DetectedServer::clearDetectedServers(); - } -} - -void SAD_Client::sendAutoDetectServer() { - SPITSocket::IPAddress* o_IPAddress; - string stringBroadcastIP4; - string stringDatagram; - int intDatagramLength; - bool boolDone; - - stringDatagram = SERVERAUTODETECT_PRECODE; - stringDatagram.append(SERVERAUTODETECT_SEPERATOR); - stringDatagram.append(SERVERAUTODETECT_TASKID); - intDatagramLength = stringDatagram.length(); - - while(s_StopSAD == false) { - - //---- IP4 --- - cycleStart(); - { - fos::MutexGuard o_LockSocket(s_MutexSocket); - if (s_SPITSocket == NULL) { - return; - } - s_SPITSocket->getAdaptersInfo(); - - for (int i = 0; i < SPITSocket::getIPAddressCount(); i++) { - o_IPAddress = SPITSocket::getIPAddress(i); - if (o_IPAddress == NULL) break; - stringBroadcastIP4 = s_SPITSocket->getBroadcastIP4(o_IPAddress); - if (s_SPITSocket->sendMessageTo(SPITSocket::FAMILY_IP4, stringBroadcastIP4, SERVERAUTODETECT_PORT, stringDatagram.data(), intDatagramLength) < 0) { - } - else { - } - } - } - - { - if (s_StopSAD == true) { - return; - } - //wait for 3000 milliseconds or - //s_StopAutoDetectServer == true see stopAutoDetectServer - fos::MutexGuard o_LockWait(s_MutexSAD); - boolDone = s_ConditionStopSAD.take(3000); - if (not boolDone) // timeout occurred - { - s_StopSAD = true; - } - if (s_StopSAD == true) { - return; - } - } - cycleEnd(); - } - int intTest = 0; -} - -void SAD_Client::receiveAutoDetectServer_IP4() { - char buffer[512+1]; - int intReceivedByteCount; - string stringMessage; - string stringServerIP; - - int intIndex = 0; - int intPos = 0; - int intOldPos = 0; - string stringPart; - string stringParts[9]; - - //sendAutoDetectServer will bind the socket to a port - //wait a while to be sendAutoDetectServer first - fos::Task::delayMs(500); - - while (s_StopSAD == false) { - { - fos::MutexGuard o_LockIP4(s_MutexSocket); - if (s_SPITSocket == NULL) { - return; - } - } - intReceivedByteCount = s_SPITSocket->receiveMessage(SPITSocket::FAMILY_IP4, buffer, 512, &stringServerIP); - if (intReceivedByteCount <= 0) { - if (s_StopSAD == false) { - //To reduce the processor load if a socket error occurs, we let the thread sleep a bit. - fos::Task::delayMs(100); - } - continue; - } - if (s_StopSAD == true) { - return; - } - //add null chararcter - if (intReceivedByteCount < 512) { - buffer[intReceivedByteCount] = '\0'; - } - else { - buffer[512] = '\0'; - } - stringMessage = buffer; - //Check if precode is ok - if (stringMessage.find(SERVERAUTODETECT_PRECODE.data(),0) != 0) { - return; - } - intIndex = 0; - intPos = 0; - intOldPos = 0; - while(intIndex < 8) { - intPos = stringMessage.find(SERVERAUTODETECT_SEPERATOR.data(),intOldPos); - if (intPos == string::npos) { - stringPart = ""; - } - else { - stringPart = stringMessage.substr(intOldPos, intPos-intOldPos); - intOldPos = intPos + SERVERAUTODETECT_SEPERATOR.length(); - } - stringParts[intIndex] = stringPart; - intIndex++; - } - stringParts[8] = stringServerIP; - SAD_DetectedServer::addDetectedServer(true, stringParts[SAD_DetectedServer::PARAMINDEX_ID], stringParts); - } - int inTest = 0; -} - -void SAD_Client::cycleStart() { - { - fos::MutexGuard o_UniqueLock(s_MutexSAD); - if (s_StopSAD == true) return; - } -// printf("SAD CYCLE START\n"); - SAD_DetectedServer::cycleStart(); -} -void SAD_Client::cycleEnd() { - { - fos::MutexGuard o_UniqueLock(s_MutexSAD); - if (s_StopSAD == true) return; - } - SAD_DetectedServer::cycleEnd(s_SADClientInterface); -// printf("SAD CYCLE END\n"); -} diff --git a/components/spit/src/SAD_DetectedServer.cpp b/components/spit/src/SAD_DetectedServer.cpp index 5179e16..74d387d 100644 --- a/components/spit/src/SAD_DetectedServer.cpp +++ b/components/spit/src/SAD_DetectedServer.cpp @@ -12,9 +12,11 @@ * Created on 4. Mai 2019, 13:51 */ -#include "SAD_DetectedServer.h" +#include "SAD_DetectedServer.hpp" +#include "esp_log.h" + +static const char * TAG = "SpitSrv"; -fos::Mutex SAD_DetectedServer::s_MutexDetectedServer; unordered_map SAD_DetectedServer::s_DetectedServers; SAD_DetectedServer::~SAD_DetectedServer() { @@ -27,47 +29,19 @@ SAD_DetectedServer::SAD_DetectedServer() { m_ClientIP = ""; m_Port = ""; m_Additions = ""; - m_IPIsLoopback = false; m_IPIsIP4 = false; - m_IPIsIP6 = false; -} - -void SAD_DetectedServer::setID(string p_ID) { - m_ID = p_ID; -} -void SAD_DetectedServer::setName(string p_Name) { - m_Name = p_Name; -} -void SAD_DetectedServer::setComputerName(string p_ComputerName) { - m_ComputerName = p_ComputerName; -} -void SAD_DetectedServer::setIP(string p_IP) { - m_IP = p_IP; -} -void SAD_DetectedServer::setClientIP(string p_IP) { - m_ClientIP = p_IP; -} -void SAD_DetectedServer::setPort(string p_Port) { - m_Port = p_Port; -} -void SAD_DetectedServer::setAdditions(string p_Additions) { - m_Additions = p_Additions; } void SAD_DetectedServer::cycleStart() { - { - fos::MutexGuard o_lock(s_MutexDetectedServer); - for (auto i = s_DetectedServers.begin(); i != s_DetectedServers.end(); i++) { - i->second->startCycleSAD(); - } + for (auto i = s_DetectedServers.begin(); i != s_DetectedServers.end(); i++) { + i->second->startCycleSAD(); } } -void SAD_DetectedServer::cycleEnd(SAD_ClientInterface* p_SADClientInterface) { +void SAD_DetectedServer::cycleEnd(I_SAD_Client& sADClientInterface) { list o_LostServers; list o_NewServers; SAD_DetectedServer* ptrDetectedServer; { - fos::MutexGuard o_lock(s_MutexDetectedServer); for (auto i = s_DetectedServers.begin(); i != s_DetectedServers.end(); i++) { ptrDetectedServer = i->second; if (ptrDetectedServer->getFoundAgain() == false) { @@ -80,7 +54,6 @@ void SAD_DetectedServer::cycleEnd(SAD_ClientInterface* p_SADClientInterface) { ptrDetectedServer->endCycleSAD(); } else if (ptrDetectedServer->getChanged()) { - // p_SADClientInterface-> ptrDetectedServer->endCycleSAD(); } else { @@ -91,12 +64,10 @@ void SAD_DetectedServer::cycleEnd(SAD_ClientInterface* p_SADClientInterface) { //Notify client interface about lost servers for (auto i = o_LostServers.begin(); i != o_LostServers.end(); i++) { ptrDetectedServer = *i; - if (p_SADClientInterface != NULL) { - p_SADClientInterface->eventServerLost(ptrDetectedServer->getID(), ptrDetectedServer->getName(), + sADClientInterface.eventServerLost(ptrDetectedServer->getID(), ptrDetectedServer->getName(), ptrDetectedServer->getComputerName(), ptrDetectedServer->getIP(), ptrDetectedServer->getPort(), ptrDetectedServer->getAdditions(), ptrDetectedServer->getClientIP(), - ptrDetectedServer->getIpIsLoopback(), ptrDetectedServer->getIpIsIP4(), ptrDetectedServer->getIpIsIP6()); - } + ptrDetectedServer->getIpIsIP4()); } //Remove lost servers for (auto i = o_LostServers.begin(); i != o_LostServers.end(); i++) { @@ -107,12 +78,10 @@ void SAD_DetectedServer::cycleEnd(SAD_ClientInterface* p_SADClientInterface) { for (auto i = o_NewServers.begin(); i != o_NewServers.end(); i++) { ptrDetectedServer = *i; - if (p_SADClientInterface != NULL) { - p_SADClientInterface->eventServerDetected(ptrDetectedServer->getID(), ptrDetectedServer->getName(), + sADClientInterface.eventServerDetected(ptrDetectedServer->getID(), ptrDetectedServer->getName(), ptrDetectedServer->getComputerName(), ptrDetectedServer->getIP(), ptrDetectedServer->getPort(), ptrDetectedServer->getAdditions(), ptrDetectedServer->getClientIP(), - ptrDetectedServer->getIpIsLoopback(), ptrDetectedServer->getIpIsIP4(), ptrDetectedServer->getIpIsIP6()); - } + ptrDetectedServer->getIpIsIP4()); } o_NewServers.clear(); @@ -126,7 +95,6 @@ void SAD_DetectedServer::cycleEnd(SAD_ClientInterface* p_SADClientInterface) { void SAD_DetectedServer::addDetectedServer(bool p_IsIP4, string p_ServerID, string p_ServerParams[]) { SAD_DetectedServer* ptrDetectedServer; { - fos::MutexGuard o_Lock(s_MutexDetectedServer); auto i = s_DetectedServers.find(p_ServerID); if (i != s_DetectedServers.end()) { ptrDetectedServer = i->second; @@ -138,7 +106,6 @@ void SAD_DetectedServer::addDetectedServer(bool p_IsIP4, string p_ServerID, stri } ptrDetectedServer->setFoundAgain(); - if (ptrDetectedServer->getIpIsLoopback() == false) { //second prefer IP4 if (p_IsIP4 == true) { ptrDetectedServer->setIP(p_ServerParams[PARAMINDEX_IP]); @@ -147,10 +114,8 @@ void SAD_DetectedServer::addDetectedServer(bool p_IsIP4, string p_ServerID, stri } else if (ptrDetectedServer->getIpIsIP4() == false){ ptrDetectedServer->setIP(p_ServerParams[PARAMINDEX_IP]); - ptrDetectedServer->setIPIsIP6(true); ptrDetectedServer->setClientIP(p_ServerParams[PARAMINDEX_CLIENTIP]); } - } ptrDetectedServer->setName(p_ServerParams[PARAMINDEX_NAME]); ptrDetectedServer->setComputerName(p_ServerParams[PARAMINDEX_COMPUTERNAME]); ptrDetectedServer->setPort(p_ServerParams[PARAMINDEX_PORT]); @@ -158,7 +123,6 @@ void SAD_DetectedServer::addDetectedServer(bool p_IsIP4, string p_ServerID, stri s_DetectedServers[ptrDetectedServer->getID()] = ptrDetectedServer; } - } /** * Used by SAD_Client to remove a SPITServer - don't use this manually @@ -167,7 +131,6 @@ void SAD_DetectedServer::addDetectedServer(bool p_IsIP4, string p_ServerID, stri void SAD_DetectedServer::removeDetectedServer(SAD_DetectedServer* p_DetectedServer) { SAD_DetectedServer* o_DetectedServer; { - fos::MutexGuard o_Lock(s_MutexDetectedServer); auto i = s_DetectedServers.find(p_DetectedServer->getID()); if (i != s_DetectedServers.end()) { o_DetectedServer = i->second; @@ -183,7 +146,6 @@ void SAD_DetectedServer::removeDetectedServer(SAD_DetectedServer* p_DetectedServ void SAD_DetectedServer::clearDetectedServers() { SAD_DetectedServer* ptrDetectedServer; { - fos::MutexGuard o_Lock(s_MutexDetectedServer); for (auto i = s_DetectedServers.begin(); i != s_DetectedServers.end(); i++) { ptrDetectedServer = i->second; i = s_DetectedServers.erase(i); diff --git a/components/spit/src/SPITObject.cpp b/components/spit/src/SPITObject.cpp index b492a0e..13cbc0d 100644 --- a/components/spit/src/SPITObject.cpp +++ b/components/spit/src/SPITObject.cpp @@ -13,15 +13,13 @@ */ #include "SPITObject.h" -#include "_SPITMACROS.h" +#include "SPITSocket.h" unordered_map SPITObject::s_SPITObjects; unordered_map SPITObject::s_SPITObjectsRemote; - fos::Mutex SPITObject::s_MutexSPITObject; SPITObject* SPITObject::getSPITObject(string p_ID) { { - fos::MutexGuard o_LockObject(s_MutexSPITObject); auto i = s_SPITObjects.find(p_ID); if (i == s_SPITObjects.end()) { return NULL; @@ -37,7 +35,6 @@ */ const SPITObject& SPITObject::getSPITObjectRef(string p_ID) { { - fos::MutexGuard o_LockObject(s_MutexSPITObject); auto i = s_SPITObjects.find(p_ID); if (i == s_SPITObjects.end()) { throw "SPITObject no SPITObject with given id"; @@ -48,7 +45,6 @@ SPITObject* SPITObject::getSPITObjectRemote(string p_ID) { { - fos::MutexGuard o_LockObject(s_MutexSPITObject); auto i = s_SPITObjectsRemote.find(p_ID); if (i == s_SPITObjectsRemote.end()) { return NULL; @@ -64,7 +60,6 @@ */ const SPITObject& SPITObject::getSPITObjectRemoteRef(string p_ID) { { - fos::MutexGuard o_LockObject(s_MutexSPITObject); auto i = s_SPITObjectsRemote.find(p_ID); if (i == s_SPITObjectsRemote.end()) { throw "Remote SPITObject no SPITObject with given id"; @@ -76,7 +71,6 @@ bool SPITObject::addSPITObject(SPITObject* p_ptrSPITObject) { if (p_ptrSPITObject == NULL) return false; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); s_SPITObjects[p_ptrSPITObject->getID()] = p_ptrSPITObject; return true; } @@ -84,7 +78,6 @@ bool SPITObject::addSPITObjectRemote(SPITObject* p_ptrSPITObject) { if (p_ptrSPITObject == NULL) return false; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); s_SPITObjectsRemote[p_ptrSPITObject->getID()] = p_ptrSPITObject; return true; } @@ -92,7 +85,6 @@ bool SPITObject::removeSPITObject(SPITObject* p_ptrSPITObject) { if (p_ptrSPITObject == NULL) return false; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); auto i = s_SPITObjects.find(p_ptrSPITObject->getID()); if (i == s_SPITObjects.end()) { return false; @@ -104,7 +96,6 @@ bool SPITObject::removeSPITObjectRemote(SPITObject* p_ptrSPITObject) { if (p_ptrSPITObject == NULL) return false; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); auto i = s_SPITObjectsRemote.find(p_ptrSPITObject->getID()); if (i == s_SPITObjectsRemote.end()) { return false; @@ -123,7 +114,6 @@ SPITObject* SPITObject::getSPITObject(int p_Index) { SPITObject* ptrSPITObject = NULL; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); if (p_Index >= 0 && p_Index < s_SPITObjects.size()) { unordered_map::iterator i = next(s_SPITObjects.begin(), p_Index); ptrSPITObject = i->second; @@ -143,7 +133,6 @@ const SPITObject& SPITObject::getSPITObjectRef(int p_Index) { SPITObject* ptrSPITObject = NULL; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); if (p_Index >= 0 && p_Index < s_SPITObjects.size()) { unordered_map::iterator i = next(s_SPITObjects.begin(), p_Index); ptrSPITObject = i->second; @@ -157,7 +146,6 @@ SPITObject* SPITObject::getSPITObjectRemote(int p_Index) { SPITObject* ptrSPITObject = NULL; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); if (p_Index >= 0 && p_Index < s_SPITObjectsRemote.size()) { unordered_map::iterator i = next(s_SPITObjectsRemote.begin(), p_Index); ptrSPITObject = i->second; @@ -177,7 +165,6 @@ const SPITObject& SPITObject::getSPITObjectRemoteRef(int p_Index) { SPITObject* ptrSPITObject = NULL; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); if (p_Index >= 0 && p_Index < s_SPITObjectsRemote.size()) { unordered_map::iterator i = next(s_SPITObjectsRemote.begin(), p_Index); ptrSPITObject = i->second; @@ -192,7 +179,6 @@ void SPITObject::clearSPITObjects() { SPITObject* ptrSPITObject; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); for (auto i = s_SPITObjects.begin(); i != s_SPITObjects.end(); i++) { ptrSPITObject = i->second; i = s_SPITObjects.erase(i); @@ -206,7 +192,6 @@ void SPITObject::clearSPITObjectsRemote() { SPITObject* ptrSPITObject; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); for (auto i = s_SPITObjectsRemote.begin(); i != s_SPITObjectsRemote.end(); i++) { ptrSPITObject = i->second; i = s_SPITObjectsRemote.erase(i); @@ -227,7 +212,6 @@ void SPITObject::setConfirmedFalse() { SPITObject* ptrSPITObject; { - fos::MutexGuard o_LockObject(s_MutexSPITObject); for (auto i = s_SPITObjects.begin(); i != s_SPITObjects.end(); i++) { ptrSPITObject = i->second; ptrSPITObject->setConfirmed(false); diff --git a/components/spit/src/SPITPlayer.cpp b/components/spit/src/SPITPlayer.cpp index 5a8b059..53ce986 100644 --- a/components/spit/src/SPITPlayer.cpp +++ b/components/spit/src/SPITPlayer.cpp @@ -14,12 +14,10 @@ #include "SPITPlayer.h" -fos::Mutex SPITPlayer::s_Mutex; unordered_map SPITPlayer::s_SPITPlayers; SPITPlayer* SPITPlayer::getSPITPlayer(string p_PlayerID) { { - fos::MutexGuard o_LockSPITPlayer(*SPITPlayer::getMutex()); auto i = s_SPITPlayers.find(p_PlayerID); if (i == s_SPITPlayers.end()) { s_SPITPlayers[p_PlayerID] = new SPITPlayer(p_PlayerID); @@ -33,7 +31,6 @@ SPITPlayer* SPITPlayer::getSPITPlayer(string p_PlayerID) { void SPITPlayer::clearPlayers() { SPITPlayer* ptrSPITPlayer; { - fos::MutexGuard o_LockSPITPlayer(*SPITPlayer::getMutex()); for (auto i = s_SPITPlayers.begin(); i != s_SPITPlayers.end(); i++) { ptrSPITPlayer = i->second; i = s_SPITPlayers.erase(i); @@ -54,7 +51,6 @@ SPITPlayer::SPITPlayer(string p_PlayerID) { SPITPlayer::~SPITPlayer() { { - fos::MutexGuard o_LockPlayer(s_Mutex); PlayObject* ptrPlayObject; for (auto i = m_PlayObjects.begin(); i != m_PlayObjects.end(); i++) { ptrPlayObject = i->second; @@ -92,7 +88,6 @@ unordered_map* SPITPlayer::getPlayObjects() { SPITPlayer::PlayObject* SPITPlayer::addSPITObject_Playing (string p_SPITObjectID) { PlayObject* ptrPlayObject; { - fos::MutexGuard o_LockSPITPlayer(*SPITPlayer::getMutex()); auto i = m_PlayObjects.find(p_SPITObjectID); if (i == m_PlayObjects.end()) { ptrPlayObject = new PlayObject(this, p_SPITObjectID); @@ -111,7 +106,6 @@ SPITPlayer::PlayObject* SPITPlayer::addSPITObject_Playing (string p_SPITObjectID void SPITPlayer::startPlaySequence() { PlayObject* ptrPlayObject; { - fos::MutexGuard o_LockSPITPlayer(*SPITPlayer::getMutex()); for (auto i = m_PlayObjects.begin(); i != m_PlayObjects.end(); i++) { ptrPlayObject = i->second; ptrPlayObject->startPlaySequence(); @@ -131,7 +125,6 @@ SPITPlayer::PlayObject* SPITPlayer::getPlayObject(string p_SPITObjectID) { void SPITPlayer::endPlaySequence() { PlayObject* ptrPlayObject; { - fos::MutexGuard o_LockSPITPlayer(*SPITPlayer::getMutex()); for (auto i = m_PlayObjects.begin(); i != m_PlayObjects.end(); i++) { ptrPlayObject = i->second; if (ptrPlayObject->getIsPlayed() == false) { diff --git a/components/spit/src/SPITSocket.cpp b/components/spit/src/SPITSocket.cpp index f67ea2c..7836b18 100644 --- a/components/spit/src/SPITSocket.cpp +++ b/components/spit/src/SPITSocket.cpp @@ -4,198 +4,282 @@ * and open the template in the editor. */ -/* - * SPITSOcket is the base class for WindowsSocket and UnixSocket. - * File: SPITSocket.cpp +/* + * Unix implementation of a SPITSocket. + * + * File: UnixSocket.cpp * Author: Hagi - * - * Created on 12. April 2019, 15:40 + * + * Created on 12. April 2019, 15:58 */ #include "SPITSocket.h" +#include "Task.hpp" +#include "esp_log.h" +#include "esp_netif.h" +#include "esp/uuid.h" +#include +#include +using namespace std; -//----- initialize static members ----- -fos::Mutex SPITSocket::s_MutexIPAddresses; -unordered_map SPITSocket::s_IPAddresses; -int SPITSocket::FAMILY_IP4 = 2; -int SPITSocket::FAMILY_IP6 = 23; +/** + * Creates socket. If there exist some, they will be closed. + * @return + */ +bool SPITSocket::createSocket_UDP() { + bool boolSuccess = true; + int intResult = -1; + int intOptionValue4 = 1; + + // ip4 + if (m_UDPSocketIP4 != INVALID_SOCKET) { + close(m_UDPSocketIP4); + m_UDPSocketIP4 = INVALID_SOCKET; + } + + m_UDPSocketIP4 = socket(AF_INET, SOCK_DGRAM, 0); + if (m_UDPSocketIP4 == INVALID_SOCKET) { + boolSuccess = false; + } else { + intResult = setsockopt(m_UDPSocketIP4, SOL_SOCKET, SO_REUSEADDR, (void *)&intOptionValue4, sizeof(intOptionValue4)); + } + + // // set the m_UDPSocketIP4 in NON BLOCKING mode because + // // if the UDPSockets are in blocking mode the receiveMessage does not return in every constellation + // int intFlags; + // intFlags = fcntl(m_UDPSocketIP4, F_GETFL); + // fcntl(m_UDPSocketIP4, F_SETFL, intFlags | O_NONBLOCK); + + struct timeval tv; + tv.tv_sec = 1; // seconds + tv.tv_usec = 0; // microseconds (0.0 sec) + + // This sets the receive timeout + setsockopt(m_UDPSocketIP4, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); -SPITSocket::SPITSocket() { - m_ServerIP = ""; - m_ServerPort = ""; - m_ClientIP = ""; - m_ClientPort = ""; - m_BoundClientPort = ""; - m_BoundClientFamily = 0; - m_IsBound = false; + if (intResult < 0) { + boolSuccess = false; + } + return boolSuccess; +} + +/** + * Binds the socket to the client's ip address and port. The socket option SO_REUSEADDR is set to true. + * @param p_ClientIP ip address of the client + * @param p_ClientPort port of the client. + * if p_Port == "0" any free port will be used + * @return -1 id bind fails, o if bind is ok + * + */ +int SPITSocket::bindSocket(string p_ClientIP, string p_ClientPort) { + addrinfo *clientAI; + struct sockaddr_in *ptrIP4SocketAddress; + struct sockaddr_in o_IP4SocketAddress; + int intSocklen; + string stringClientPort; + if (p_ClientPort.length() <= 0) + stringClientPort = "0"; + else + stringClientPort = p_ClientPort; + // int intResult = SOCKET_ERROR; + int intResult = 0; + if (getaddrinfo(p_ClientIP.data(), p_ClientPort.data(), NULL, &clientAI) != 0) { + return -1; + } + switch (clientAI->ai_family) { + case AF_INET: + if (m_UDPSocketIP4 == INVALID_SOCKET) { + break; + } + ptrIP4SocketAddress = reinterpret_cast(clientAI->ai_addr); + intSocklen = sizeof(*ptrIP4SocketAddress); + // copy the ptrIP4SocketAddress, may be not filled correct by getaddrinfo + memset(&o_IP4SocketAddress, 0, intSocklen); + o_IP4SocketAddress.sin_addr = ptrIP4SocketAddress->sin_addr; + o_IP4SocketAddress.sin_family = ptrIP4SocketAddress->sin_family; + // o_IP4SocketAddress.sin_zero = ptrIP4SocketAddress->sin_zero; + o_IP4SocketAddress.sin_port = ptrIP4SocketAddress->sin_port; + intResult = bind(m_UDPSocketIP4, (const sockaddr *)(ptrIP4SocketAddress), (socklen_t)intSocklen); + if (intResult < 0) { + break; + } + setBoundClientFamily(AF_INET); + if (intResult == 0) { + if (getsockname(m_UDPSocketIP4, (sockaddr *)ptrIP4SocketAddress, (socklen_t *)&intSocklen) != -1) { + setBoundClientPort(to_string((int)ptrIP4SocketAddress->sin_port)); + } + } + break; + default: + setBoundClientFamily(0); + intResult = -1; + break; + } + freeaddrinfo(clientAI); + + if (intResult == -1) { + setIsBound(false); + } else { + setIsBound(true); + } + return intResult; +} + +/** + * Set whether the sockat are brodcast sockets or not. Set the sockopt SO_BROADCAST to 0 or 1 + * @param p_Broadcast true SO_BROADCAST is set + * false = SO_BROADCAST is not set + * @return 0 = ok, -1 = error + */ +int SPITSocket::setBroadcast(bool p_Broadcast) { + int intResult; + int intOptionValue = 1; + u_char charOptionValue = 0x01; + // IP4 + if (p_Broadcast) { + intOptionValue = 1; + } else { + intOptionValue = 0; + } + intResult = setsockopt(m_UDPSocketIP4, SOL_SOCKET, SO_BROADCAST, &intOptionValue, sizeof(int)); + // intResult = setsockopt(m_UDPSocketIP4, IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&charOptionValue, sizeof(charOptionValue)); + + return intResult; +} +/** + * + * @param p_InetFamily AF_INET or AF_INET6 + * @param p_ServerIP the ip address of the server + * @param p_ServerPort the port of the server + * @param p_MessageBytes buffer containing the message + * @param p_MessageLength the length of the message + * @return -1 send fails + * 0 send is done + */ +int SPITSocket::sendMessageTo(int p_InetFamily, string p_ServerIP, string p_ServerPort, const char *p_MessageBytes, int p_MessageLength) { + if (m_UDPSocketIP4 == INVALID_SOCKET) + return -1; + struct addrinfo *ptrAddressInfo; + struct sockaddr_in *ptrIP4SocketAddress; + struct sockaddr_in o_IP4SocketAddress; + int intSocklen; + int intResult = -1; + + // prepare AddressInfo + if (getaddrinfo(p_ServerIP.data(), p_ServerPort.data(), NULL, &ptrAddressInfo) != 0) { + return -1; + } + switch (ptrAddressInfo->ai_family) { + case AF_INET: + ptrIP4SocketAddress = reinterpret_cast(ptrAddressInfo->ai_addr); + intSocklen = sizeof(*ptrIP4SocketAddress); + if (m_UDPSocketIP4 != INVALID_SOCKET) { + // copy the ptrIP4SocketAddress, may be not filled correct by getaddrinfo + memset(&o_IP4SocketAddress, 0, intSocklen); + o_IP4SocketAddress.sin_addr = ptrIP4SocketAddress->sin_addr; + o_IP4SocketAddress.sin_family = ptrIP4SocketAddress->sin_family; + o_IP4SocketAddress.sin_port = ptrIP4SocketAddress->sin_port; + intResult = sendto(m_UDPSocketIP4, p_MessageBytes, p_MessageLength, 0, (const sockaddr *)&o_IP4SocketAddress, (socklen_t)intSocklen); + if (intResult < 0) { + printf("UnixSocket::sendMessageTo IP4 sendto %s FAILED %s\n", p_ServerIP.data(), strerror(errno)); + printf("UnixSocket::sendMessageTo ret=%d %s / %s / %d\n", intResult, + p_ServerPort.data(), p_MessageBytes, p_MessageLength); + } + freeaddrinfo(ptrAddressInfo); + } + break; + default: + intResult = -1; + } + + if (intResult == -1) { + return -1; + } + return 0; +} + /** + * Call this for receiving a message + * This will block until a message is received or the underlying socket is closed + * @param p_InetFamily either AF_INET or AF_INET6
+ * The SPITSocket creates two udp sockets, one for IP4 and one for IP6 + * This parameter decides from which socket should a message recieved + * @param p_Buffer the buffer containing the received message later. + * @param p_BufferLength the size of the buffer + * @param p_ServerIP a pointer to a string, when a messages is received the string will contain the ip address of the sender/server + * if p_ServerIP is NULL - no detection of the server will be done. + * @return + */ +int SPITSocket::receiveMessage(int p_InetFamily, char *p_Buffer, int p_BufferLength, string *p_ServerIP) { + int intResult = -1; + // ADDRINFO *AI; + struct sockaddr_in o_IP4SocketAddress; + int intSocklen; + + switch (p_InetFamily) { + case AF_INET: + if (m_UDPSocketIP4 == INVALID_SOCKET) { + break; + } + intSocklen = sizeof(o_IP4SocketAddress); + memset(&o_IP4SocketAddress, 0, intSocklen); + intResult = recvfrom(m_UDPSocketIP4, (void *)p_Buffer, p_BufferLength, 0 , (sockaddr *)&o_IP4SocketAddress, (socklen_t *)&intSocklen); + if (intResult >= 0) { + if (p_ServerIP != NULL) { + char bufferIP4[INET_ADDRSTRLEN]; + inet_ntop(AF_INET, &(o_IP4SocketAddress.sin_addr), bufferIP4, intSocklen); + *p_ServerIP = bufferIP4; + } + } + break; + } + return intResult; } -SPITSocket::~SPITSocket() { - { - fos::MutexGuard o_LockSocket(m_MutexSocket); - m_IsBound = false; +SPITSocket::IPAddress SPITSocket::getAdaptersInfo() { + // iterate over active interfaces, and print out IPs + esp_netif_t *netif = NULL; + while ((netif = esp_netif_next_unsafe(netif)) != NULL) { + ESP_LOGI("SPIT", "Connected to %s", esp_netif_get_desc(netif)); + esp_netif_ip_info_t ip; + ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip)); + ESP_LOGI("SPIT", "- IPv4 address: " IPSTR ",", IP2STR(&ip.ip)); + ESP_LOGI("SPIT", "- IPv4 netmask: " IPSTR ",", IP2STR(&ip.netmask)); + char buffer[64]; + + sprintf(buffer, IPSTR, IP2STR(&ip.ip)); + string stringIP4 = buffer; + sprintf(buffer, IPSTR, IP2STR(&ip.netmask)); + string stringSubnet = buffer; + return {stringIP4, stringSubnet}; + } + return {"0.0.0.0", "0.0.0.0"}; +} + +string createGUID() { + // uuid_t id; + // uuid_generate(id); + // char *guid_string = new char[100]; + // uuid_unparse(id, guid_string); + // string stringGUID = guid_string; + // return stringGUID; + + uuid_t uu; + char uu_str[UUID_STR_LEN]; + + uuid_generate(uu); + uuid_unparse(uu, uu_str); + string stringGUID = uu_str; + return stringGUID; +} +/** The name of the client's host computer*/ +string getClientHostName() { + string stringHostName = ""; + const char * hostname; + esp_netif_get_hostname(esp_netif_get_default_netif(), &hostname); + if (hostname != nullptr) { + stringHostName = hostname; } -} -void SPITSocket::setConnectionParams(string p_ServerIP, string p_ServerPort, string p_ClientIP, string p_ClientPort) { - m_ServerIP = p_ServerIP; - m_ServerPort = p_ServerPort; - m_ClientIP = p_ClientIP; - m_ClientPort = p_ClientPort; -} -string SPITSocket::getServerIP() { - return m_ServerIP; -} -string SPITSocket::getServerPort(){ - return m_ServerPort; -} -string SPITSocket::getClientIP() { - return m_ClientIP; -} -string SPITSocket::getClientPort() { - return m_ClientPort; -} -string SPITSocket::getBoundClientPort() { - return m_BoundClientPort; -} -void SPITSocket::setBoundClientPort(string p_Port) { - m_BoundClientPort = p_Port; -} -int SPITSocket::getBoundClientFamily() { - return m_BoundClientFamily; -} -void SPITSocket::setBoundClientFamily(int p_Family) { - m_BoundClientFamily = p_Family; -} - -void SPITSocket::setIsBound(bool p_IsBound) { - { - fos::MutexGuard o_LockSocket(m_MutexSocket); - m_IsBound = p_IsBound; - } -} -bool SPITSocket::getIsBound() { - return m_IsBound; -} - -int SPITSocket::sendMessage(const char* p_MessageBytes, int p_MessageLength) { - if (m_ServerPort.length() <= 0) return -1; - int intResult; - { - fos::MutexGuard o_LockSocket(m_MutexSocket); - if (m_IsBound == false) return -1; - intResult = sendMessageTo(m_BoundClientFamily, m_ServerIP, m_ServerPort, p_MessageBytes, p_MessageLength); - } - return intResult; -} - - - -//---------- IP Adresses --------- -void SPITSocket::addIPAddress(string p_IPAddress, string p_SubnetMask) { - IPAddress* o_IPAddress; - { - fos::MutexGuard o_LockIP(s_MutexIPAddresses); - auto i = s_IPAddresses.find(p_IPAddress); - if (i != s_IPAddresses.end()) { - o_IPAddress = i->second; - } - else { - o_IPAddress = new IPAddress(); - } - o_IPAddress->setIPAddress(p_IPAddress); - o_IPAddress->setSubnetMask(p_SubnetMask); - o_IPAddress->setFound(true); - s_IPAddresses[o_IPAddress->getIPAddress()] = o_IPAddress; - } -} -void SPITSocket::removeIPAddress(string p_IPAddress) { - IPAddress* o_IPAddress; - { - fos::MutexGuard o_LockIP(s_MutexIPAddresses); - auto i = s_IPAddresses.find(p_IPAddress); - if (i != s_IPAddresses.end()) { - o_IPAddress = i->second; - i = s_IPAddresses.erase(i); - delete o_IPAddress; - } - } -} -int SPITSocket::getIPAddressCount() { - return s_IPAddresses.size(); -} -SPITSocket::IPAddress* SPITSocket::getIPAddress(int p_Index) { - IPAddress* ptr_IPAddress = NULL; - { - fos::MutexGuard o_LockIP(s_MutexIPAddresses); - if (p_Index <= s_IPAddresses.size()) { - unordered_map::iterator i = next(s_IPAddresses.begin(), p_Index); - ptr_IPAddress = i->second; - } - return ptr_IPAddress; - } -} -void SPITSocket::clearIPAddresses() { - IPAddress* o_IPAddress; - { - fos::MutexGuard o_LockIP(s_MutexIPAddresses); - for (auto i = s_IPAddresses.begin(); i != s_IPAddresses.end(); i++) { - o_IPAddress = i->second; - i = s_IPAddresses.erase(i); - delete o_IPAddress; - if (i == s_IPAddresses.end()) { - break; - } - } - } - } - - -void SPITSocket::resetFoundIPAddresses() { - IPAddress* o_IPAddress; - { - fos::MutexGuard o_LockIP(s_MutexIPAddresses); - for (auto i = s_IPAddresses.begin(); i != s_IPAddresses.end(); i++) { - o_IPAddress = i->second; - o_IPAddress->setFound(false); - } - } -} -void SPITSocket::removeNotFoundIPAddresses() { - IPAddress* o_IPAddress; - { - fos::MutexGuard o_LockIP(s_MutexIPAddresses); - for (auto i = s_IPAddresses.begin(); i != s_IPAddresses.end(); i++) { - o_IPAddress = i->second; - if (o_IPAddress->getFound() == false) { - i = s_IPAddresses.erase(i); - delete o_IPAddress; - if (i == s_IPAddresses.end()) { - break; - } - } - } - } -} - - - -//------------ IPAddress ------------------- -SPITSocket::IPAddress::IPAddress() { - m_IPAddress = ""; - m_SubnetMask = ""; - m_Found = false; -} -SPITSocket::IPAddress::~IPAddress() { - m_Found = false; -} -void SPITSocket::IPAddress::setIPAddress(const string& p_IPAddress) { - m_IPAddress = p_IPAddress; -} -void SPITSocket::IPAddress::setSubnetMask(const string& p_SubnetMask) { - m_SubnetMask = p_SubnetMask; -} -void SPITSocket::IPAddress::setFound(bool p_Found) { - m_Found = p_Found; + return stringHostName;; } diff --git a/components/spit/src/SPITType.cpp b/components/spit/src/SPITType.cpp index 76f54b8..789b2e9 100644 --- a/components/spit/src/SPITType.cpp +++ b/components/spit/src/SPITType.cpp @@ -14,15 +14,15 @@ #include "SPITType.h" -#include "_SPITMACROS.h" +#include "esp_log.h" + +static const char * TAG = "SPIT"; unordered_map SPITType::s_SPITTypes; unordered_map SPITType::s_SPITTypesRemote; - fos::Mutex SPITType::s_MutexSPITType; SPITType* SPITType::getSPITType(string p_ID) { { - fos::MutexGuard o_LockType(s_MutexSPITType); auto i = s_SPITTypes.find(p_ID); if (i == s_SPITTypes.end()) { return NULL; @@ -38,7 +38,6 @@ */ const SPITType& SPITType::getSPITTypeRef(string p_ID) { { - fos::MutexGuard o_LockType(s_MutexSPITType); auto i = s_SPITTypes.find(p_ID); if (i == s_SPITTypes.end()) { throw "SPITType no SPITType with given ID"; @@ -49,7 +48,6 @@ SPITType* SPITType::getSPITTypeRemote(string p_ID) { { - fos::MutexGuard o_LockType(s_MutexSPITType); auto i = s_SPITTypesRemote.find(p_ID); if (i == s_SPITTypesRemote.end()) { return NULL; @@ -65,7 +63,6 @@ */ const SPITType& SPITType::getSPITTypeRemoteRef(string p_ID) { { - fos::MutexGuard o_LockType(s_MutexSPITType); auto i = s_SPITTypesRemote.find(p_ID); if (i == s_SPITTypesRemote.end()) { throw "Remote SPITType no SPITType with given ID"; @@ -77,7 +74,6 @@ bool SPITType::addSPITType(SPITType* p_ptrSpitType) { if (p_ptrSpitType == NULL) return false; { - fos::MutexGuard o_LockType(s_MutexSPITType); s_SPITTypes[p_ptrSpitType->getID()] = p_ptrSpitType; return true; } @@ -85,7 +81,6 @@ bool SPITType::addSPITTypeRemote(SPITType* p_ptrSpitType) { if (p_ptrSpitType == NULL) return false; { - fos::MutexGuard o_LockType(s_MutexSPITType); s_SPITTypesRemote[p_ptrSpitType->getID()] = p_ptrSpitType; return true; } @@ -93,7 +88,6 @@ bool SPITType::removeSPITType(SPITType* p_ptrSpitType) { if (p_ptrSpitType == NULL) return false; { - fos::MutexGuard o_LockType(s_MutexSPITType); auto i = s_SPITTypes.find(p_ptrSpitType->getID()); if (i == s_SPITTypes.end()) { return false; @@ -105,7 +99,6 @@ bool SPITType::removeSPITTypeRemote(SPITType* p_ptrSpitType) { if (p_ptrSpitType == NULL) return false; { - fos::MutexGuard o_LockType(s_MutexSPITType); auto i = s_SPITTypesRemote.find(p_ptrSpitType->getID()); if (i == s_SPITTypesRemote.end()) { return false; @@ -124,7 +117,6 @@ SPITType* SPITType::getSPITType(int p_Index) { SPITType* ptrSPITType = NULL; { - fos::MutexGuard o_LockType(s_MutexSPITType); if (p_Index < s_SPITTypes.size()) { unordered_map::iterator i = next(s_SPITTypes.begin(), p_Index); ptrSPITType = i->second; @@ -141,7 +133,6 @@ const SPITType& SPITType::getSPITTypeRef(int p_Index) { SPITType* ptrSPITType = NULL; { - fos::MutexGuard o_LockType(s_MutexSPITType); if (p_Index >= 0 && p_Index < s_SPITTypes.size()) { unordered_map::iterator i = next(s_SPITTypes.begin(), p_Index); ptrSPITType = i->second; @@ -155,7 +146,6 @@ SPITType* SPITType::getSPITTypeRemote(int p_Index) { SPITType* ptrSPITType = NULL; { - fos::MutexGuard o_LockType(s_MutexSPITType); if (p_Index < s_SPITTypesRemote.size()) { unordered_map::iterator i = next(s_SPITTypesRemote.begin(), p_Index); ptrSPITType = i->second; @@ -172,7 +162,6 @@ const SPITType& SPITType::getSPITTypeRemoteRef(int p_Index) { SPITType* ptrSPITType = NULL; { - fos::MutexGuard o_LockType(s_MutexSPITType); if (p_Index >= 0 && p_Index < s_SPITTypesRemote.size()) { unordered_map::iterator i = next(s_SPITTypesRemote.begin(), p_Index); ptrSPITType = i->second; @@ -187,7 +176,6 @@ void SPITType::clearSPITTypes() { SPITType* ptrSPITType; { - fos::MutexGuard o_LockType(s_MutexSPITType); for (auto i = s_SPITTypes.begin(); i != s_SPITTypes.end(); i++) { ptrSPITType = i->second; i = s_SPITTypes.erase(i); @@ -201,7 +189,6 @@ void SPITType::clearSPITTypesRemote() { SPITType* ptrSPITType; { - fos::MutexGuard o_LockType(s_MutexSPITType); for (auto i = s_SPITTypesRemote.begin(); i != s_SPITTypesRemote.end(); i++) { ptrSPITType = i->second; i = s_SPITTypesRemote.erase(i); @@ -220,7 +207,6 @@ void SPITType::setConfirmedFalse() { SPITType* ptrSPITType; { - fos::MutexGuard o_LockType(s_MutexSPITType); for (auto i = s_SPITTypes.begin(); i != s_SPITTypes.end(); i++) { ptrSPITType = i->second; ptrSPITType->setConfirmed(false); diff --git a/components/spit/src/SPIT_Client.cpp b/components/spit/src/SPIT_Client.cpp index 3e8aa6f..7edf648 100644 --- a/components/spit/src/SPIT_Client.cpp +++ b/components/spit/src/SPIT_Client.cpp @@ -20,93 +20,61 @@ static const char * TAG = "SPIT"; -SPITSocket* SPIT_Client::createSPITSocket() { - SPITSocket* ptrSPITSocket = NULL; - ptrSPITSocket = new UnixSocket(); - return ptrSPITSocket; -} - /** * 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. */ -SPIT_Client::SPIT_Client(SPIT_ClientInterface* p_SPITClientInterface): SAD_ClientInterface() { - m_SPITClientInterface = p_SPITClientInterface; +SPIT_Client::SPIT_Client(string name, string projName, Callbacks calls) + : I_SAD_Client(), mCallbacks(calls), m_Name(name), m_ProjName(projName) { m_ConnectionStatus = CONNECTION_NONE; - m_DisconnectedByServer = false; - m_SPITSocket = NULL; - m_ThreadReceive = NULL; - m_ServerID = ""; - m_ServerName = ""; - m_ServerComputerName = ""; - m_ServerStepTime = -1; - - UnixSocket::init(); m_ID = createGUID(); m_ComputerName = getClientHostName(); - m_Watchdog = new Watchdog(this); + auto ip = SPITSocket::getAdaptersInfo(); + mSPITSocket = new SPITSocket(ip); + m_MessageNumber_Send = 1; + m_MessageNumber_Received = -1; //set to -1 because the first received message will set the number (1..255) } SPIT_Client::~SPIT_Client() { stopServerAutoDetect(); - disconnectInternal(CONNECTION_NONE); - - SPIT_Handler::closeHandler(); - - UnixSocket::cleanUp(); } -/** The ID of the client.
Every client instance should set an unique id.
This is done autmatically.*/ -string SPIT_Client::getID() { - return m_ID; -} +/** The ID of the client. Every client instance should set an unique id.*/ +string SPIT_Client::getID() { return m_ID; } /** The name of the client's host computer*/ -string SPIT_Client::getComputerName() { - return m_ComputerName; -} +string SPIT_Client::getComputerName() { return m_ComputerName; } + /** * Sets the name of the client. This should be done by the user app. * @param p_Name the anme of the user's app */ -void SPIT_Client::setName(string p_Name) { - m_Name = p_Name; -} /** The name of the client, as set by the user's app*/ -string SPIT_Client::getName() { - return m_Name; -} +string SPIT_Client::getName() { return m_Name; } //connected Server Infos /**If a connection is established. THis returns the SPITServer's ID*/ -string SPIT_Client::getServerID() { - return m_ServerID; -} +string SPIT_Client::getServerID() { return m_ServerID; } /**If a connection is established. THis returns the SPITServer's computer/host name*/ -string SPIT_Client::getServerComputerName() { - return m_ServerComputerName; -} +string SPIT_Client::getServerComputerName() { return m_ServerComputerName; } /**If a connection is established. THis returns the SPITServer's name*/ -string SPIT_Client::getServerName() { - return m_ServerName; -} +string SPIT_Client::getServerName() { return m_ServerName; } + /** 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 SPIT_Client::getServerStepTime() { - return m_ServerStepTime; -} +int SPIT_Client::getServerStepTime() { return m_ServerStepTime; } -void SPIT_Client::clientProjectClose() { +void SPIT_Client::clientProjectClose() { if (m_ConnectionStatus == CONNECTION_OK) { - SPIT_Message::CloseSPITProject* ptrSMCloseSPITProject; - ptrSMCloseSPITProject = new SPIT_Message::CloseSPITProject(); - fillHeader(ptrSMCloseSPITProject->getHeader()); - ptrSMCloseSPITProject->setProjectID(m_SPITClientInterface->getClientProjectID()); - if (sendSPITMessage(ptrSMCloseSPITProject) < 0) { + ESP_LOGI(TAG, " ... tidy up ressources"); + SPIT_Message::CloseSPITProject sMCloseSPITProject; + fillHeader(sMCloseSPITProject.getHeader()); + sMCloseSPITProject.setProjectID(m_ProjName); + if (sendSPITMessage(sMCloseSPITProject) < 0) { ESP_LOGD(TAG, "SPIT_Client could not send Client's ReportSPITProject"); } } @@ -119,26 +87,22 @@ void SPIT_Client::clientProjectLoaded() { if (m_ConnectionStatus == CONNECTION_OK) { //send ReportSPITProject to the server - SPIT_Message::ReportSPITProject* ptrSMReportSPITProject; - ptrSMReportSPITProject = new SPIT_Message::ReportSPITProject(); - fillHeader(ptrSMReportSPITProject->getHeader()); - ptrSMReportSPITProject->setProjectID(m_SPITClientInterface->getClientProjectID()); - ptrSMReportSPITProject->setProjectName(m_SPITClientInterface->getClientProjectName()); - ptrSMReportSPITProject->setFramesPerSecond(0); - if (sendSPITMessage(ptrSMReportSPITProject) < 0) { + SPIT_Message::ReportSPITProject sMReportSPITProject; + fillHeader(sMReportSPITProject.getHeader()); + sMReportSPITProject.setProjectID(m_ProjName); + sMReportSPITProject.setProjectName(m_ProjName); + sMReportSPITProject.setFramesPerSecond(0); + if (sendSPITMessage(sMReportSPITProject) < 0) { ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send Client's ReportSPITProject"); } //send RequestProjectTransfer - SPIT_Message::RequestProjectTransfer* ptrSMRequestProjectTransfer; - ptrSMRequestProjectTransfer = new SPIT_Message::RequestProjectTransfer(); - fillHeader(ptrSMRequestProjectTransfer->getHeader()); - if (sendSPITMessage(ptrSMRequestProjectTransfer) < 0) { + SPIT_Message::RequestProjectTransfer sMRequestProjectTransfer; + fillHeader(sMRequestProjectTransfer.getHeader()); + if (sendSPITMessage(sMRequestProjectTransfer) < 0) { ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send RequestProjectTransfer"); } } - - } @@ -154,16 +118,11 @@ void SPIT_Client::setActionSPITType(string p_SPITTypeID, bool p_ActionAssigned) SPITType* ptrSPITType; SPITObject* ptrSPITObject; { - fos::MutexGuard o_LockType(*SPITType::getMutex()); - ptrSPITType = SPITType::getSPITType(p_SPITTypeID); if (ptrSPITType == NULL) return; if (ptrSPITType->setActionAssigned(p_ActionAssigned) == true) { sendSPITTypeInternal(ptrSPITType); - //setActionAssigned to all SPITObjects with this SPITType - fos::MutexGuard o_LockObject(*SPITObject::getMutex()); - for (int i = 0; i < SPITObject::getSPITObjectCount(); i++) { ptrSPITObject = SPITObject::getSPITObject(i); if (ptrSPITObject == NULL) break; @@ -185,8 +144,6 @@ void SPIT_Client::setActionSPITType(string p_SPITTypeID, bool p_ActionAssigned) void SPIT_Client::setActionSPITObject(string p_SPITObjectID, bool p_ActionAssigned) { SPITObject* ptrSPITObject; { - fos::MutexGuard o_LockObject(*SPITObject::getMutex()); - ptrSPITObject = SPITObject::getSPITObject(p_SPITObjectID); if (ptrSPITObject == NULL) return; if (ptrSPITObject->setActionAssigned(p_ActionAssigned) == true) { @@ -205,42 +162,88 @@ void SPIT_Client::startServerAutoDetect() { //sleep a little to give the SPITServer time to clean up its stuff - fos::Task::delayMs(1000); } - SPITSocket* ptrSPITSocket; - ptrSPITSocket = createSPITSocket(); - if (ptrSPITSocket == NULL) return; - ptrSPITSocket->setBroadcast(true); - SAD_Client::startAutoDetectServer(this, ptrSPITSocket); + + SAD_DetectedServer::clearDetectedServers(); + if (!sThread) { + sThread = new fos::TaskT(SPIT_Client::processSocketTask, *this, "spitSock"); + } + abortSearch = false; + sStartSad.give(); } + /** * Stops the auto detection of SPIT servers. */ void SPIT_Client::stopServerAutoDetect() { - SAD_Client::stopAutoDetectServer(this); + abortSearch = true; } -void SPIT_Client::eventServerDetected(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_ClientIP, bool p_isLoopback, bool p_IsIP4, bool p_IsIP6) { - SAD_DetectedServer o_RefDetectedServer; + /** + * 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:
+ * 1.) If a loopback address is available, it is used.
+ * 2.) If an IP4 address is available, it is used.
+ * 3.) In the other cases the IP6 address is used.
+ * @param p_ID the id of the server (every started server should generate an id) + * @param p_Name the name of the SPIT server + * @param p_ComputerName the Hostname of the cpmputer on which the SPIT server is running + * @param p_IP the selected ip address of the SPIT server + * @param p_Port the port of the SPIT server + * @param p_Addition sometimes server may have additional informations + * @param p_IsIP4 the server ip is a ip4 address + */ +void SPIT_Client::eventServerDetected(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_ClientIP, bool p_IsIP4) { try { - o_RefDetectedServer = SAD_DetectedServer::getRefDetectedServer(p_ID); - } - catch (...) { - return; - } - NotifyServerDetected* o_Runnable = new NotifyServerDetected(m_SPITClientInterface, o_RefDetectedServer); - SPIT_Handler::addRunnable(o_Runnable); -} -void SPIT_Client::eventServerLost(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_ClientIP, bool p_isLoopback, bool p_IsIP4, bool p_IsIP6) { - SAD_DetectedServer o_RefDetectedServer; - try { - o_RefDetectedServer = SAD_DetectedServer::getRefDetectedServer(p_ID); - } - catch (...) { - return; - } - NotifyServerLost* o_Runnable = new NotifyServerLost(m_SPITClientInterface, o_RefDetectedServer); - SPIT_Handler::addRunnable(o_Runnable); -} + SAD_DetectedServer o_RefDetectedServer = SAD_DetectedServer::getRefDetectedServer(p_ID); + mCallbacks.onServerDetect(o_RefDetectedServer); + // If a connection has been established and the connection is lost -> reconnect + if (_doReconnect) { + if (m_ServerID == o_RefDetectedServer.getID()) { + stopServerAutoDetect(); + ESP_LOGI(TAG, "reconnect to %s", o_RefDetectedServer.getIP().data()); + // ClientPort = "0" meeans use any port + if (connect(o_RefDetectedServer.getIP(), o_RefDetectedServer.getPort(), o_RefDetectedServer.getClientIP(), "0")) { + return; + } + } + } + + // Stop auto detection because a suitable server was found + stopServerAutoDetect(); + ESP_LOGI(TAG, "connect to %s", o_RefDetectedServer.getIP().data()); + // ClientPort = "0" meeans use any port + if (not connect(o_RefDetectedServer.getIP(), o_RefDetectedServer.getPort(), o_RefDetectedServer.getClientIP(), "0")) { + // connection message could not be sent -> better to restart AutoDetection + startServerAutoDetect(); + } + + } + catch (...) { + return; + } +} + /** + * 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.
+ * @param p_ID the id of the server (every started server should generate an id) + * @param p_Name the name of the SPIT server + * @param p_ComputerName the Hostname of the cpmputer on which the SPIT server is running + * @param p_IP the selected ip address of the SPIT server + * @param p_Port the port of the SPIT server + * @param p_Addition sometimes server may have additional informations + * @param p_IsIP4 the server ip is a ip4 address + */ +void SPIT_Client::eventServerLost(string p_ID, string p_Name, string p_ComputerName, string p_IP, string p_Port, string p_Addition, string p_ClientIP, bool p_IsIP4) { + try { + SAD_DetectedServer o_RefDetectedServer = SAD_DetectedServer::getRefDetectedServer(p_ID); + mCallbacks.onServerLost(o_RefDetectedServer); + } + catch (...) { + return; + } +} void SPIT_Client::fillHeader(SPIT_Message::Header* p_Header) { @@ -249,118 +252,83 @@ void SPIT_Client::fillHeader(SPIT_Message::Header* p_Header) { p_Header->setServerID(m_ServerID); } -int SPIT_Client::sendSPITMessage(SPIT_Message::OPPart* p_SPITMessageOPPart) { - if (p_SPITMessageOPPart == NULL) return -1; - { - fos::MutexGuard o_LockSocket(m_MutexSPITSocket); - - if (m_SPITSocket == NULL || m_StopReceiveSPITMessages == true) { - delete p_SPITMessageOPPart; - return -1; - } - SPIT_Message* ptrSPIT_Message; - const char* ptrMessageBytes; - int intByteCount; - int intResult; - ptrSPIT_Message = new SPIT_Message(p_SPITMessageOPPart); - ptrMessageBytes = ptrSPIT_Message->getMessageBytes(); - intByteCount = ptrSPIT_Message->getMesageByteCount(); - if (ptrMessageBytes == NULL) { - delete ptrSPIT_Message; - return -1; - } - try { - intResult = m_SPITSocket->sendMessage(ptrMessageBytes, intByteCount); - if (intResult < 0) { - ESP_LOGD(TAG, "SPIT_Client::sendSPITMessage could not send message OPFlage: %d", ptrSPIT_Message->getOPFlag()); - } - delete ptrSPIT_Message; - p_SPITMessageOPPart = NULL; - return intResult; - } - catch (...) { - ESP_LOGD(TAG, "Exception SPIT_Client::sendSPITMessage OPFlag: %d", ptrSPIT_Message->getOPFlag()); - return -1; +int SPIT_Client::sendSPITMessage(SPIT_Message::OPPart& spitMessageOPPart) { + if (m_StopReceiveSPITMessages == true) { + return -1; + } + + if (m_MessageNumber_Send == 255) m_MessageNumber_Send = 1; + else m_MessageNumber_Send++; + spitMessageOPPart.getHeader()->setMessageNumber(m_MessageNumber_Send); + + SPIT_Message* ptrSPIT_Message; + ptrSPIT_Message = new SPIT_Message(&spitMessageOPPart); + const char* ptrMessageBytes = ptrSPIT_Message->getMessageBytes(); + int intByteCount = ptrSPIT_Message->getMesageByteCount(); + + if (ptrMessageBytes == NULL) { + return -1; + } + try { + int intResult = mSPITSocket->sendMessage(ptrMessageBytes, intByteCount); + if (intResult < 0) { + ESP_LOGD(TAG, "SPIT_Client::sendSPITMessage could not send message OPFlage: %d", ptrSPIT_Message->getOPFlag()); } + return intResult; + } + catch (...) { + ESP_LOGD(TAG, "Exception SPIT_Client::sendSPITMessage OPFlag: %d", ptrSPIT_Message->getOPFlag()); + return -1; } } bool SPIT_Client::startReceiveSPITMessages() { { - fos::MutexGuard o_LockSocket(m_MutexSPITSocket); - if (m_SPITSocket == NULL) return false; - if (m_SPITSocket->getBoundClientFamily() <= 0) return false; + if (mSPITSocket->getBoundClientFamily() <= 0) return false; m_StopReceiveSPITMessages = false; - m_ThreadReceive = new fos::TaskT(receiveSPITMessage, *this, "receiveTask"); + m_ThreadReceive = new fos::TaskT(receiveSPITMessage, *this, "receiveTask", fos::Task::DefaultStackSize *4); } return true; } void SPIT_Client::stopReceiveSPITMessages() { - { - fos::MutexGuard o_LockSocket(m_MutexSPITSocket); if (m_StopReceiveSPITMessages == true) return; m_StopReceiveSPITMessages = true; - if (m_SPITSocket != NULL) { - delete m_SPITSocket; - m_SPITSocket = NULL; - } - } - fos::Task::delayMs(100); - if (m_ThreadReceive != NULL) { - try { - delete m_ThreadReceive; - } - catch(...) { - ESP_LOGD(TAG, "Exception SPIT_Client::stopReceiveSPITMessages m_ThreadReceive->join()"); - } - m_ThreadReceive = NULL; } } void SPIT_Client::receiveSPITMessage(SPIT_Client& rM) { - if (rM.m_SPITSocket == NULL) return; - SPIT_Message* ptrSPIT_Message; + char buffer[MAXSPITMESSAGEBYTECOUNT]; int intResult; while (rM.m_StopReceiveSPITMessages == false) { - { - fos::MutexGuard o_LockSocket(rM.m_MutexSPITSocket); - if (rM.m_SPITSocket == NULL || rM.m_StopReceiveSPITMessages == true) { - return; - } + if ( rM.m_StopReceiveSPITMessages == true) { + return; } - intResult = rM.m_SPITSocket->receiveMessage(rM.m_SPITSocket->getBoundClientFamily(), buffer, MAXSPITMESSAGEBYTECOUNT, NULL); - + intResult = rM.mSPITSocket->receiveMessage(rM.mSPITSocket->getBoundClientFamily(), buffer, MAXSPITMESSAGEBYTECOUNT, NULL); if (intResult < 0) { - if (rM.m_StopReceiveSPITMessages == false) { - //To reduce the processor load, we let the thread sleep a little bit. - fos::Task::delayMs(25); -// printf("SPIT_Client::receiveSPITMessage intResult < 0\n"); - continue; - } - else { + if (rM.m_StopReceiveSPITMessages) { return;; } + continue; } - - ptrSPIT_Message = new SPIT_Message(buffer, intResult); - rM.parseSPIT_Message(ptrSPIT_Message); + auto ptrSPIT_Message = make_unique(buffer, intResult); + rM.parseSPIT_Message(move(ptrSPIT_Message)); } } -void SPIT_Client::parseSPIT_Message(SPIT_Message* p_SPITMessage) { - m_Watchdog->answerWatchdog(); - if (p_SPITMessage == NULL) { +void SPIT_Client::parseSPIT_Message(unique_ptr p_SPITMessage) { + answerWatchdog(); + if (!p_SPITMessage) { ESP_LOGD(TAG, "SPIT_Client::parseSPIT_Message Parameter == NULL"); return; } - if (p_SPITMessage->getHeader() == NULL) { + if (p_SPITMessage->getHeader() == nullptr) { ESP_LOGD(TAG, "SPIT_Client::parseSPIT_Message no Header"); return; } - if (p_SPITMessage->getOPPart() == NULL) { + if (p_SPITMessage->getOPPart() == nullptr) { ESP_LOGD(TAG, "SPIT_Client::parseSPIT_Message no OPPart"); return; } @@ -405,7 +373,7 @@ void SPIT_Client::parseSPIT_Message(SPIT_Message* p_SPITMessage) { else if (p_SPITMessage->getOPFlag() == SPIT_Message::EndProjectTransfer::OPFLAG) { SPIT_Message::EndProjectTransfer* o_EndProjectTransfer = (SPIT_Message::EndProjectTransfer*) p_SPITMessage->getOPPart(); parseEndProjectTransfer(o_EndProjectTransfer); - } + } //----- SPIT Types ------ else if (p_SPITMessage->getOPFlag() == SPIT_Message::ReportSPITType::OPFLAG) { SPIT_Message::ReportSPITType* o_ReportSPITType = (SPIT_Message::ReportSPITType*) p_SPITMessage->getOPPart(); @@ -461,56 +429,41 @@ void SPIT_Client::parseSPIT_Message(SPIT_Message* p_SPITMessage) { bool SPIT_Client::connect(string p_ServerIP, string p_ServerPort, string p_ClientIP, string p_ClientPort, string p_LoginName, string p_LoginPassword) { int intResult; disconnect(); - { - fos::MutexGuard o_LockSocket(m_MutexSPITSocket); - m_SPITSocket = createSPITSocket(); - m_SPITSocket->setConnectionParams(p_ServerIP, p_ServerPort, p_ClientIP, p_ClientPort); - intResult = m_SPITSocket->bindSocket(p_ClientIP, p_ClientPort); + mSPITSocket->setConnectionParams(p_ServerIP, p_ServerPort, p_ClientIP, p_ClientPort); + intResult = mSPITSocket->bindSocket(p_ClientIP, p_ClientPort); if (intResult < 0) { m_StopReceiveSPITMessages = true; - delete m_SPITSocket; - m_SPITSocket = NULL; return false; } } - SPIT_Message::Connect* ptrSMConnect; - ptrSMConnect = new SPIT_Message::Connect(); - fillHeader(ptrSMConnect->getHeader()); - ptrSMConnect->setClientComputerName(m_ComputerName); - ptrSMConnect->setClientName(m_Name); - ptrSMConnect->setLoginName(p_LoginName); - ptrSMConnect->setLoginPassword(p_LoginPassword); - ptrSMConnect->setServerIP(p_ServerIP); + SPIT_Message::Connect sMConnect; + fillHeader(sMConnect.getHeader()); + sMConnect.setClientComputerName(m_ComputerName); + sMConnect.setClientName(m_Name); + sMConnect.setLoginName(p_LoginName); + sMConnect.setLoginPassword(p_LoginPassword); + sMConnect.setServerIP(p_ServerIP); if (p_ServerPort.length() <= 0) { p_ServerPort = "0"; } int intServerPort; intServerPort = stoi(p_ServerPort); - ptrSMConnect->setServerPort(intServerPort); + sMConnect.setServerPort(intServerPort); if (startReceiveSPITMessages() == false) { - { - fos::MutexGuard o_LockSocket(m_MutexSPITSocket); m_StopReceiveSPITMessages = true; - delete m_SPITSocket; - m_SPITSocket = NULL; return false; - } } m_ConnectionStatus = CONNECTION_TRYCONNECTION; + //sleep a little to make sure that the reception of the messages is started fos::Task::delayMs(500); - intResult = sendSPITMessage(ptrSMConnect); + intResult = sendSPITMessage(sMConnect); if (intResult < 0) { m_ConnectionStatus = CONNECTION_NONE; - { - fos::MutexGuard o_LockSocket(m_MutexSPITSocket); m_StopReceiveSPITMessages = true; - delete m_SPITSocket; - m_SPITSocket = NULL; return false; - } } return true; } @@ -523,31 +476,50 @@ void SPIT_Client::disconnect() { } void SPIT_Client::disconnectInternal(int p_Cause) { int intOldConnectionStatus = m_ConnectionStatus; - SPIT_Message::Disconnect* ptrSMDisconnect; int intResult; - m_Watchdog->stopWatchdog(); - m_ConnectionStatus = p_Cause; switch (m_ConnectionStatus) { case CONNECTION_LOST: break; case CONNECTION_NONE: - ptrSMDisconnect = new SPIT_Message::Disconnect(); - fillHeader(ptrSMDisconnect->getHeader()); - intResult = sendSPITMessage(ptrSMDisconnect); + { + SPIT_Message::Disconnect sMDisconnect; + fillHeader(sMDisconnect.getHeader()); + intResult = sendSPITMessage(sMDisconnect); if (intResult < 0) { } - break; + } + break; case CONNECTION_NONESERVER: break; } stopReceiveSPITMessages(); if (intOldConnectionStatus != CONNECTION_NONE && intOldConnectionStatus != CONNECTION_NONESERVER) { - NotifyConnectionStatus* o_Runnable = new NotifyConnectionStatus(m_SPITClientInterface, m_ServerID, m_ServerComputerName, m_ServerName, m_ServerStepTime, - m_ConnectionStatus, intOldConnectionStatus); - SPIT_Handler::addRunnable(o_Runnable); + ESP_LOGI(TAG, "eventConnectionStatus %d ", m_ConnectionStatus); + switch (m_ConnectionStatus) { + case SPIT_Client::CONNECTION_NONE: + ESP_LOGD(TAG, "not connected"); + break; + case SPIT_Client::CONNECTION_NONESERVER: + ESP_LOGD(TAG, "connection terminated by server"); + // call eventProjectClosed because this may not be sended by the server, + // when the connection is closed + mCallbacks.onProjectClosed(m_ServerProjectID); + + // Server has terminated the connection -> start a new game + // _doReconnect = false; + startServerAutoDetect(); + break; + case SPIT_Client::CONNECTION_LOST: + 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; + } } } @@ -569,10 +541,14 @@ void SPIT_Client::parseConnectAnswer(SPIT_Message::ConnectAnswer* p_ConnectAnswe p_ConnectAnswer->getStepTime(); m_ConnectionStatus = CONNECTION_OK; m_DisconnectedByServer = false; - m_Watchdog->startWatchdog(); - NotifyConnectionStatus* o_Runnable = new NotifyConnectionStatus(m_SPITClientInterface, m_ServerID, m_ServerComputerName, m_ServerName, m_ServerStepTime, - m_ConnectionStatus, intOldConnectionStatus); - SPIT_Handler::addRunnable(o_Runnable); + ESP_LOGD(TAG, "connection established"); + stopServerAutoDetect(); // normally you should stop the autodetection before you try a connection + // This is redundand + m_StopReceiveSPITMessages = false; + + // Maybe you want to reconnect, see eventServerDetected(...) + // Here the connection is established -> don't reconnect at eventServerDetected(...) + // _doReconnect = false; } } @@ -600,9 +576,8 @@ void SPIT_Client::parseDisconnect(SPIT_Message::Disconnect* p_Disconnect) { */ void SPIT_Client::parseWatchdog(SPIT_Message::Watchdog* p_Watchdog) { // printf("parse Watchdog \n"); - SPIT_Message::WatchdogAnswer* o_WatchdogAnswer; - o_WatchdogAnswer = new SPIT_Message::WatchdogAnswer(); - fillHeader(o_WatchdogAnswer->getHeader()); + SPIT_Message::WatchdogAnswer o_WatchdogAnswer; + fillHeader(o_WatchdogAnswer.getHeader()); int intResult; intResult = sendSPITMessage(o_WatchdogAnswer); if (intResult < 0) { @@ -615,16 +590,16 @@ void SPIT_Client::parseWatchdog(SPIT_Message::Watchdog* p_Watchdog) { * @param p_Watchdog */ void SPIT_Client::parseWatchdogAnswer(SPIT_Message::WatchdogAnswer* p_WatchdogAnswer) { - m_Watchdog->answerWatchdog(); //is also done by parseSPIT_Message + answerWatchdog();; //is also done by parseSPIT_Message } void SPIT_Client::sendWatchdog() { int intResult; - SPIT_Message::Watchdog* ptrSMWatchdog; - ptrSMWatchdog = new SPIT_Message::Watchdog(); - fillHeader(ptrSMWatchdog->getHeader()); - intResult = sendSPITMessage(ptrSMWatchdog); - if (intResult < 0) { - } + SPIT_Message::Watchdog sMWatchdog; + fillHeader(sMWatchdog.getHeader()); + intResult = sendSPITMessage(sMWatchdog); + if (intResult < 0) { + ESP_LOGW("WDT", "Failed to send Watchdog msg"); + } } void SPIT_Client::eventWatchdogLost() { disconnectInternal(CONNECTION_LOST); @@ -636,13 +611,7 @@ void SPIT_Client::parseReportSPITProject(SPIT_Message::ReportSPITProject* p_Repo m_ServerProjectID = p_ReportSPITProject->getProjectID(); m_ServerProjectName = p_ReportSPITProject->getProjectName(); m_ServerFramesPerSecond = p_ReportSPITProject->getFramesPerSecond(); - /* - function o_Callable = bind(&SPIT_Client::notifyReportProject, this); - SPIT_Handler::addCallable(o_Callable); - */ - - NotifyReportProject* o_Runnable = new NotifyReportProject(m_SPITClientInterface, m_ServerProjectID, m_ServerProjectName, m_ServerFramesPerSecond); - SPIT_Handler::addRunnable(o_Runnable); + mCallbacks.onProjectReport(m_ServerProjectID, m_ServerProjectName, m_ServerFramesPerSecond); //Set all SPITTypes and SPITObjects confirmed = false SPITType::setConfirmedFalse(); @@ -650,63 +619,50 @@ void SPIT_Client::parseReportSPITProject(SPIT_Message::ReportSPITProject* p_Repo //Send RequestProjectTransfer - SPIT_Message::RequestProjectTransfer* ptrSMRequestProjectTransfer; - ptrSMRequestProjectTransfer = new SPIT_Message::RequestProjectTransfer(); - fillHeader(ptrSMRequestProjectTransfer->getHeader()); - if (sendSPITMessage(ptrSMRequestProjectTransfer) < 0) { + SPIT_Message::RequestProjectTransfer sMRequestProjectTransfer; + fillHeader(sMRequestProjectTransfer.getHeader()); + if (sendSPITMessage(sMRequestProjectTransfer) < 0) { printf("SPIT_Client::parseReportSPITProject could not send RequestProjectTransfer\n"); } //Send client's ReportSPITProject - SPIT_Message::ReportSPITProject* ptrSMReportSPITProject; - ptrSMReportSPITProject = new SPIT_Message::ReportSPITProject(); - fillHeader(ptrSMReportSPITProject->getHeader()); - ptrSMReportSPITProject->setProjectID(m_SPITClientInterface->getClientProjectID()); - ptrSMReportSPITProject->setProjectName(m_SPITClientInterface->getClientProjectName()); - ptrSMReportSPITProject->setFramesPerSecond(0); - if (sendSPITMessage(ptrSMReportSPITProject) < 0) { + SPIT_Message::ReportSPITProject sMReportSPITProject; + fillHeader(sMReportSPITProject.getHeader()); + sMReportSPITProject.setProjectID(m_ProjName); + sMReportSPITProject.setProjectName(m_ProjName); + sMReportSPITProject.setFramesPerSecond(0); + if (sendSPITMessage(sMReportSPITProject) < 0) { printf("SPIT_Client::parseReportSPITProject could not send Client's ReportSPITProject"); } } void SPIT_Client::parseCloseSPITProject(SPIT_Message::CloseSPITProject* p_CloseSPITProject) { // printf("parse CloseSPITProject \n"); - NotifyProjectClosed* o_Runnable = new NotifyProjectClosed(m_SPITClientInterface, p_CloseSPITProject->getProjectID()); - SPIT_Handler::addRunnable(o_Runnable); - SPITPlayer::clearPlayers(); + mCallbacks.onProjectClosed(p_CloseSPITProject->getProjectID()); } -string SPIT_Client::getServerProjectID() { - return m_ServerProjectID; -} -string SPIT_Client::getServerProjectName() { - return m_ServerProjectName; -} -int SPIT_Client::getServerFramesPerSecond() { - return m_ServerFramesPerSecond; -} +string SPIT_Client::getServerProjectID() { return m_ServerProjectID; } +string SPIT_Client::getServerProjectName() { return m_ServerProjectName; } +int SPIT_Client::getServerFramesPerSecond() { return m_ServerFramesPerSecond; } void SPIT_Client::parseRequestProjectTransfer(SPIT_Message::RequestProjectTransfer* p_RequestProjectTransfer) { // printf("parse RequestProjectTransfer \n"); int intResult; - SPIT_Message::StartProjectTransfer* ptrSMStartProjectTransfer; - SPIT_Message::EndProjectTransfer* ptrSMEndProjectTransfer; int intCount; SPITType* ptrSPITType; SPITObject* ptrSPITObject; //StartProjectTransfer - ptrSMStartProjectTransfer = new SPIT_Message::StartProjectTransfer(); - fillHeader(ptrSMStartProjectTransfer->getHeader()); - intResult = sendSPITMessage(ptrSMStartProjectTransfer); + SPIT_Message::StartProjectTransfer sMStartProjectTransfer; + fillHeader(sMStartProjectTransfer.getHeader()); + intResult = sendSPITMessage(sMStartProjectTransfer); if (intResult < 0) { return; } { //send all listes SPITTypes - fos::MutexGuard o_LockType(*SPITType::getMutex()); intCount = SPITType::getSPITTypeCount(); for (int i = 0; i < intCount; i++) { ptrSPITType = SPITType::getSPITType(i); @@ -717,8 +673,7 @@ void SPIT_Client::parseRequestProjectTransfer(SPIT_Message::RequestProjectTransf } { - fos::MutexGuard o_LockObject(*SPITObject::getMutex()); - intCount = SPITObject::getSPITObjectCount(); + intCount = SPITObject::getSPITObjectCount(); for (int i = 0; i < intCount; i++) { ptrSPITObject = SPITObject::getSPITObject(i); if (ptrSPITObject == NULL) break; @@ -728,25 +683,20 @@ void SPIT_Client::parseRequestProjectTransfer(SPIT_Message::RequestProjectTransf } //EndProjectTransfer - ptrSMEndProjectTransfer = new SPIT_Message::EndProjectTransfer(); - fillHeader(ptrSMEndProjectTransfer->getHeader()); - intResult = sendSPITMessage(ptrSMEndProjectTransfer); + SPIT_Message::EndProjectTransfer sMEndProjectTransfer; + fillHeader(sMEndProjectTransfer.getHeader()); + intResult = sendSPITMessage(sMEndProjectTransfer); if (intResult < 0) { } } void SPIT_Client::parseStartProjectTransfer(SPIT_Message::StartProjectTransfer* p_StartProjectTransfer) { -//printf("parse StartProjectTransfer \n"); - NotifyStartProjectTransfer* o_Runnable = new NotifyStartProjectTransfer(m_SPITClientInterface); - SPIT_Handler::addRunnable(o_Runnable); + mCallbacks.onStartProjectTransfer(); } void SPIT_Client::parseEndProjectTransfer(SPIT_Message::EndProjectTransfer* p_EndProjectTransfer) { -//printf("parse EndProjectTransfer \n"); - NotifyEndProjectTransfer* o_Runnable = new NotifyEndProjectTransfer(m_SPITClientInterface); - SPIT_Handler::addRunnable(o_Runnable); + mCallbacks.onEndProjectTransfer(); } - //----- SPIT Types ------ void SPIT_Client::parseReportSPITType(SPIT_Message::ReportSPITType* p_ReportSPITType) { // printf("parse ReportSPITType ID %s Name %s \n",p_ReportSPITType->getID(), p_ReportSPITType->getName()); @@ -755,7 +705,6 @@ void SPIT_Client::parseReportSPITType(SPIT_Message::ReportSPITType* p_ReportSPIT bool boolNew = false; { - fos::MutexGuard o_LockSPITType(*SPITType::getMutex()); if (p_ReportSPITType->getServerRemote() == false) { ptrSPITType = SPITType::getSPITType(p_ReportSPITType->getID()); if (ptrSPITType == NULL) { @@ -779,14 +728,13 @@ void SPIT_Client::parseReportSPITType(SPIT_Message::ReportSPITType* p_ReportSPIT //add or change SPITType if (ptrSPITType->getServerRemote() == false) { SPITType::addSPITType(ptrSPITType); + mCallbacks.onSpitType(boolNew, *ptrSPITType); } else { SPITType::addSPITTypeRemote(ptrSPITType); + mCallbacks.onSpitTypeRemote(boolNew, *ptrSPITType); } - - NotifyReportSPITType* o_Runnable = new NotifyReportSPITType(ptrSPITType->getServerRemote(), boolNew, m_SPITClientInterface, *ptrSPITType); - SPIT_Handler::addRunnable(o_Runnable); - + if (ptrSPITType != NULL) { if (ptrSPITType->setConfirmed(true) == true) { sendSPITTypeInternal(ptrSPITType); @@ -803,8 +751,6 @@ void SPIT_Client::parseRemoveSPITType(SPIT_Message::RemoveSPITType* p_RemoveSPIT stringSPITTypeID = p_RemoveSPITType->getID(); { - fos::MutexGuard o_LockSPITType(*SPITType::getMutex()); - ptrSPITType = SPITType::getSPITTypeRemote(stringSPITTypeID); if (ptrSPITType != NULL) { boolRemote = true; @@ -827,17 +773,15 @@ void SPIT_Client::parseRemoveSPITType(SPIT_Message::RemoveSPITType* p_RemoveSPIT return; } - NotifyRemoveSPITType* o_Runnable = new NotifyRemoveSPITType(boolRemote, m_SPITClientInterface, *ptrSPITType); - SPIT_Handler::addRunnable(o_Runnable); - if (boolRemote == false) { + mCallbacks.onSpitTypeRemoved(*ptrSPITType); SPITType::removeSPITType(ptrSPITType); } else { + mCallbacks.onSpitTypeRemoteRemoved(*ptrSPITType); SPITType::removeSPITTypeRemote(ptrSPITType); } delete ptrSPITType; - } } @@ -850,10 +794,9 @@ void SPIT_Client::parseRemoveSPITType(SPIT_Message::RemoveSPITType* p_RemoveSPIT */ int SPIT_Client::sendSPITTypeInternal(SPITType* p_SPITType) { if (p_SPITType == NULL) return -1; - SPIT_Message::ReportSPITType* ptrSMReportSPITType; - ptrSMReportSPITType = new SPIT_Message::ReportSPITType(); - p_SPITType->fillMessageOP(ptrSMReportSPITType); - fillHeader(ptrSMReportSPITType->getHeader()); + SPIT_Message::ReportSPITType ptrSMReportSPITType; + p_SPITType->fillMessageOP(&ptrSMReportSPITType); + fillHeader(ptrSMReportSPITType.getHeader()); return sendSPITMessage(ptrSMReportSPITType); } @@ -866,8 +809,6 @@ bool SPIT_Client::changeSPITType(SPITType* p_SPITType) { if (p_SPITType == NULL) return false; SPITType* ptrSPITType; { - fos::MutexGuard o_LockType(*SPITType::getMutex()); - ptrSPITType = SPITType::getSPITType(p_SPITType->getID()); if (ptrSPITType == NULL) return false; @@ -878,9 +819,7 @@ bool SPIT_Client::changeSPITType(SPITType* p_SPITType) { ptrSPITType->setName(p_SPITType->getName()); ptrSPITType->setProjectIndepended(p_SPITType->getProjectIndepended()); - NotifyReportSPITType* o_Runnable = new NotifyReportSPITType(false, false, m_SPITClientInterface, *ptrSPITType); - SPIT_Handler::addRunnable(o_Runnable); - + mCallbacks.onSpitType(false, *ptrSPITType); sendSPITTypeInternal(ptrSPITType); } return true; @@ -897,21 +836,18 @@ bool SPIT_Client::changeSPITType(SPITType* p_SPITType) { int SPIT_Client::removeSPITType(string p_SPITTypeID) { if (p_SPITTypeID.length() <= 0) return -1; SPITType* ptrSPITType; - SPIT_Message::RemoveSPITType* ptrSMRemoveSPITType; { - fos::MutexGuard o_LockType(*SPITType::getMutex()); - ptrSPITType = SPITType::getSPITType(p_SPITTypeID); if (ptrSPITType == NULL) return -1; - ptrSMRemoveSPITType = new SPIT_Message::RemoveSPITType(); - ptrSPITType->fillMessageOP(ptrSMRemoveSPITType); - fillHeader(ptrSMRemoveSPITType->getHeader()); - NotifyRemoveSPITType* o_Runnable = new NotifyRemoveSPITType(false, m_SPITClientInterface, *ptrSPITType); - SPIT_Handler::addRunnable(o_Runnable); + SPIT_Message::RemoveSPITType sMRemoveSPITType; + ptrSPITType->fillMessageOP(&sMRemoveSPITType); + fillHeader(sMRemoveSPITType.getHeader()); + mCallbacks.onSpitTypeRemoved(*ptrSPITType); SPITType::removeSPITType(ptrSPITType); delete ptrSPITType; + return sendSPITMessage(sMRemoveSPITType); } - return sendSPITMessage(ptrSMRemoveSPITType); + return -1; } @@ -923,8 +859,6 @@ SPITType* SPIT_Client::createSPITType(string p_ID, string p_GroupName, string p_ SPITType* ptrSPITType; bool boolNew; { - fos::MutexGuard o_LockType(*SPITType::getMutex()); - ptrSPITType = SPITType::getSPITType(p_ID); if (ptrSPITType == NULL) { ptrSPITType = new SPITType(p_ID, p_GroupName, p_Name, p_FIxed, p_ProjectIndepended, p_DefaultDelay, p_DefaultDuration); @@ -943,15 +877,10 @@ SPITType* SPIT_Client::createSPITType(string p_ID, string p_GroupName, string p_ } } SPITType::addSPITType(ptrSPITType); - NotifyReportSPITType* o_Runnable = new NotifyReportSPITType(false, boolNew, m_SPITClientInterface, *ptrSPITType); - SPIT_Handler::addRunnable(o_Runnable); + mCallbacks.onSpitType(boolNew, *ptrSPITType); sendSPITTypeInternal(ptrSPITType); return ptrSPITType; -} - - - - +} //----- SPIT Objects ------ void SPIT_Client::parseReportSPITObject(SPIT_Message::ReportSPITObject* p_ReportSPITObject) { @@ -962,12 +891,7 @@ void SPIT_Client::parseReportSPITObject(SPIT_Message::ReportSPITObject* p_Report SPITType* ptrSPITType; bool boolNew = false; bool boolRemote = false; - - { - fos::MutexGuard o_LockSPITObject(*SPITObject::getMutex()); - fos::MutexGuard o_LockSPITType(*SPITType::getMutex()); - if (p_ReportSPITObject->getServerRemote() == false) { boolRemote = false; ptrSPITObject = SPITObject::getSPITObject(p_ReportSPITObject->getID()); @@ -999,9 +923,13 @@ void SPIT_Client::parseReportSPITObject(SPIT_Message::ReportSPITObject* p_Report SPITObject::addSPITObjectRemote(ptrSPITObject); } - NotifyReportSPITObject* o_Runnable = new NotifyReportSPITObject(boolRemote, boolNew, m_SPITClientInterface, *ptrSPITType, *ptrSPITObject); - SPIT_Handler::addRunnable(o_Runnable); - + if (boolRemote) { + mCallbacks.onSpitObjectRemote(boolNew, *ptrSPITType, *ptrSPITObject); + } + else { + mCallbacks.onSpitObject(boolNew, *ptrSPITType, *ptrSPITObject); + } + if (ptrSPITObject->setConfirmed(true) == true) { //Confirmation has changed sendSPITObjectInternal(ptrSPITObject); @@ -1016,18 +944,18 @@ void SPIT_Client::parseRemoveSPITObject(SPIT_Message::RemoveSPITObject* p_Remove SPITObject* ptrSPITObject; SPITType* ptrSPITType; - { - fos::MutexGuard o_LockSPITObject(*SPITObject::getMutex()); - fos::MutexGuard o_LockSPITType(*SPITType::getMutex()); - ptrSPITObject = SPITObject::getSPITObjectRemote(p_RemoveSPITObject->getID()); if (ptrSPITObject != NULL) { boolRemote = true; ptrSPITType = SPITType::getSPITTypeRemote(ptrSPITObject->getSPITTypeID()); if (ptrSPITType != NULL) { - NotifyRemoveSPITObject* o_Runnable = new NotifyRemoveSPITObject(boolRemote, m_SPITClientInterface, *ptrSPITType, *ptrSPITObject); - SPIT_Handler::addRunnable(o_Runnable); + if (boolRemote) { + mCallbacks.onSpitObjectRemoteRemoved(*ptrSPITType, *ptrSPITObject); + } + else { + mCallbacks.onSpitObjectRemoved(*ptrSPITType, *ptrSPITObject); + } } else { //No associated SPITType found @@ -1041,47 +969,14 @@ void SPIT_Client::parseRemoveSPITObject(SPIT_Message::RemoveSPITObject* p_Remove removeSPITObject(p_RemoveSPITObject->getID()); } -/* ptrSPITObject = SPITObject::getSPITObjectRemote(p_RemoveSPITObject->getID()); - if (ptrSPITObject != NULL) { - boolRemote = true; - ptrSPITType = SPITType::getSPITTypeRemote(ptrSPITObject->getSPITTypeID()); - } - else { - ptrSPITObject = SPITObject::getSPITObject(p_RemoveSPITObject->getID()); - if (ptrSPITObject != NULL) { - boolRemote = false; - ptrSPITType = SPITType::getSPITType(ptrSPITObject->getSPITTypeID()); - } - else { - return; - } - } - if (ptrSPITType != NULL) { - NotifyRemoveSPITObject* o_Runnable = new NotifyRemoveSPITObject(boolRemote, m_SPITClientInterface, *ptrSPITType, *ptrSPITObject); - SPIT_Handler::addRunnable(o_Runnable); - } - else { - //No associated SPITType found - //delete the SPITObject without a notification - } - - if (boolRemote == false) { - SPITObject::removeSPITObject(ptrSPITObject); - } - else { - SPITObject::removeSPITObjectRemote(ptrSPITObject); - } - delete ptrSPITObject; -*/ } } int SPIT_Client::sendSPITObjectInternal(SPITObject* ptrSPITObject) { if (ptrSPITObject == NULL) return -1; - SPIT_Message::ReportSPITObject* ptrSMReportSPITObject; - ptrSMReportSPITObject = new SPIT_Message::ReportSPITObject(); - ptrSPITObject-> fillMessageOP(ptrSMReportSPITObject); - fillHeader(ptrSMReportSPITObject->getHeader()); + SPIT_Message::ReportSPITObject ptrSMReportSPITObject; + ptrSPITObject->fillMessageOP(&ptrSMReportSPITObject); + fillHeader(ptrSMReportSPITObject.getHeader()); return sendSPITMessage(ptrSMReportSPITObject); } @@ -1098,9 +993,6 @@ bool SPIT_Client::changeSPITObject(SPITObject* p_SPITObject) { SPITObject* ptrSPITObject; SPITType* ptrSPITType; { - fos::MutexGuard o_LockObject(*SPITObject::getMutex()); - fos::MutexGuard o_LockType(*SPITType::getMutex()); - ptrSPITObject = SPITObject::getSPITObject(p_SPITObject->getID()); if (ptrSPITObject == NULL) return false; ptrSPITType = SPITType::getSPITType(p_SPITObject->getID()); @@ -1122,9 +1014,7 @@ bool SPIT_Client::changeSPITObject(SPITObject* p_SPITObject) { ptrSPITObject->setValueFactor(p_SPITObject->getValueFactor()); ptrSPITObject->setValueUse(p_SPITObject->getValueUse()); - NotifyReportSPITObject* o_Runnable = new NotifyReportSPITObject(false, false, m_SPITClientInterface, *ptrSPITType, *ptrSPITObject); - SPIT_Handler::addRunnable(o_Runnable); - + mCallbacks.onSpitObject(false, *ptrSPITType, *ptrSPITObject); sendSPITObjectInternal(ptrSPITObject); } return true; @@ -1143,25 +1033,21 @@ int SPIT_Client::removeSPITObject(string p_SPITObjectID) { if (p_SPITObjectID.length() <= 0) return -1; SPITType* ptrSPITType; SPITObject* ptrSPITObject; - SPIT_Message::RemoveSPITObject* ptrSMRemoveSPITObject; { - fos::MutexGuard o_LockObject(*SPITObject::getMutex()); - fos::MutexGuard o_LockType(*SPITType::getMutex()); - + SPIT_Message::RemoveSPITObject sMRemoveSPITObject; ptrSPITObject = SPITObject::getSPITObject(p_SPITObjectID); if (ptrSPITObject == NULL) return -1; ptrSPITType = SPITType::getSPITType(ptrSPITObject->getSPITTypeID()); if (ptrSPITType == NULL) return -1; - ptrSMRemoveSPITObject = new SPIT_Message::RemoveSPITObject(); - ptrSPITObject->fillMessageOP(ptrSMRemoveSPITObject); - fillHeader(ptrSMRemoveSPITObject->getHeader()); - NotifyRemoveSPITObject* o_Runnable = new NotifyRemoveSPITObject(false, m_SPITClientInterface, *ptrSPITType, *ptrSPITObject); - SPIT_Handler::addRunnable(o_Runnable); + ptrSPITObject->fillMessageOP(&sMRemoveSPITObject); + fillHeader(sMRemoveSPITObject.getHeader()); + mCallbacks.onSpitObjectRemoved(*ptrSPITType, *ptrSPITObject); SPITObject::removeSPITObject(ptrSPITObject); delete ptrSPITObject; + return sendSPITMessage(sMRemoveSPITObject); } - return sendSPITMessage(ptrSMRemoveSPITObject); + return -1; } @@ -1171,7 +1057,6 @@ void SPIT_Client::parsePlaySPITStart(SPIT_Message::PlaySPITStart* p_PlaySPITStar // printf("parse PlaySPITStart ID: %s Name: %s Running: %d\n", p_PlaySPITStart->getPlayerID(), p_PlaySPITStart->getPlayerName(), p_PlaySPITStart->getPlayerIsRunning()); SPITPlayer* ptrSPITPlayer; { - fos::MutexGuard o_LockSPITPlayer(*SPITPlayer::getMutex()); ptrSPITPlayer = SPITPlayer::getSPITPlayer(p_PlaySPITStart->getPlayerID()); if (ptrSPITPlayer == NULL) return; ptrSPITPlayer->setIsRunning(p_PlaySPITStart->getPlayerIsRunning()); @@ -1180,8 +1065,7 @@ void SPIT_Client::parsePlaySPITStart(SPIT_Message::PlaySPITStart* p_PlaySPITStar ptrSPITPlayer->setTime(p_PlaySPITStart->getTime()); ptrSPITPlayer->startPlaySequence(); - NotifyPlaySPITStart* o_Runnable = new NotifyPlaySPITStart(m_SPITClientInterface, ptrSPITPlayer->getID(), ptrSPITPlayer->getName(), ptrSPITPlayer->getType(), ptrSPITPlayer->getIsRunning(), ptrSPITPlayer->getTime()); - SPIT_Handler::addRunnable(o_Runnable); + mCallbacks.onPlay(ptrSPITPlayer->getID(), ptrSPITPlayer->getName(), ptrSPITPlayer->getType(), ptrSPITPlayer->getIsRunning(), ptrSPITPlayer->getTime()); } } void SPIT_Client::parsePlaySPITObject(SPIT_Message::PlaySPITObject* p_PlaySPITObject) { @@ -1189,17 +1073,14 @@ void SPIT_Client::parsePlaySPITObject(SPIT_Message::PlaySPITObject* p_PlaySPITOb SPITPlayer* ptrSPITPlayer; SPITPlayer::PlayObject* ptrPlayObject; SPITObject* ptrSPITObject; - { - fos::MutexGuard o_LockSPITPlayer(*SPITPlayer::getMutex()); - ptrSPITPlayer = SPITPlayer::getSPITPlayer(p_PlaySPITObject->getPlayerID()); if (ptrSPITPlayer == NULL) return; ptrPlayObject = ptrSPITPlayer->addSPITObject_Playing(p_PlaySPITObject->getSPITObjectID()); //Fetch infoemations from SPITObject { - fos::MutexGuard o_LockSPITObject(*SPITObject::getMutex()); + ptrSPITObject = SPITObject::getSPITObject(p_PlaySPITObject->getSPITObjectID()); if (ptrSPITObject == NULL) { @@ -1224,8 +1105,7 @@ void SPIT_Client::parsePlaySPITEnd(SPIT_Message::PlaySPITEnd* p_PlaySPITEnd) { SPITObject* ptrSPITObject = NULL; { - fos::MutexGuard o_LockSPITPlayer(*SPITPlayer::getMutex()); - + ptrSPITPlayer = SPITPlayer::getSPITPlayer(p_PlaySPITEnd->getPlayerID()); if (ptrSPITPlayer == NULL) return; @@ -1246,9 +1126,6 @@ void SPIT_Client::parsePlaySPITEnd(SPIT_Message::PlaySPITEnd* p_PlaySPITEnd) { boolStopped = true; } { - fos::MutexGuard o_LockSPITObject(*SPITObject::getMutex()); - fos::MutexGuard o_LockSPITType(*SPITType::getMutex()); - ptrSPITObject = SPITObject::getSPITObject(ptrPlayObject->getSPITObjectID()); if (ptrSPITObject == NULL) { return; @@ -1257,9 +1134,8 @@ void SPIT_Client::parsePlaySPITEnd(SPIT_Message::PlaySPITEnd* p_PlaySPITEnd) { if (ptrSPITType == NULL) { return; } - NotifyPlaySPITObject* o_Runnable = new NotifyPlaySPITObject(boolStarted, boolStopped, m_SPITClientInterface, - *ptrSPITType, *ptrSPITObject, *ptrPlayObject); - SPIT_Handler::addRunnable(o_Runnable); + + mCallbacks.onPlayObject(ptrPlayObject->getPlayerID(), boolStarted, boolStopped, *ptrSPITType, *ptrSPITObject, *ptrPlayObject); } } ptrSPITPlayer->endPlaySequence(); @@ -1272,8 +1148,7 @@ void SPIT_Client::parseReportPlayStatus(SPIT_Message::ReportPlayStatus* p_Report SPITType* ptrSPITType = NULL; SPITObject* ptrSPITObject = NULL; { - fos::MutexGuard o_LockSPITObject(*SPITObject::getMutex()); - fos::MutexGuard o_LockSPITType(*SPITType::getMutex()); + ptrSPITObject = SPITObject::getSPITObjectRemote(p_ReportPlayStatus->getID()); if (ptrSPITObject == NULL) { @@ -1283,8 +1158,7 @@ void SPIT_Client::parseReportPlayStatus(SPIT_Message::ReportPlayStatus* p_Report if (ptrSPITType == NULL) { return; } - NotifyReportPlayStatus* o_Runnable = new NotifyReportPlayStatus(m_SPITClientInterface, *ptrSPITType, *ptrSPITObject, p_ReportPlayStatus->getFrameInsideObject(), p_ReportPlayStatus->getValue()); - SPIT_Handler::addRunnable(o_Runnable); + mCallbacks.onPlayRemoteObjectStatus(*ptrSPITType, *ptrSPITObject, p_ReportPlayStatus->getFrameInsideObject(), p_ReportPlayStatus->getValue()); } } @@ -1306,39 +1180,137 @@ void SPIT_Client::parseReportPlayStatus(SPIT_Message::ReportPlayStatus* p_Report */ void SPIT_Client::sendRemoteObject(string p_SPITObjectID, int p_Valueppm, char p_ValueFlag) { SPITObject* ptrRemoteSPITObject; - SPIT_Message::PlaySPITStart* ptrPlaySPITStart; - SPIT_Message::PlaySPITObject* ptrPlaySPITObject; - SPIT_Message::PlaySPITEnd* ptrPlaySPITEnd; - { - fos::MutexGuard o_LockRemote(*SPITObject::getMutex()); - ptrRemoteSPITObject = SPITObject::getSPITObjectRemote(p_SPITObjectID); if (ptrRemoteSPITObject == NULL) return; - ptrPlaySPITStart = new SPIT_Message::PlaySPITStart(); - fillHeader(ptrPlaySPITStart->getHeader()); - ptrPlaySPITStart->setPlayerID(m_ID); - ptrPlaySPITStart->setPlayerName(m_SPITClientInterface->getClientProjectName()); - ptrPlaySPITStart->setPlayerIsRunning(false); - ptrPlaySPITStart->setPlayerType(PLAYERTYPE_DISCRETE); - ptrPlaySPITStart->setTime(0); - sendSPITMessage(ptrPlaySPITStart); + SPIT_Message::PlaySPITStart playSPITStart; + fillHeader(playSPITStart.getHeader()); + playSPITStart.setPlayerID(m_ID); + playSPITStart.setPlayerName(m_ProjName); + playSPITStart.setPlayerIsRunning(false); + playSPITStart.setPlayerType(PLAYERTYPE_DISCRETE); + playSPITStart.setTime(0); + sendSPITMessage(playSPITStart); - ptrPlaySPITObject = new SPIT_Message::PlaySPITObject(); - fillHeader(ptrPlaySPITObject->getHeader()); - ptrPlaySPITObject->setID(ptrRemoteSPITObject->getID()); - ptrPlaySPITObject->setPlayPrePosition(false); - ptrPlaySPITObject->setPlayerID(m_ID); - ptrPlaySPITObject->setValue(p_Valueppm); - ptrPlaySPITObject->setValueFlag(p_ValueFlag); - sendSPITMessage(ptrPlaySPITObject); - - ptrPlaySPITEnd = new SPIT_Message::PlaySPITEnd(); - fillHeader(ptrPlaySPITEnd->getHeader()); - ptrPlaySPITEnd->setPlayerID(m_ID); - sendSPITMessage(ptrPlaySPITEnd); + SPIT_Message::PlaySPITObject playSPITObject; + fillHeader(playSPITObject.getHeader()); + playSPITObject.setID(ptrRemoteSPITObject->getID()); + playSPITObject.setPlayPrePosition(false); + playSPITObject.setPlayerID(m_ID); + playSPITObject.setValue(p_Valueppm); + playSPITObject.setValueFlag(p_ValueFlag); + sendSPITMessage(playSPITObject); + SPIT_Message::PlaySPITEnd playSPITEnd; + fillHeader(playSPITEnd.getHeader()); + playSPITEnd.setPlayerID(m_ID); + sendSPITMessage(playSPITEnd); } } +fos::Semaphore SPIT_Client::sStartSad; + +void SPIT_Client::processSocketTask(SPIT_Client & instance) { + ESP_LOGI(TAG, "Starting Socket managing"); + +static const string SERVERAUTODETECT_PRECODE = "#SAD#"; +static const string SERVERAUTODETECT_SEPERATOR = "#,#"; +static const string SERVERAUTODETECT_TASKID = "#spit#"; // -> "#SAD##,##spit#" +static const string SERVERAUTODETECT_PORT = "15110"; +static constexpr int WATCHDOGTIME = 3000; + + string stringDatagram = SERVERAUTODETECT_PRECODE + SERVERAUTODETECT_SEPERATOR + SERVERAUTODETECT_TASKID; + int intDatagramLength = stringDatagram.length(); + string stringPart; + string stringParts[9]; + + while (true) { + sStartSad.take(); + bool searching = true; + instance.mSPITSocket->setBroadcast(true); + while (searching) { + if (instance.abortSearch) + break; + + SAD_DetectedServer::cycleStart(); + string stringBroadcastIP4 = instance.mSPITSocket->mOwnIp.getBroadcastIP4(); + instance.mSPITSocket->sendMessageTo(SPITSocket::FAMILY_IP4, stringBroadcastIP4, SERVERAUTODETECT_PORT, stringDatagram.data(), intDatagramLength); + { + // wait for 3000 milliseconds or + fos::Task::delayMs(3000); + } + + bool receiving = true; + while (receiving) { + if (instance.abortSearch) + break; + + char buffer[512 + 1]; + string stringServerIP; + int intReceivedByteCount = instance.mSPITSocket->receiveMessage(SPITSocket::FAMILY_IP4, buffer, 512, &stringServerIP); + if (intReceivedByteCount <= 0) { + break; + } + + // add null chararcter + if (intReceivedByteCount < 512) { + buffer[intReceivedByteCount] = '\0'; + } else { + buffer[512] = '\0'; + } + string stringMessage = buffer; + // Check if precode is ok + if (stringMessage.find(SERVERAUTODETECT_PRECODE.data(), 0) != 0) { + return; + } + int intIndex = 0; + int intOldPos = 0; + while (intIndex < 8) { + int intPos = stringMessage.find(SERVERAUTODETECT_SEPERATOR.data(), intOldPos); + if (intPos == string::npos) { + stringPart = ""; + } else { + stringPart = stringMessage.substr(intOldPos, intPos - intOldPos); + intOldPos = intPos + SERVERAUTODETECT_SEPERATOR.length(); + } + stringParts[intIndex] = stringPart; + intIndex++; + } + stringParts[8] = stringServerIP; + SAD_DetectedServer::addDetectedServer(true, stringParts[SAD_DetectedServer::PARAMINDEX_ID], stringParts); + } + fos::Task::delayMs(100); + SAD_DetectedServer::cycleEnd(instance); + + instance.abortSearch = false; + // if(instance.m_ConnectionStatus == CONNECTION_OK) break; + fos::Task::delayMs(1000); + } + instance.mSPITSocket->setBroadcast(false); + + ESP_LOGW(TAG, "Finished searching"); + ESP_LOGW(TAG, "Start working"); + auto nextWdTrigger = fos::Timing::getMilliSec() + WATCHDOGTIME; + auto nextWdCheck = nextWdTrigger + WATCHDOGTIME; + while (true) { + auto time = fos::Timing::getMilliSec(); + if (time > nextWdTrigger) { + instance.sAnswered = false; + instance.sendWatchdog(); + nextWdTrigger = nextWdCheck + WATCHDOGTIME; + } + + if (time > nextWdCheck) { + if (!instance.sAnswered) { + ESP_LOGW(TAG, "TimeOut"); + instance.eventWatchdogLost(); + break; + } + nextWdCheck = nextWdTrigger + WATCHDOGTIME; + } + fos::Task::delayMs(25); + if(instance.m_StopReceiveSPITMessages) break; + } + } +} \ No newline at end of file diff --git a/components/spit/src/SPIT_Handler.cpp b/components/spit/src/SPIT_Handler.cpp deleted file mode 100644 index fceb0d2..0000000 --- a/components/spit/src/SPIT_Handler.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * SPITHandler lists runnable instances and processes them in order. - * File: SPIT_Handler.cpp - * Author: Hagi - * - * Created on 24. April 2019, 11:18 - */ - -#include "SPIT_Handler.h" -#include "esp_log.h" - -fos::Mutex SPIT_Handler::s_MutexLock; -fos::Semaphore SPIT_Handler::s_ConditionVariable(1000); -list SPIT_Handler::s_Runnables; -bool SPIT_Handler::s_Close = false; -fos::Task* SPIT_Handler::s_HandlerThread = nullptr; -SPIT_Handler::Runnable::~Runnable() {} - - -void SPIT_Handler::addRunnable(Runnable* p_Runnable) { - if(s_HandlerThread == nullptr) { - s_HandlerThread = new fos::Task(SPIT_Handler::run, "spitHandler"); - } - - if (p_Runnable == NULL) return; - { - fos::MutexGuard o_Unique_Lock(s_MutexLock); - if (s_Close == true) return; - s_Runnables.push_back(p_Runnable); - } - s_ConditionVariable.give(); -} - -void SPIT_Handler::closeHandler() { - if (s_Close == true) return; - { - fos::MutexGuard o_Unique_Lock(s_MutexLock); - if (s_Close == true) return; - - s_Close = true; - } - s_ConditionVariable.give(); -} -void SPIT_Handler::run() { - Runnable* o_Runnable; - bool boolWait = false; - while (s_Close == false) { - boolWait = false; - { - fos::MutexGuard o_Lock(s_MutexLock); - - if (s_Runnables.empty()) { - s_ConditionVariable.take(); - } - if (s_Close == true) { - return; - } - - if (s_Runnables.empty()) { - continue; - } - else { - o_Runnable = s_Runnables.front(); - s_Runnables.erase(s_Runnables.begin()); - } - } - - if (o_Runnable != NULL) { - try { - o_Runnable->run(); - delete o_Runnable; - } - catch(...) { - ESP_LOGW("SPIT", "ERROR SPITHandler o_Runable->run()"); - } - } - } -} diff --git a/components/spit/src/UnixSocket.cpp b/components/spit/src/UnixSocket.cpp deleted file mode 100644 index daa7542..0000000 --- a/components/spit/src/UnixSocket.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * Unix implementation of a SPITSocket. - * - * File: UnixSocket.cpp - * Author: Hagi - * - * Created on 12. April 2019, 15:58 - */ - - - -#include "_SPITMACROS.h" -#include "UnixSocket.h" -#include "esp_netif.h" -#include "esp_log.h" -#include "Task.hpp" - - -UnixSocket::UnixSocket() : SPITSocket(){ - SPITSocket::FAMILY_IP4 = AF_INET; - SPITSocket::FAMILY_IP6 = AF_INET6; - m_UDPSocketIP4 = INVALID_SOCKET; - m_UDPSocketIP6 = INVALID_SOCKET; - createSocket_UDP(); -} - - -UnixSocket::~UnixSocket() { - - int intResultIP4; - int intResultIP6; - if (m_UDPSocketIP4 != INVALID_SOCKET) { -// intResultIP4 = shutdown(m_UDPSocketIP4, 2); - intResultIP4 = close(m_UDPSocketIP4); - m_UDPSocketIP4 = INVALID_SOCKET; - } - if (m_UDPSocketIP6 != INVALID_SOCKET) { -// intResultIP6 = shutdown(m_UDPSocketIP6, 2); - intResultIP6 = close(m_UDPSocketIP6); - m_UDPSocketIP6 = INVALID_SOCKET; - } - fos::Task::delayMs(100); -} - -int UnixSocket::init() { - return 0; -} - -int UnixSocket::cleanUp() { - return 0; -} - -/** - * Creates two new sockets.
- * One socket for IP4 and one for IP6.
- * If there exist some, they will be closed.
- * @return - */ -bool UnixSocket::createSocket_UDP() { - bool boolSuccess = true; - int intResult = -1; - int intOptionValue4 = 1; - int intOptionValue6 = 1; - u_char charOptionValue = 0x01; - - //ip4 - if (m_UDPSocketIP4 != INVALID_SOCKET) { - close(m_UDPSocketIP4); - m_UDPSocketIP4 = INVALID_SOCKET; - } - if (m_UDPSocketIP6 != INVALID_SOCKET) { - close(m_UDPSocketIP6); - m_UDPSocketIP6 = INVALID_SOCKET; - } - - - m_UDPSocketIP4 = socket(AF_INET,SOCK_DGRAM, 0); - if (m_UDPSocketIP4 == INVALID_SOCKET) { - boolSuccess = false; - } - else { - intResult = setsockopt(m_UDPSocketIP4, SOL_SOCKET, SO_REUSEADDR, (void*)&intOptionValue4, sizeof(intOptionValue4)); - } - - m_UDPSocketIP6 = socket(AF_INET6,SOCK_DGRAM, 0); - if (m_UDPSocketIP6 == INVALID_SOCKET) { - boolSuccess = false; - close(m_UDPSocketIP4); - m_UDPSocketIP4 = INVALID_SOCKET; - } - else { - intResult = setsockopt(m_UDPSocketIP6, SOL_SOCKET, SO_REUSEADDR, (void*)&intOptionValue6, sizeof(intOptionValue6)); - } - //set the m_UDPSocketIP4 and m_UDPSocketIP6 in NON BLOCKING mode because - //if the UDPSockets are in blocking mode the receiveMessage does not return in every constellation - int intFlags; - intFlags = fcntl(m_UDPSocketIP4, F_GETFL); - fcntl(m_UDPSocketIP4, F_SETFL, intFlags | O_NONBLOCK); - intFlags = fcntl(m_UDPSocketIP6, F_GETFL); - fcntl(m_UDPSocketIP6, F_SETFL, intFlags | O_NONBLOCK); - - if (intResult < 0) { - boolSuccess = false; - } - return boolSuccess; -} - -/** - * Binds the socket to the client's ip address and port.
- * The socket option SO_REUSEADDR is set to true.
- * @param p_ClientIP ip address of the client - * @param p_ClientPort port of the client.
- * if p_Port == "0" any free port will be used
- * @return -1 id bind fails, o if bind is ok - * - */ -int UnixSocket::bindSocket(string p_ClientIP, string p_ClientPort) { - addrinfo *clientAI; - struct sockaddr_in* ptrIP4SocketAddress; - struct sockaddr_in o_IP4SocketAddress; - struct sockaddr_in6* ptrIP6SocketAddress; - struct sockaddr_in6 o_IP6SocketAddress; - int intSocklen; - string stringClientPort; - if (p_ClientPort.length() <= 0) stringClientPort = "0"; - else stringClientPort = p_ClientPort; - //int intResult = SOCKET_ERROR; - int intResult = 0; - if (getaddrinfo(p_ClientIP.data(), p_ClientPort.data(), NULL, &clientAI) != 0) { - return -1; - } - switch(clientAI->ai_family) { - case AF_INET: - if (m_UDPSocketIP4 == INVALID_SOCKET) { - break; - } - ptrIP4SocketAddress = reinterpret_cast(clientAI->ai_addr); - intSocklen = sizeof (*ptrIP4SocketAddress); - //copy the ptrIP4SocketAddress, may be not filled correct by getaddrinfo - memset(&o_IP4SocketAddress, 0, intSocklen); - o_IP4SocketAddress.sin_addr = ptrIP4SocketAddress->sin_addr; - o_IP4SocketAddress.sin_family = ptrIP4SocketAddress->sin_family; - //o_IP4SocketAddress.sin_zero = ptrIP4SocketAddress->sin_zero; - o_IP4SocketAddress.sin_port = ptrIP4SocketAddress->sin_port; - intResult = bind(m_UDPSocketIP4, (const sockaddr*)(ptrIP4SocketAddress),(socklen_t)intSocklen); - if (intResult < 0) { - break; - } - setBoundClientFamily(AF_INET); - if (intResult == 0) { - if (getsockname(m_UDPSocketIP4, (sockaddr*)ptrIP4SocketAddress, (socklen_t*)&intSocklen) != -1) { - setBoundClientPort(to_string((int)ptrIP4SocketAddress->sin_port)); - } - } - break; - case AF_INET6: - if (m_UDPSocketIP6 == INVALID_SOCKET) { - break; - } - ptrIP6SocketAddress = reinterpret_cast(clientAI->ai_addr); - intSocklen = sizeof (*ptrIP6SocketAddress); - //copy the ptrIP6SocketAddress, may be not filled correct by getaddrinfo - o_IP6SocketAddress.sin6_addr = ptrIP6SocketAddress->sin6_addr; - o_IP6SocketAddress.sin6_family = ptrIP6SocketAddress->sin6_family; - o_IP6SocketAddress.sin6_flowinfo = ptrIP6SocketAddress->sin6_flowinfo; - o_IP6SocketAddress.sin6_port = ptrIP6SocketAddress->sin6_port; - o_IP6SocketAddress.sin6_scope_id = ptrIP6SocketAddress->sin6_scope_id; - intResult = bind(m_UDPSocketIP6, (const sockaddr*)(ptrIP6SocketAddress), (socklen_t)intSocklen); - if (intResult < 0) { - break; - } - setBoundClientFamily(AF_INET6); - - if (intResult == 0) { - if (getsockname(m_UDPSocketIP6, (sockaddr*)ptrIP6SocketAddress, (socklen_t*)&intSocklen) != -1) { - setBoundClientPort(to_string((int)ptrIP6SocketAddress->sin6_port)); - } - } - break; - default: - setBoundClientFamily(0); - intResult = -1; - break; - } - freeaddrinfo(clientAI); - - if (intResult == -1) { - setIsBound(false); - } - else { - setIsBound(true); - } - return intResult; -} - -/** - * Set the sockopt SO_BROADCAST to 0 or 1 - * @param p_Broadcast true SO_BROADCAST is set
- * false = SO_BROADCAST is not set - * @return 0 = ok, -1 = error - */ -int UnixSocket::setBroadcast(bool p_Broadcast) { - int intResult; - int intOptionValue = 1; - u_char charOptionValue = 0x01; - //IP4 - if (p_Broadcast) { - intOptionValue = 1; - } - else { - intOptionValue = 0; - } - intResult = setsockopt(m_UDPSocketIP4, SOL_SOCKET, SO_BROADCAST, &intOptionValue, sizeof(int)); -// intResult = setsockopt(m_UDPSocketIP4, IPPROTO_IP, IP_MULTICAST_LOOP, (void*)&charOptionValue, sizeof(charOptionValue)); - - //IP6 -// intResult = setsockopt(m_UDPSocketIP6, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (void*)&charOptionValue, sizeof(charOptionValue)); - - return intResult; -} -/** - * - * @param p_InetFamily AF_INET or AF_INET6 - * @param p_ServerIP the ip address of the server - * @param p_ServerPort the port of the server - * @param p_MessageBytes buffer containing the message - * @param p_MessageLength the length of the message - * @return -1 send fails
- * 0 send is done - */ -int UnixSocket::sendMessageTo(int p_InetFamily, string p_ServerIP, string p_ServerPort, const char* p_MessageBytes, int p_MessageLength) { - if (m_UDPSocketIP4 == INVALID_SOCKET && m_UDPSocketIP6 == INVALID_SOCKET) return -1; - struct addrinfo* ptrAddressInfo; - struct sockaddr_in* ptrIP4SocketAddress; - struct sockaddr_in o_IP4SocketAddress; - struct sockaddr_in6* ptrIP6SocketAddress; - struct sockaddr_in6 o_IP6SocketAddress; - int intSocklen; - int intResult = -1; - - // prepare AddressInfo - if (getaddrinfo(p_ServerIP.data(), p_ServerPort.data(), NULL, &ptrAddressInfo) != 0) { - return -1; - } - switch(ptrAddressInfo->ai_family) { - case AF_INET: - ptrIP4SocketAddress = reinterpret_cast(ptrAddressInfo->ai_addr); - intSocklen = sizeof(*ptrIP4SocketAddress); - if (m_UDPSocketIP4 != INVALID_SOCKET) { - //copy the ptrIP4SocketAddress, may be not filled correct by getaddrinfo - memset(&o_IP4SocketAddress, 0, intSocklen); - o_IP4SocketAddress.sin_addr = ptrIP4SocketAddress->sin_addr; - o_IP4SocketAddress.sin_family = ptrIP4SocketAddress->sin_family; - o_IP4SocketAddress.sin_port = ptrIP4SocketAddress->sin_port; - intResult = sendto(m_UDPSocketIP4, p_MessageBytes, p_MessageLength, 0, (const sockaddr*)&o_IP4SocketAddress, (socklen_t)intSocklen); -if (intResult < 0) printf("UnixSocket::sendMessageTo IP4 sendto %s FAILED %s\n", p_ServerIP.data(), strerror(errno)); - freeaddrinfo(ptrAddressInfo); - } - break; - case AF_INET6: - ptrIP6SocketAddress = reinterpret_cast(ptrAddressInfo->ai_addr); - intSocklen = sizeof(*ptrIP6SocketAddress); - if (m_UDPSocketIP6 != INVALID_SOCKET) { - //copy the ptrIP6SocketAddress, may be not filled correct by getaddrinfo - o_IP6SocketAddress.sin6_addr = ptrIP6SocketAddress->sin6_addr; - o_IP6SocketAddress.sin6_family = ptrIP6SocketAddress->sin6_family; - o_IP6SocketAddress.sin6_flowinfo = ptrIP6SocketAddress->sin6_flowinfo; - o_IP6SocketAddress.sin6_port = ptrIP6SocketAddress->sin6_port; - o_IP6SocketAddress.sin6_scope_id = ptrIP6SocketAddress->sin6_scope_id; - intResult = sendto(m_UDPSocketIP6, p_MessageBytes, p_MessageLength, 0, (const sockaddr*)&o_IP6SocketAddress, (socklen_t)intSocklen); -if (intResult < 0) printf("UnixSocket::sendMessageTo IP6 sendto %s FAILED %s\n", p_ServerIP.data(), strerror(errno)); - freeaddrinfo(ptrAddressInfo); - } - break; - default: - intResult = -1; - } - - if (intResult == -1) { - return -1; - } - return 0; -} -/** - * Starts receiving a message - * @param p_InetFamily AF_INET or AF_INET6 - * @param p_Buffer a char* buffer large enough to hold the expected data - * @param p_BufferLength the length of the buffer - * @param p_ServerIP = NULL, the ip address is not determined
- * != NULL after receiving a message p_ServerID contains the ip address of the sender/server - * @return - */ -int UnixSocket::receiveMessage(int p_InetFamily, char* p_Buffer, int p_BufferLength, string* p_ServerIP) { - int intResult = -1; -// ADDRINFO *AI; - struct sockaddr_in o_IP4SocketAddress; - struct sockaddr_in6 o_IP6SocketAddress; - int intSocklen; - - switch(p_InetFamily) { - case AF_INET: - if (m_UDPSocketIP4 == INVALID_SOCKET) { - break; - } - intSocklen = sizeof(o_IP4SocketAddress); - memset(&o_IP4SocketAddress, 0, intSocklen); - intResult = recvfrom(m_UDPSocketIP4, (void*)p_Buffer, p_BufferLength, 0, (sockaddr*)&o_IP4SocketAddress, (socklen_t*)&intSocklen); - if (intResult >= 0) { - if (p_ServerIP != NULL) { - char bufferIP4[INET_ADDRSTRLEN]; - inet_ntop(AF_INET, &(o_IP4SocketAddress.sin_addr), bufferIP4, intSocklen); - *p_ServerIP = bufferIP4; - } - } - break; - case AF_INET6: - if (m_UDPSocketIP6 == INVALID_SOCKET) { - break; - } - intSocklen = sizeof(o_IP6SocketAddress); - memset(&o_IP6SocketAddress, 0, intSocklen); - intResult = recvfrom(m_UDPSocketIP6, (void*)p_Buffer, p_BufferLength, 0, (sockaddr*)&o_IP6SocketAddress, (socklen_t*)&intSocklen); - if (intResult >= 0) { - if (p_ServerIP != NULL) { - char bufferIP6[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &(o_IP6SocketAddress.sin6_addr), bufferIP6, intSocklen); - *p_ServerIP = bufferIP6; - } - } - break; - } - return intResult; -} - -/** - * Calculates the broadcast address from a ip4 address.
- * @param p_IPAddress the ip4 address - * @return returns the broadcast address - */ -string UnixSocket::getBroadcastIP4(SPITSocket::IPAddress* p_IPAddress) { - struct in_addr broadcast; - unsigned long ulIPAddress; - unsigned long ulSubnetMask; - - ulIPAddress = inet_addr(p_IPAddress->getIPAddress().data()); - ulSubnetMask = inet_addr(p_IPAddress->getSubnetMask().data()); - broadcast.s_addr = ulIPAddress | ~ulSubnetMask; - - return inet_ntoa(broadcast); -} - -void UnixSocket::getAdaptersInfo() { - resetFoundIPAddresses(); - // iterate over active interfaces, and print out IPs - esp_netif_t *netif = NULL; - while ((netif = esp_netif_next_unsafe(netif)) != NULL) { - ESP_LOGI("SPIT", "Connected to %s", esp_netif_get_desc(netif)); - esp_netif_ip_info_t ip; - ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip)); - ESP_LOGI("SPIT", "- IPv4 address: " IPSTR ",", IP2STR(&ip.ip)); - ESP_LOGI("SPIT", "- IPv4 netmask: " IPSTR ",", IP2STR(&ip.netmask)); - char buffer[64]; - - sprintf(buffer, IPSTR, IP2STR(&ip.ip)); - string stringIP4 = buffer; - sprintf(buffer, IPSTR, IP2STR(&ip.netmask)); - string stringSubnet = buffer; - addIPAddress(stringIP4, stringSubnet); - } - removeNotFoundIPAddresses(); -} diff --git a/components/spit/src/Watchdog.cpp b/components/spit/src/Watchdog.cpp deleted file mode 100644 index 748a62f..0000000 --- a/components/spit/src/Watchdog.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -/* - * SPITWatchdog sends watchdog messages to the server from time to time. - * If there is no response from the server an eventWatchdogLost is triggered. - * - * File: Watchdog.cpp - * Author: Hagi - * - * Created on 22. April 2019, 13:02 - */ - - -#include "Watchdog.h" - -int Watchdog::WATCHDOGTIME = 3000; -bool Watchdog::s_StopWatchdog = true; - -Watchdog::Watchdog(Listener* p_Listener) { - s_StopWatchdog = true; - m_Listener = p_Listener; - m_WatchdogThread = NULL; -} - - -Watchdog::~Watchdog() { - stopWatchdog(); -} - -void Watchdog::startWatchdog() { - if (s_StopWatchdog == false) return; - { - fos::Mutex o_UniqueLock(m_MutexLock); - s_StopWatchdog = false; - } - m_WatchdogThread = new fos::TaskT(Watchdog::runWatchdog, *this, "spitWD"); -} -void Watchdog::stopWatchdog() { - if (m_WatchdogThread != NULL) { - { - fos::Mutex o_UniqueLock(m_MutexLock); - if (s_StopWatchdog == true) { - return; - } - s_StopWatchdog = true; - } - m_ConditionVariable.give(); - delete m_WatchdogThread; - m_WatchdogThread = NULL; - } -} -void Watchdog::answerWatchdog() { - m_Answered = true; -} - -void Watchdog::runWatchdog(Watchdog& wd) { - bool boolDone; - while (wd.s_StopWatchdog == false) { - wd.m_Answered = false; - wd.m_Listener->sendWatchdog(); - { - fos::Mutex o_UniqueLock(wd.m_MutexLock); - boolDone = wd.m_ConditionVariable.take(WATCHDOGTIME); - if (wd.s_StopWatchdog == true) { - return; - } - } - if (boolDone) { - return; - } - if (wd.m_Answered == false) { - wd.stopWatchdog(); - wd.m_Listener->eventWatchdogLost(); - return; - } - } - -} diff --git a/components/spit/src/_SPITMACROS.cpp b/components/spit/src/_SPITMACROS.cpp deleted file mode 100644 index 3beac2a..0000000 --- a/components/spit/src/_SPITMACROS.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - -#include "_SPITMACROS.h" -#include "esp/uuid.h" -#include "esp_netif.h" - -string createGUID() { - // uuid_t id; - // uuid_generate(id); - // char *guid_string = new char[100]; - // uuid_unparse(id, guid_string); - // string stringGUID = guid_string; - // return stringGUID; - - uuid_t uu; - char uu_str[UUID_STR_LEN]; - - uuid_generate(uu); - uuid_unparse(uu, uu_str); - string stringGUID = uu_str; - return stringGUID; -} -/** The name of the client's host computer*/ -string getClientHostName() { - string stringHostName = ""; - const char * hostname; - esp_netif_get_hostname(esp_netif_get_default_netif(), &hostname); - if (hostname != nullptr) { - stringHostName = hostname; - } - return stringHostName;; -} diff --git a/main/watchMain.cpp b/main/watchMain.cpp index 95495ce..059b10a 100644 --- a/main/watchMain.cpp +++ b/main/watchMain.cpp @@ -36,6 +36,9 @@ struct { #include "watchMain.hpp" +string MyApp::s_ClientName = "CatasWatchDev"; +string MyApp::s_ProjectName = "CatastrphicProj"; + extern "C" { // This switch allows the ROS C-implementation to find this main void app_main(void); } @@ -614,6 +617,21 @@ void MovementTask() { } } +void SpitClientApp() { + ESP_LOGI(TAG, "Starting SPIT task"); + auto ptrMyApp = std::make_unique(); + + + // load a client project and start auto detection of SPITServers + ptrMyApp->init(); + + while (true) { + fos::Task::delayMs(10000); + ESP_LOGI(TAG, "Test LiveShow"); + ptrMyApp->testLiveShowRemote(); //This is an excample how to remote control the liveSHOWsoftware + } +} + void app_main(void) { esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { @@ -633,6 +651,7 @@ void app_main(void) { static fos::TaskT telnetSocket(telnetSocketTask, ipVersion, "tcpServer", 4096); static fos::TaskT dmxNode(dmxSocketTask, ipVersion, "dmxNode", 4096); // static Task otaUpdate(SystemFunctions::OtaTaskEntry, "otaTask", 8192); + static fos::Task spit(SpitClientApp,"SpitClient"); auto &store = NvsApi::getInstance(); auto logger = store.getValue(ConfigKeys.syslogDest); @@ -640,17 +659,17 @@ void app_main(void) { Syslog::setupTask(IpAdr{logger, 0}); } - auto broker = store.getValue(ConfigKeys.mqttBroker); - if (broker != "") { - ESP_LOGI(TAG, "Initializing MQTT"); - auto prefix = store.getValue(ConfigKeys.mqttPrefix); - auto &client = MqttClient::init(broker, prefix); - if (!client.isRunning()) { - client.addSubscription(MqttTopics.moveTo, [](std::string d) { moveToSubs(d); }); - client.addSubscription(MqttTopics.startShuffle, [](std::string d) { startShuffle(d); }); - client.start(); - } - } + // auto broker = store.getValue(ConfigKeys.mqttBroker); + // if (broker != "") { + // ESP_LOGI(TAG, "Initializing MQTT"); + // auto prefix = store.getValue(ConfigKeys.mqttPrefix); + // auto &client = MqttClient::init(broker, prefix); + // if (!client.isRunning()) { + // client.addSubscription(MqttTopics.moveTo, [](std::string d) { moveToSubs(d); }); + // client.addSubscription(MqttTopics.startShuffle, [](std::string d) { startShuffle(d); }); + // client.start(); + // } + // } while (true) { fos::Task::delayMs(5000); diff --git a/main/watchMain.hpp b/main/watchMain.hpp index 294caeb..09aee55 100644 --- a/main/watchMain.hpp +++ b/main/watchMain.hpp @@ -36,6 +36,7 @@ #include "Processor.hpp" #include "nvsFunctions.hpp" #include "mqttClient.hpp" +#include "MyApp.h" // #include "esp_chip_info.h" // #include "esp_flash.h"