feature: Add SPIT-Source as is

This commit is contained in:
2024-08-19 03:29:37 +02:00
parent a5805aceb2
commit 500641a6e2
31 changed files with 10176 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
/*
* 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: MySPITApp.h
* Author: Hagi
*
* Created on 17. April 2019, 18:24
*/
#ifndef MYSPITAPP_H
#define MYSPITAPP_H
#include "SPIT_Client.h"
#include <string>
#include <chrono>
using namespace std;
int main();
class MyApp : SPIT_ClientInterface {
public:
MyApp();
virtual ~MyApp();
//Client's infos is set by the client
static string s_ClientName;
static string s_ClientProjectID;
static string s_ClientProjectName;
static int s_ClientDefaultFramesPerSecond;
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
//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
public:
//---------- SPIT_ClientInterface -------------
string getClientProjectID(); //should return the client's project id, maybe the same as project name
string getClientProjectName(); //should return the client's project name
//----- 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 -----
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);
//----- 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);
//----- 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);
//----- 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);
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);
};
#endif /* MYSPITAPP_H */
+68
View File
@@ -0,0 +1,68 @@
/*
* 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 <string>
#include <list>
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 recursive_mutex s_MutexClientInterface;
static SAD_ClientInterface* s_SADClientInterface;
//----- SAD_Client -----
public:
private:
static mutex s_MutexSAD;
static condition_variable s_ConditionStopSAD;
static bool s_StopSAD;
static thread* s_ThreadSend;
static thread* s_ThreadReceiveIP4;
static thread* s_ThreadReceiveIP6;
static recursive_mutex s_MutexSocket;
static SPITSocket* s_SPITSocket;
static void sendAutoDetectServer();
static void cycleStart();
static void cycleEnd();
static void receiveAutoDetectServer_IP4();
static void receiveAutoDetectServer_IP6();
public:
static void startAutoDetectServer(SAD_ClientInterface* p_SADClientInterface, SPITSocket* p_SPITSocket);
static void stopAutoDetectServer(SAD_ClientInterface* p_SADClientInterface);
};
#endif /* SERVERAUTODETETC_CLIENT_H */
@@ -0,0 +1,57 @@
/*
* 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
#include <string>
using namespace std;
class SAD_ClientInterface {
public:
/**
* If a new server was found by the ServerAutoDetect mechanism, this function is called.<br>
* To do so the SAD_Client ServerAutoDetect has to be startet - see SAD_Client::startServerAutoDetect.<br>
* If a server can be reached via several IP addresses, the IP address is selected according to the following preference:<br>
* 1.) If a loopback address is available, it is used.<br>
* 2.) If an IP4 address is available, it is used.<br>
* 3.) In the other cases the IP6 address is used.<br>
* @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(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;
/**
* 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.<br>
* @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 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;
};
#endif /* SAD_CLIENTINTERFACE_H */
@@ -0,0 +1,242 @@
/*
* 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.
*/
/*
* This class describes a detected SPITServer, found by SAD_Client.<br>
* 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 <string>
#include <mutex>
#include <unordered_map>
#include <list>
using namespace std;
class SAD_DetectedServer {
public:
SAD_DetectedServer();
SAD_DetectedServer(const SAD_DetectedServer& orig) {
m_ID = orig.getID();
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();
}
~SAD_DetectedServer();
private:
string m_ID;
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;
bool m_New;
bool m_Changed;
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;
}
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;
}
//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() {
}
private:
static recursive_mutex s_MutexDetectedServer;
static unordered_map<string, SAD_DetectedServer*> s_DetectedServers;
public:
static const int PARAMINDEX_PRECODE = 0;
static const int PARAMINDEX_SPITTASKID = 1;
static const int PARAMINDEX_NAME = 2;
static const int PARAMINDEX_ID = 3;
static const int PARAMINDEX_COMPUTERNAME = 4;
static const int PARAMINDEX_PORT = 5;
static const int PARAMINDEX_CLIENTIP = 6;
static const int PARAMINDEX_ADDITIONS = 7;
static const int PARAMINDEX_IP = 8;
/**
* Used by SAD_Client to add a found SPITServer - don't use this manually
* @param p_IsIP4 true = the server is reached via a IP4 address<br>false = the server is reahed via a IP6 address
* @param p_ServerID the id of the server, every instance of a SPITServer has an own id
* @param p_ServerParams the server's parameter
*/
static void addDetectedServer(bool p_IsIP4, string p_ServerID, string p_ServerParams[]);
/**
* Used by SAD_Client to remove a SPITServer - don't use this manually
* @param p_DetectedServer
*/
static void removeDetectedServer(SAD_DetectedServer* p_DetectedServer);
/**
* Used by SAD_Client to clear all found SPITServers - don't use this manually
*/
static void clearDetectedServers();
/**
* Used by SAD_Client internally - don't use this manually
*/
static void cycleStart();
/**
* Used by SAD_Client internally -don't use this manually
* @param p_SADClientInterface
*/
static void cycleEnd(SAD_ClientInterface* p_SADClientInterface);
/**
* Returns a reference of the DetectedServer with the id p_ServerID.<br>
* If no DetectedServer is found an eyception is thrown.
* @param p_ServerID the id of the SPITServer
* @return the reference of the SAD_DetectedServer instance with getID() == p_ServerID
*/
static const SAD_DetectedServer& getRefDetectedServer(string p_ServerID) {
SAD_DetectedServer* ptrDetectedServer = NULL;
{
unique_lock<recursive_mutex> o_Lock(s_MutexDetectedServer);
auto i = s_DetectedServers.find(p_ServerID);
if (i != s_DetectedServers.end()) {
ptrDetectedServer = i->second;
}
if (ptrDetectedServer != NULL) {
return *ptrDetectedServer;
}
throw new exception();
}
}
};
#endif /* SAD_DETECTEDSERVER_H */
+198
View File
@@ -0,0 +1,198 @@
/*
* 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: SPITObject.h
* Author: Hagi
*
* Created on 9. April 2019, 12:11
*/
#ifndef SPITOBJECT_H
#define SPITOBJECT_H
//#include "_SPITMACROS.h"
#include "SPIT_Message.h"
#include "SPITType.h"
#include <string>
#include <unordered_map>
#include <mutex>
using namespace std;
class SPITObjectListener;
class SPITObject {
private:
static recursive_mutex s_MutexSPITObject;
static unordered_map<string, SPITObject*> s_SPITObjects;
static unordered_map<string, SPITObject*> s_SPITObjectsRemote;
public:
static recursive_mutex* getMutex() {
return &s_MutexSPITObject;
}
static SPITObject* getSPITObject(string p_ID);
static const SPITObject& getSPITObjectRef(string p_ID);
static bool addSPITObject(SPITObject* p_ptrSpitObject);
static bool removeSPITObject(SPITObject* p_ptrSpitObject);
static int getSPITObjectCount();
static SPITObject* getSPITObject(int p_Index);
static const SPITObject& getSPITObjectRef(int p_Index);
static void clearSPITObjects();
static void setConfirmedFalse();
static SPITObject* getSPITObjectRemote(string p_ID);
static const SPITObject& getSPITObjectRemoteRef(string p_ID);
static bool addSPITObjectRemote(SPITObject* p_ptrSpitObject);
static bool removeSPITObjectRemote(SPITObject* p_ptrSpitObject);
static int getSPITObjectRemoteCount();
static SPITObject* getSPITObjectRemote(int p_Index);
static const SPITObject& getSPITObjectRemoteRef(int p_Index);
static void clearSPITObjectsRemote();
SPITObject();
// SPITObject(const SPITObject& orig);
~SPITObject();
private:
string m_ID;
string m_Name;
string m_SPITTypeID;
string m_ServerParams;
string m_Remark;
bool m_Confirmed;
bool m_Fixed;
bool m_ServerRemote;
bool m_ActionAssigned;
bool m_ActionAssignedType; //Virtual construct
long long m_FrameStart;
long long m_FrameLength;
long long m_FrameFadeInLength;
long long m_FrameFadeOutLength;
char m_ValueUse;
int m_ValueFactor;
int m_Track;
long long m_Delay;
long long m_Duration;
bool m_PlayPrePosition;
long long m_PlayTimeInsideFrames;
int m_PlayValue;
char m_PlayValueFlag;
void initMembers();
public:
string getID() const {
return m_ID;
}
string getName() const {
return m_Name;
}
string getRemark() const {
return m_Remark;
}
string getSPITTypeID() const {
return m_SPITTypeID;
}
string getServerParams() const {
return m_ServerParams;
}
/**
* 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<br>
* true = the action is triggered on the server. The server waits for the client to play objects of this SPITType.
*/
bool getServerRemote() const {
return m_ServerRemote;
}
/**
* 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;
}
/**
* This is a virtual construct - ActionAssignedType is not implemented in the SPITProtocol.<br>
* This is used when an action is associated with a SPITType. <br>
* Then this action is done for every SPITObject with the SPITType.
* @return true = an action is assigned for the SPITType.
*/
bool getActionAssignedType() const {
return m_ActionAssignedType;
}
/** Returns if this SPITObject has an associated action or not.<br>
* @return true = the user has asscociated an action with this SPITObject or <br>
* the user has asscociated an action with the SPITType of this SPITObject
*/
bool getActionAssigned() const {
return m_ActionAssigned || m_ActionAssignedType;
}
long long getFrameStart() const {
return m_FrameStart;
}
long long getFrameLength() const {
return m_FrameLength;
}
long long getFrameFadeInLength() const {
return m_FrameFadeInLength;
}
long long getFrameFadeOutLength() const {
return m_FrameFadeOutLength;
}
char getValueUse() const {
return m_ValueUse;
}
int getValueFactor() const {
return m_ValueFactor;
}
int getTrack() const {
return m_Track;
}
long long getDelay() const {
return m_Delay;
}
long long getDuration() const {
return m_Duration;
}
void setID(string p_ID);
bool setConfirmed(bool p_Confirmed);
bool setName(string p_Name);
bool setRemark(string p_Remark);
bool setServerParams(string p_ServerParams);
bool setSPITTypeID(string p_GroupName);
bool setServerRemote(bool p_BelongstoServer);
bool setActionAssignedType(bool p_ActionAssigned);
bool setActionAssigned(bool p_ActionAssigned);
bool setFixed(bool p_Fixed);
bool setFrameStart(long long p_FrameStart);
bool setFrameLength(long long p_FrameLength);
bool setFrameFadeInLength(long long p_FrameFadeInLength);
bool setFrameFadeOutLength(long long p_FrameFadeOutLength);
bool setValueUse(char p_ValueUse);
bool setValueFactor(int p_ValueFactor);
bool setTrack(int p_Track);
bool setDelay(long long p_Delay);
bool setDuration(long long p_Duration);
void setMessageOP(SPIT_Message::ReportSPITObject* p_ReportSPITObject);
void fillMessageOP(SPIT_Message::ReportSPITObject* p_ReportSPITObject);
void fillMessageOP(SPIT_Message::RemoveSPITObject* p_RemoveSPITObject);
};
#endif /* SPITOBJECT_H */
+176
View File
@@ -0,0 +1,176 @@
/*
* 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: SPITPLayer.h
* Author: Hagi
*
* Created on 30. April 2019, 11:44
*/
#ifndef SPITPLAYER_H
#define SPITPLAYER_H
#include "SPITObject.h"
#include <unordered_map>
class SPITPlayer {
//----- PlayObject used in PlaySequences: PlaySPITStart, PlaySPITObject,..., PlaySPITEnd ------
public:
class PlayObject {
public:
PlayObject();
PlayObject(SPITPlayer* p_SPITPlayer, string p_SPITObjectID);
PlayObject(const PlayObject& orig);
string getSPITObjectID() const {
return m_SPITObjectID;
}
void startPlaySequence();
bool getIsNew() const {
return m_IsNew;
}
void setIsNew(bool p_IsNew) {
m_IsNew = p_IsNew;
}
bool getIsPlayed() const {
return m_IsPlayed;
}
void setIsPlayed(bool p_IsFound) {
m_IsPlayed = p_IsFound;
}
string getPlayerID() const {
return m_PlayerID;
}
string getPlayerName() const {
return m_PlayerName;
}
bool getPlayerIsRunning() const {
return m_PlayerRuns;
}
void setPlayerIsRunning(bool p_PlayerRuns) {
m_PlayerRuns = p_PlayerRuns;
}
void setValue(int p_Value, bool p_PlayPrePosition) {
if (p_PlayPrePosition) m_ValuePrePosition = p_Value;
else m_Value = p_Value;
}
int getValue() const {
return m_ValuePrePosition + m_Value;
}
int getValueFadePrePosition() const {
return m_ValuePrePosition;
}
int getValueFade() const {
return m_Value;
}
void setValueFactor(int p_ValueFactor) {
m_ValueFactor = p_ValueFactor;
}
void setValueFlag(char p_ValueFlag) {
m_ValueFlag = p_ValueFlag;
}
int getValueFactor() const {
return m_ValueFactor;
}
char getValueFlag() const {
return m_ValueFlag;
}
void setFrameInside(long long p_FrameInside, bool p_PlayPrePosition) {
if (p_PlayPrePosition) m_FrameInsidePrePosition = p_FrameInside;
else m_FrameInside = p_FrameInside;
}
long long getFrameInside() const {
return m_FrameInside;
}
long long getFrameInsidePrePosition() const {
return m_FrameInsidePrePosition;
}
private:
string m_PlayerID;
string m_PlayerName;
bool m_PlayerRuns;
string m_SPITObjectID;
bool m_IsPlayed;
bool m_IsNew;
int m_Value;
int m_ValuePrePosition;
int m_ValueFactor;
char m_ValueFlag;
long long m_FrameInsidePrePosition;
long long m_FrameInside;
};
//----- SPITPlayer ------
public:
static recursive_mutex s_Mutex;
static recursive_mutex* getMutex() {
return &s_Mutex;
}
//list the SPITPlayers
static unordered_map<string, SPITPlayer*> s_SPITPlayers; //all actual played objects
static SPITPlayer* getSPITPlayer(string p_PlayerID); //if a player does not exist creates a new one
static void clearPlayers();
SPITPlayer(string p_PlayerID);
virtual ~SPITPlayer();
void startPlaySequence(); //called by SPIT_Client::parsePlaySPITStart
PlayObject* addSPITObject_Playing (string p_SPITObjectID); //called by SPIT_Client::parsePlaySPITStart
void endPlaySequence(); //called by SPIT_Client::parsePlaySPITEnd
string getID() {
return m_ID;
}
unordered_map<string, PlayObject*>* getPlayObjects();
void setIsRunning(bool p_IsRunning);
bool getIsRunning() {
return m_IsRunning;
}
void setName(string p_Name);
string getName() {
return m_Name;
}
void setType(char p_Type);
char getType() {
return m_Type;
}
void setTime(long long p_Frames);
long long getTime() {
return m_TimeFrames;
}
PlayObject* getPlayObject(string p_SPITObjectID);
private:
string m_ID;
string m_Name;
char m_Type;
unordered_map<string, PlayObject*> m_PlayObjects;
bool m_IsRunning;
long long m_TimeFrames;
};
#endif /* SPITPLAYER_H */
+171
View File
@@ -0,0 +1,171 @@
/*
* 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.
*/
/*
* SPITSocket is the base class for WindowsSocket, UnixSocket,..<br>
* Used by SPIT_Client and SAD_Client.
* File: SPITSocket.h
* Author: Hagi
*
* Created on 12. April 2019, 15:40
*/
#ifndef SPITSOCKET_H
#define SPITSOCKET_H
#include "_SPITMACROS.h"
#include <mutex>
#include <unordered_map>
#include <string>
using namespace std;
class SPITSocket{
public:
static int FAMILY_IP4;
static int FAMILY_IP6;
//-------- nested classes --------------
public:
/**
* IPAddress class is used to fetch all available IP addresses of the computer.<br>
* This is for internal usage.<br>
*/
class IPAddress {
public:
IPAddress();
~IPAddress();
private:
string m_IPAddress;
string m_SubnetMask;
bool m_Found;
public:
const string& getIPAddress() {
return m_IPAddress;
}
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);
};
private:
static recursive_mutex s_MutexIPAddresses;
public:
static unordered_map<string, IPAddress*> 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();
private:
string m_ServerIP;
string m_ServerPort;
string m_ClientIP;
string m_ClientPort; //port given by the user maybe "0"
string m_BoundClientPort; //port set after bind
int m_BoundClientFamily;
bool m_IsBound;
recursive_mutex m_MutexSocket;
public:
/**
* Sets the ip address and port for server and client.
* @param p_ServerIP
* @param p_ServerPort
* @param p_ClientIP
* @param p_ClientPort
*/
void setConnectionParams(string p_ServerIP, string p_ServerPort, string p_ClientIP, string p_ClientPort);
/**
* Send a message to the server as set by setConnectionParams.<br>
* @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.<br>
* This will block until a message is received or the underlying socket is closed.<br>
* @param p_InetFamily either AF_INET or AF_INET6<br>
* The SPITSocket creates two udp sockets, one for IP4 and one for IP6.<br>
* This parameter decides from which socket should a message recieved.<br>
* @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.<br>
* 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.<br>
* @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.<br>
* @param p_ClientIP the ip address either IP4 or IP6
* @param p_ClientPort the client port number.<br>
* "0" = bind to any free port.<br>
* @return
*/
virtual int bindSocket(string p_ClientIP, string p_ClientPort) = 0;
/**
* Internal usage - don't use this manually.<br>
* Use sendMessage instead.<br>
* @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.<br>
*/
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();
};
#endif /* SPITSOCKET_H */
+168
View File
@@ -0,0 +1,168 @@
/*
* 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: SPITType.h
* Author: Hagi
*
* Created on 8. April 2019, 08:40
*/
#ifndef SPITTYPE_H
#define SPITTYPE_H
#include "_SPITMACROS.h"
#include "SPIT_Message.h"
#include <string>
#include <unordered_map>
#include <mutex>
using namespace std;
class SPITTypeListener;
class SPITType {
private:
static recursive_mutex s_MutexSPITType;
static unordered_map<string, SPITType*> s_SPITTypes;
static unordered_map<string, SPITType*> s_SPITTypesRemote;
public:
static recursive_mutex* getMutex() {
return &s_MutexSPITType;
}
static SPITType* getSPITType(string p_ID);
static const SPITType& getSPITTypeRef(string p_ID);
static bool addSPITType(SPITType* p_ptrSpitType);
static bool removeSPITType(SPITType* p_ptrSpitType);
static int getSPITTypeCount();
static SPITType* getSPITType(int p_Index);
static const SPITType& getSPITTypeRef(int p_Index);
static void clearSPITTypes();
static void setConfirmedFalse();
static SPITType* getSPITTypeRemote(string p_ID);
static const SPITType& getSPITTypeRemoteRef(string p_ID);
static bool addSPITTypeRemote(SPITType* p_ptrSpitType);
static bool removeSPITTypeRemote(SPITType* p_ptrSpitType);
static int getSPITTypeRemoteCount();
static SPITType* getSPITTypeRemote(int p_Index);
static const SPITType& getSPITTypeRemoteRef(int p_Index);
static void clearSPITTypesRemote();
SPITType();
SPITType(string p_ID, string p_GroupName, string p_Name, bool p_Fixed, bool p_ProjectIndepended,long long p_DefaultDelay, long long p_DefaultDuration);
// SPITType(const SPITType& orig);
~SPITType();
private:
bool m_Confirmed;
string m_ID;
bool m_Fixed;
bool m_ServerRemote;
bool m_ServerProjectIndepended;
string m_GroupName;
string m_Name;
long long m_DefaultDelay;
long long m_DefaultDuration;
bool m_CreatedByClient; //flag true = the SPITTyype is created by the client
//false = the SPITType is received from the server
bool m_ActionAssigned; //This is a virtual flag if user associates an action with a SPITType.
//Can be used to setActionAssigned for all SPITObjects with this SPITType
void initMembers();
public:
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<br>
* true = the action is triggered on the server. The server waits for the client to play objects of this SPITType.
*/
bool getServerRemote() const {
return m_ServerRemote;
}
bool getProjectIndepended() const {
return m_ServerProjectIndepended;
}
/**
* 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;
}
/**
* Virtual construct - means ActionAssigned for SPITTypes is is not implemented in SPITProtocol.<br>
* This can used to setActionAssigned to all SPITObjects with this SPITType.<br>
* This may be used in the case when the same action should be done for every SPITObject with this SPITType associated.<br>
* @return true = the user has associated an action with this SPITType.
*/
bool getActionAssigned() const {
return m_ActionAssigned;
}
public:
void setID(string p_ID);
bool setGroupName(string p_GroupName);
bool setName(string p_Name);
bool setServerRemote(bool p_BelongstoServer);
bool setProjectIndepended(bool p_ProjectIndepeneded);
bool setConfirmed(bool p_Confirmed);
bool setFixed(bool p_Fixed);
bool setDefaultDelay(long long p_Delay);
bool setDefaultDuration(long long p_Duration);
void setCreatedByClient(bool p_CreatedByClient);
/**
* Virtual construct - means ActionAssigned for SPITTypes is is not implemented in SPITProtocol.<br>
* This can used to setActionAssigned to all SPITObjects with this SPITType.<br>
* This may be used in the case when the same action should be done for every SPITObject with this SPITType associated.<br>
* @return true = the m_ActionAssigned has changed.
*/
bool setActionAssigned(bool p_ActionAssigned);
bool setMessageOP(SPIT_Message::ReportSPITType* p_ReportSPITType);
void fillMessageOP(SPIT_Message::ReportSPITType* p_ReportSPITType);
void fillMessageOP(SPIT_Message::RemoveSPITType* p_RemoveSPITType);
// static char* stringCopy(const char* p_String);
};
#endif /* SPITTYPE_H */
+648
View File
@@ -0,0 +1,648 @@
/*
* 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_Client.h
* Author: Hagi
*
* Created on 7. April 2019, 08:50
*/
#ifndef SPIT_CLIENT_H
#define SPIT_CLIENT_H
#include "_SPITMACROS.h"
#if defined OS_WINDOWS
#include "WindowsSocket.h"
#endif
#if defined OS_MAC || defined OS_LINUX
#include "UnixSocket.h"
#endif
#include "SPITSocket.h"
#include "SAD_Client.h"
#include "SAD_ClientInterface.h"
#include "SAD_DetectedServer.h"
#include "SPIT_ClientInterface.h"
#include "SPIT_Message.h"
#include "Watchdog.h"
#include "SPITType.h"
#include "SPITObject.h"
#include "SPIT_Handler.h"
#include "SPITPlayer.h"
#include <chrono>
//#include <thread>
using namespace std;
//static char nullChar[] = "\0";
class SPIT_Client : SAD_ClientInterface, Watchdog::Listener {
public:
/** Maximal length of a SPITMessage*/
static const int MAXSPITMESSAGEBYTECOUNT = 512;
//----- Connection Status -----
public:
/** No Connection established.<br>Either no connect tried or disconnected*/
static const int CONNECTION_NONE = 0;
/** Server has disconnected*/
static const int CONNECTION_NONESERVER = 1;
/** The connection is lost<br>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.*/
static const int CONNECTION_OK = 3;
/** A connection to the server is tried.*/
static const int CONNECTION_TRYCONNECTION = 4;
//------ PlayerType ------
public:
/** continous main player, time value can be used like a timecode.<br>The time value is the position in server's project.<br>A server should use only one main player.*/
static const char PLAYERTYPE_MAIN = 0x02;
/** continous player. This player plays SPIT objects sometime during the project.*/
static const char PLAYERTYPE_CONTINOUS = 0x01;
/** diescrete player. This player is used to transmit single discrete values.*/
static const char PLAYERTYPE_DISCRETE = 0x00;
//------ Value Flag ------
//------ used by sendRemoteObject
public:
/**Set the given value directly*/
static const char VALUEFLAG_DIRECT = 0x00;
/**Increase the existing value by the given value.<br>This is usefull e.g. when instead of a fader a endless wheel is used*/
static const char VALUEFLAG_INCREASE = 0x01;
/**Decrease the existing value by the given value.<br>This is usefull e.g. when instead of a fader a endless wheel is used*/
static const char VALUEFLAG_DECREASE = 0x02;
//----- SPIT_Client -----
public:
static SPITSocket* createSPITSocket();
public:
SPIT_Client(SPIT_ClientInterface* p_SPITClientInterface);
virtual ~SPIT_Client();
private:
/** SPITClientInterface, normally the user app should implement this*/
SPIT_ClientInterface* m_SPITClientInterface;
SPITSocket* m_SPITSocket;
recursive_mutex m_MutexSPITSocket;
thread* m_ThreadReceive;
bool m_StopReceiveSPITMessages;
int m_ConnectionStatus;
bool m_DisconnectedByServer; //flag true = when server disconnects
string m_ID;
string m_Name;
string m_ComputerName;
//Server's info filled by parseConnectAnswer
string m_ServerID;
string m_ServerName;
string m_ServerComputerName;
int m_ServerStepTime;
Watchdog* m_Watchdog;
//--- Server Project ---
string m_ServerProjectID;
string m_ServerProjectName;
int m_ServerFramesPerSecond;
public:
SPIT_ClientInterface* getSPITClientInterface() {
return m_SPITClientInterface;
}
public:
/** The ID of the client.<br>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 -----
/** The name of the client's host computer*/
string getComputerName();
//connected Server Infos
/** The ID of the connected SPITServer*/
string getServerID();
/** The host computername of the connected SPITServer*/
string getServerComputerName();
/** The name of the connected SPITServer*/
string getServerName();
/** Expected Refreah Rate of the connectd SPITServer.<br>
* When the server plays objects, it will do so at discrete time steps.<br>
* Play events will take place in these time steps..
*/
int getServerStepTime();
/** Should be called when the client wants to close his project*/
void clientProjectClose();
/**
* Should be called whenever the client has a project loaded
*/
void clientProjectLoaded();
/**
*
* @param p_SPITTypeID
* @param p_ActionAssigned
*/
void setActionSPITType(string p_SPITTypeID, bool p_ActionAssigned);
void setActionSPITObject(string p_SPITObjectID, bool p_ActionAssigned);
//--------------- SPITMessage ---------------
private:
bool startReceiveSPITMessages();
void stopReceiveSPITMessages();
void receiveSPITMessage();
int sendSPITMessage(SPIT_Message::OPPart* p_SPITMessageOPPart);
void fillHeader(SPIT_Message::Header* p_Header);
//--------------- ServerAutoDetection SAD ---------------
public:
/** Starts the autodetection of SPITServers in the local network. If a connection is tried, the autodetection should be stopped before.*/
void startServerAutoDetect();
/** Stops the autodetection of SPITServers in the local network*/
void stopServerAutoDetect();
/** Called every time a new SPITServer is detetced in the local network */
void eventServerDetected(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);
/** 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);
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:
/**
* Tries a connection to the SPITServer
* @param p_ServerIP ip address of the SPITServer
* @param p_ServerPort port of the SPITServer
* @param p_ClientIP IP of the client
* @param p_ClientPort if "0" any free port will be used
* @param p_LoginName maybe some SPITServer need a login - liveSHOWsoftware will not.
* @param p_LoginPassword maybe some SPITServer need a login - liveSHOWsoftware will not
* @return true = the connection try is ok, SPITServer will answer with COnnectAnswer and an eventConnectionStatus will occur.<br>
* false = something is going wrong. (client could not bind)
*/
bool connect(string p_ServerIP, string p_ServerPort, string p_ClientIP, string p_ClientPort, string p_LoginName = "", string p_LoginPassword = "");
/**
* Terminates the connection to the SPITServer.
*/
void disconnect();
private:
void disconnectInternal(int p_Cause);
void parseSPIT_Message(SPIT_Message* p_SPITMessage);
void parseConnectAnswer(SPIT_Message::ConnectAnswer* p_ConnectAnswer);
void parseDisconnect(SPIT_Message::Disconnect* p_Disconnect);
void parseWatchdog(SPIT_Message::Watchdog* p_Watchdog);
void parseWatchdogAnswer(SPIT_Message::WatchdogAnswer* p_WatchdogAnswer);
public:
/** Used internally*/
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);
void parseCloseSPITProject(SPIT_Message::CloseSPITProject* p_CloseSPITProject);
public:
/** Returns the SPITServer's project ID - may be the same as the project's name*/
string getServerProjectID();
/** Returns the SPITServer's project name*/
string getServerProjectName();
/** Returns frame rate per second. This is the time resolution in which the server transmits time data. The unit of time data is always frames.*/
int getServerFramesPerSecond();
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 ---------------
public:
/**
* Creates a fixed SPITType for application actions that are always present and project independent.<br>
* Fixed SPIT types cannot be changed or deleted by the server.<br>
* These SPITTypes will be automatically added to the SPITType-List and sended to the server.
* @param p_ID an unique of the SPITType, these are always the same per client approach. Different client approaches should use different ids.
* @param p_GroupName a name which groups the actions/SPITTypes
* @param p_Name the name of the Action/SPITType
* @param p_DefaultDelay maybe there is an default delay until the action starts, this is only used for graphical representations, 0 is allowd
* @param p_DefaultDuration maybe the action has a default duration, this is only used for graphical representations, 0 is allowd
* @return the pointer to the new SPITType.
*/
SPITType* createSPITTypeFixed(string p_ID, string p_GroupName, string p_Name, long long p_DefaultDelay, long long p_DefaultDuration);
/**
* Creates a SPITType for application actions.<br>
* These SPITTypes will be automatically added to the SPITType-List and sended to the server.
* @param p_ID an unique of the SPITType, these are always the same per client approach. Different client approaches should use different ids.
* @param p_GroupName a name which groups the actions/SPITTypes
* @param p_Name the name of the Action/SPITType
* @param p_DefaultDelay maybe there is an default delay until the action starts, this is only used for graphical representations, 0 is allowd
* @param p_DefaultDuration maybe the action has a default duration, this is only used for graphical representations, 0 is allowd
* @param p_Fixed true = the server is not allowed to change this SPITType, false = the server may change or delete this SPITType
* @param p_ProjectIndepended true = the SPITType belongs to a specific project, false = the SpitType always exists for every project
* @return the pointer to the new SPITType.
*/
SPITType* createSPITType(string p_ID, string p_GroupName, string p_Name, long long p_DefaultDelay, long long p_DefaultDuration, bool p_Fixed, bool p_ProjectIndepended);
private:
//receive SPITTypes
void parseReportSPITType(SPIT_Message::ReportSPITType* p_ReportSPITType);
void parseRemoveSPITType(SPIT_Message::RemoveSPITType* p_RemoveSPITType);
int sendSPITTypeInternal(SPITType* p_SPITType);
public:
/**
* If a client wants to change a SPITType, he should send it to the server.<br>
* If the SPITTye is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the change.<br>
* @param p_SPITTypeID the id of the SPITType to remove.
* @return 0 = is sended, -1 = is not sended
*/
bool changeSPITType(SPITType* p_SPITType);
/**
* If a client wants to remove a SPITType, he should send it to the server.<br>
* If the SPITTye is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the deletion.<br>
* @param p_SPITTypeID the id of the SPITType to remove.
* @return 0 = is sended, -1 = is not sended
*/
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:
void parseReportSPITObject(SPIT_Message::ReportSPITObject* p_ReportSPITObject);
void parseRemoveSPITObject(SPIT_Message::RemoveSPITObject* p_RemoveSPITObject);
int sendSPITObjectInternal(SPITObject* ptrSPITObject);
public:
/**
* When the client changes a SPITObject (normally the client should not do this), then it should send the changes to the SPITServer.<br>
* The SPITServer may discard the changes and an eventSPITObject occurs.<br>
* @param p_SPITObject the pointer to the changed SPITObject.
* @return 0 = sended, -1 = not sended
*/
bool changeSPITObject(SPITObject* p_SPITObject);
/**
* When the client removes a SPITObject (normally the client should not do this), then he should send it to the SPITServer.<br>
* The SPITServer may discard the deletion and an eventSPITObject occurs.<br>
* @param p_SPITObjectID the id of the SPITObject to remove.
* @return 0 = sended, -1 = not sended
*/
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:
void parsePlaySPITStart(SPIT_Message::PlaySPITStart* p_PlaySPITStart);
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);
}
}
};
//--------- Remote ----------
void sendRemoteObject(string p_SPITObjectID, int p_Valueppm = 0, char p_ValueFlag = 0x00);
};
#endif /* SPIT_CLIENT_H */
@@ -0,0 +1,82 @@
/*
* 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 <string>
#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:<br>
* 1.) If a loopback address is available, it is used.<br>
* 2.) If an IP4 address is available, it is used.<br>
* 3.) In the other cases the IP6 address is used.<br>
* @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 */
+48
View File
@@ -0,0 +1,48 @@
/*
* 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>
#include <condition_variable>
#include <thread>
#include <list>
using namespace std;
class SPIT_Handler {
public:
class Runnable {
public:
Runnable() {};
virtual ~Runnable();
virtual void run() = 0;
};
private:
static list<Runnable*> s_Runnables;
static mutex s_MutexLock;
static condition_variable s_ConditionVariable;
static thread 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 */
+950
View File
@@ -0,0 +1,950 @@
/*
* 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_Message.h
* Author: Hagi
*
* Created on 3. April 2019, 08:51
*/
#ifndef SPIT_MESSAGE_H
#define SPIT_MESSAGE_H
#include <cstdlib>
#include <string>
using namespace std;
static const string SPITID = "#spit#";
//static char stringEmpty[] = "";
static char nullChar[] = "\0";
class SPIT_Message {
//----------- Header -----------
public:
class Header {
public:
static const int BYTESLENGTH = 99;
virtual ~Header();
Header(const Header& orig);
Header();
//Members
private:
string m_SPITID;
int m_SPITVersion;
unsigned char m_MessageNumber;
int m_BytesCount;
string m_ServerID;
string m_ClientID;
int m_OPFlag;
int m_ParseOffset = 0;
void initMembers();
public:
const string getSPITID() const {
return m_SPITID;
}
int getSPITVersion() const {
return m_SPITVersion;
}
unsigned char getMessageNumber() const {
return m_MessageNumber;
}
int getBytesCount() const {
return m_BytesCount;
}
const string getServerID() const {
return m_ServerID;
}
const string getClientID() const {
return m_ClientID;
}
int getOPFlag() const {
return m_OPFlag;
}
//Receive
public:
bool parse(char* p_Bytes, int p_ByteCount);
//Send
public:
Header(int p_SPITVersion, int p_OPFlag);
void setMessageNumber(unsigned char p_MessageNumber);
void setServerID(string p_ServerID);
void setClientID(string p_ID);
void setOPFlag(int p_OPFlag);
bool fillBytes(char* p_Bytes, int p_ByteCount);
};
//----------- OPPart -----------
public:
class OPPart {
//Members
protected:
Header* m_Header;
int m_ParseOffset;
int m_BytesCount;
private:
void initMembers();
public:
virtual ~OPPart();
// OPPart(const OPPart& orig);
Header* getHeader() const {
return m_Header;
}
int getBytesCount() const {
return m_BytesCount;
}
const string getServerID() const {
if (m_Header == NULL) return "";
return m_Header->getServerID();
}
const string getClientID() const {
if (m_Header == NULL) return "";
return m_Header->getClientID();
}
int getOPFlag() const {
if (m_Header == NULL) return -1;
return m_Header->getOPFlag();
}
//Receive
public:
OPPart(Header* p_Header, int p_OPFlag);
void setHeader(Header* p_Header);
virtual bool parse(char* p_Bytes, int p_ByteCounth)=0;
//Send
public:
OPPart();
virtual bool fillBytes(char* p_Bytes, int p_ByteCount)=0;
};
//----------- SPIT_Message -----------
public:
static const int SPITVERSION = 1;
//SPIT_Object value usage
static const char VALUEUSE_DISCARD = 0x00; //value of SPITObejct is not used
static const char VALUEUSE_INRANGE = 0x01; //value of SPITOBject in range 0 - 1000000ppm
static const char VALUEUSE_OVERRIDE = 0x02; //value can be overridden
//SPIT Player type
static const char PLAYERTYPE_MAIN = 0x02;
static const char PLAYERTYPE_CONTINIOUS = 0x01;
static const char PLAYERTYPE_DISCRETE = 0x00;
//PlayObject value usage
static const char VALUEFLAG_DIRECT = 0x00; //use the vlue direct
static const char VALUEFLAG_INCREASE = 0x01; //increase the value
static const char VALUEFLAG_DECREASE = 0x02; //decrease the value
SPIT_Message();
virtual ~SPIT_Message();
// SPIT_Message(const SPIT_Message& orig);
//Members
private:
char* m_MessageBytes;
int m_MessageByteCount;
Header* m_Header;
OPPart* m_OPPart;
bool m_MessageBytesCreated;
void initMembers();
//Receive
public:
SPIT_Message(char* p_MessageBytes, int p_MessageBytesLength);
// SPIT_Message(const SPIT_Message& orig);
const Header* getHeader() const {
return m_Header;
}
int getOPFlag() const {
if (m_Header == NULL) return -1;
return m_Header->getOPFlag();
}
const OPPart* getOPPart() const {
return m_OPPart;
}
int getMesageByteCount() const {
return m_MessageByteCount;
}
OPPart* parse();
//Send
public:
SPIT_Message(OPPart* p_OPPart);
bool fillBytes();
const char* getMessageBytes();
//------------------------------ Connection ----------------------------------
//----------- Connect -----------
public:
class Connect : public OPPart {
public:
static const int OPFLAG = 1;
static const int BYTESLENGTH = 304;
private:
string m_ClientComputerName;
string m_ClientName;
string m_LoginName;
string m_LoginPassword;
string m_ServerIP;
int m_ServerPort;
void initMembers();
public:
~Connect();
// Connect(const Connect& orig);
//Receive
public:
Connect(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
const string getClientComputerName() const {
return m_ClientComputerName;
}
const string getClientName() const {
return m_ClientName;
}
const string getLoginName() const {
return m_LoginName;
}
const string getLoginPassword() const {
return m_LoginPassword;
}
const string getServerIP() const {
return m_ServerIP;
}
int getServerPort() const {
return m_ServerPort;
}
//Send
public:
Connect();
void setClientComputerName(string p_ComputerName);
void setClientName(string p_ClientName);
void setLoginName(string p_LoginName);
void setLoginPassword(string p_LoginPassword);
void setServerIP(string p_ServerIP);
void setServerPort(int p_ServerPort);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- ConnectAnswer -----------
class ConnectAnswer : public OPPart {
public:
static const int OPFLAG = 2;
static const int BYTESLENGTH = 137;
private:
string m_ServerComputerName;
string m_ServerName;
bool m_Connected;
int m_StepTime; //ms step size the Server will send play sequences
void initMembers();
public:
~ConnectAnswer();
ConnectAnswer(const ConnectAnswer& orig);
//Receive
ConnectAnswer(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
const string getServerComputerName() const {
return m_ServerComputerName;
}
const string getServerName() const {
return m_ServerName;
}
bool getConnected() const {
return m_Connected;
}
int getStepTime() const {
return m_StepTime;
}
//Send
public:
ConnectAnswer();
void setServerComputerName(string p_ServerComputerName);
void setServerName(string p_ContollerName);
void setConnected(bool p_Connected);
void setStepTime(int p_StepTime_ms);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- Disconnect -----------
class Disconnect : public OPPart {
public:
static const int OPFLAG = 3;
static const int BYTESLENGTH = 4;
private:
void initMembers();
public:
~Disconnect();
Disconnect(const Disconnect& orig);
//Receive
Disconnect(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
// Send
public:
Disconnect();
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- Watchdog -----------
class Watchdog : public OPPart {
public:
static const int OPFLAG = 8;
static const int BYTESLENGTH = 4;
private:
void initMembers();
public:
~Watchdog();
Watchdog(const Watchdog& orig);
//Receive
Watchdog(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
// Send
public:
Watchdog();
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- WatchdogAnswer -----------
class WatchdogAnswer : public OPPart {
public:
static const int OPFLAG = 9;
static const int BYTESLENGTH = 4;
private:
void initMembers();
//Receive
public:
~WatchdogAnswer();
WatchdogAnswer(const WatchdogAnswer& orig);
WatchdogAnswer(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
// Send
public:
WatchdogAnswer();
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//------------------------------ SPITProject ----------------------------------
//----------- ReportSPITProject -----------
class ReportSPITProject : public OPPart {
public:
static const int OPFLAG = 11;
static const int BYTESLENGTH = 113;
private:
string m_ProjectID;
string m_ProjectName;
int m_FramesPerSecond; //Frames per second
void initMembers();
//Receive
public:
~ReportSPITProject();
ReportSPITProject(const ReportSPITProject& orig);
ReportSPITProject(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
const string getProjectID() const {
return m_ProjectID;
}
const string getProjectName() const {
return m_ProjectName;
}
int getFramesPerSecond() const {
return m_FramesPerSecond;
}
// Send
ReportSPITProject();
void setProjectID(string p_ClientID);
void setProjectName(string p_ClientName);
void setFramesPerSecond(const int p_FramesPerSecond);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- CloseSPITProject -----------
class CloseSPITProject : public OPPart {
public:
static const int OPFLAG = 13;
static const int BYTESLENGTH = 45;
private:
string m_ProjectID;
void initMembers();
public:
~CloseSPITProject();
CloseSPITProject(const CloseSPITProject& orig);
//Receive
CloseSPITProject(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
const string getProjectID() const {
return m_ProjectID;
}
// Send
public:
CloseSPITProject();
void setProjectID(string p_ClientID);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- StartProjectTransfer -----------
class RequestProjectTransfer : public OPPart {
public:
static const int OPFLAG = 15;
static const int BYTESLENGTH = 4;
private:
void initMembers();
public:
~RequestProjectTransfer();
RequestProjectTransfer(const RequestProjectTransfer& orig);
//Receive
RequestProjectTransfer(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
// Send
public:
RequestProjectTransfer();
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- StartProjectTransfer -----------
class StartProjectTransfer : public OPPart {
public:
static const int OPFLAG = 16;
static const int BYTESLENGTH = 4;
private:
void initMembers();
public:
~StartProjectTransfer();
StartProjectTransfer(const StartProjectTransfer& orig);
//Receive
StartProjectTransfer(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
// Send
public:
StartProjectTransfer();
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- EndProjectTransfer -----------
class EndProjectTransfer : public OPPart {
public:
static const int OPFLAG = 17;
static const int BYTESLENGTH = 4;
private:
void initMembers();
public:
~EndProjectTransfer();
EndProjectTransfer(const EndProjectTransfer& orig);
//Receive
EndProjectTransfer(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
// Send
EndProjectTransfer();
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//---------------------------- SPIT_Types ----------------------------------
//----------- ReportSPITType -----------
class ReportSPITType : public OPPart {
public:
static const int OPFLAG = 21;
static const int BYTESLENGTH = 168;
private:
bool m_Confirmed;
string m_SPITTypeID;
bool m_Fixed;
bool m_ServerRemote;
bool m_ServerProjectIndepended;
string m_SPITTypeGroupName;
string m_SPITTypeName;
long long m_Delay;
long long m_Duration;
void initMembers();
public:
~ReportSPITType();
ReportSPITType(const ReportSPITType& orig);
//Receive
ReportSPITType(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
bool getConfirmed() const {
return m_Confirmed;
}
const string getID() const {
return m_SPITTypeID;
}
bool getFixed() const {
return m_Fixed;
}
bool getServerRemote() const {
return m_ServerRemote;
}
bool getServerProjectIndepended() const {
return m_ServerProjectIndepended;
}
const string getGroupName() const {
return m_SPITTypeGroupName;
}
const string getName() const {
return m_SPITTypeName;
}
long long getDelay() const {
return m_Delay;
}
long long getDuration() const {
return m_Duration;
}
// Send
public:
ReportSPITType();
void setConfirmed(bool p_Confirmed);
void setID(string p_ID);
void setFixed(bool p_Fixed);
void setServerRemote(bool p_IsServerRemote);
void setServerProjectIndepended(bool p_ProjectIndpended);
void setGroupName(string p_GroupName);
void setName(string p_Name);
void setDelay(long long p_Delay);
void setDuration(long long p_Duration);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- RemoveSPITType -----------
class RemoveSPITType : public OPPart {
public:
static const int OPFLAG = 23;
static const int BYTESLENGTH = 45;
private:
string m_SPITTypeID;
void initMembers();
public:
~RemoveSPITType();
RemoveSPITType(const RemoveSPITType& orig);
//Receive
RemoveSPITType(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
const string getID() const {
return m_SPITTypeID;
}
// Send
RemoveSPITType();
void setID(string p_ID);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//---------------------------- SPITObjects ----------------------------------
//----------- ReportSPITObject -----------
class ReportSPITObject : public OPPart {
public:
static const int OPFLAG = 31;
static const int BYTESLENGTH = 339;
private:
bool m_Confirmed;
string m_SPITObjectID;
bool m_Fixed;
bool m_ServerRemote;
string m_SPITObjectName;
string m_SPITTypeID;
string m_ServerParams;
long long m_FrameStart;
long long m_FrameLength;
long long m_FrameFadeInLength;
long long m_FrameFadeOutLength;
int m_ValueFactor;
char m_ValueUse;
int m_Track;
string m_Remark;
long long m_Delay;
long long m_Duration;
bool m_ActionAssigned;
void initMembers();
public:
~ReportSPITObject();
ReportSPITObject(const ReportSPITObject& orig);
//Receive
ReportSPITObject(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
bool getConfirmed() const {
return m_Confirmed;
}
const string getID() const {
return m_SPITObjectID;
}
bool getFixed() const {
return m_Fixed;
}
bool getServerRemote() const {
return m_ServerRemote;
}
const string getName() const {
return m_SPITObjectName;
}
const string getSPITTypeID() const {
return m_SPITTypeID;
}
const string getServerParams() const {
return m_ServerParams;
}
long long getFrameStart() const {
return m_FrameStart;
}
long long getFrameLength() const {
return m_FrameLength;
}
long long getFrameFadeInLength() const {
return m_FrameFadeInLength;
}
long long getFrameFadeOutLength() const {
return m_FrameFadeOutLength;
}
int getValueFactor() const {
return m_ValueFactor;
}
char getValueUse() const {
return m_ValueUse;
}
int getTrack() const {
return m_Track;
}
const string getRemark() const {
return m_Remark;
}
long long getDelay() const {
return m_Delay;
}
long long getDuration() const {
return m_Duration;
}
bool getActionAssigned() const {
return m_ActionAssigned;
}
// Send
public:
ReportSPITObject();
void setConfirmed(bool p_Confirmed);
void setID(string p_ID);
void setFixed(bool p_Fixed);
void setServerRemote(bool p_IsRemote);
void setName(string p_Name);
void setSPITTypeID(string p_ID);
void setServerParams(string p_Parameters);
void setFrameStart(long long p_StartTime);
void setFrameLength(long long p_Length);
void setFrameFadeInLength(long long p_FadeInTime);
void setFrameFadeOutLength(long long p_FadeOutTime);
void setValueFactor(int p_Volume);
void setValueUse(char p_ValueUse);
void setTrack(int p_Track);
void setRemark(string p_Description);
void setDelay(long long p_Delay);
void setDuration(long long p_Duration);
void setActionAssigned(bool p_ActionAssigned);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- RemoveSPITObject -----------
class RemoveSPITObject : public OPPart {
public:
static const int OPFLAG = 33;
static const int BYTESLENGTH = 45;
private:
string m_SPITObjectID;
void initMembers();
public:
~RemoveSPITObject();
RemoveSPITObject(const RemoveSPITObject& orig);
//Receive
RemoveSPITObject(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
const string getID() const {
return m_SPITObjectID;
}
// Send
public:
RemoveSPITObject();
void setID(string p_ID);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//---------------------------- SPITPlayer ----------------------------------
//----------- PlaySPITStart -----------
class PlaySPITStart : public OPPart {
public:
static const int OPFLAG = 37;
static const int BYTESLENGTH = 119;
private:
string m_PlayerID;
string m_PlayerName;
char m_PlayerType;
bool m_PlayerIsRunning;
long long m_Time; //Frames
void initMembers();
public:
~PlaySPITStart();
PlaySPITStart(const PlaySPITStart& orig);
//Receive
PlaySPITStart(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
const string getPlayerID() const {
return m_PlayerID;
}
const string getPlayerName() const {
return m_PlayerName;
}
char getPlayerType() const {
return m_PlayerType;
}
bool getPlayerIsRunning() const {
return m_PlayerIsRunning;
}
long long getTime() const {
return m_Time;
}
// Send
public:
PlaySPITStart();
void setPlayerID(string p_PlayerID);
void setPlayerName(string p_PlayerName);
void setPlayerType(char p_PlayerType);
void setPlayerIsRunning(bool p_IsPlaying);
void setTime(long long p_Time);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- PlaySPITObject -----------
class PlaySPITObject : public OPPart {
public:
static const int OPFLAG = 38;
static const int BYTESLENGTH = 100;
private:
string m_PlayerID;
string m_SPITObjectID;
long long m_FrameInsideObject; //Frames
bool m_PlayPrePosition;
int m_Value;
char m_ValueFlag;
void initMembers();
public:
~PlaySPITObject();
PlaySPITObject(const PlaySPITObject& orig);
//Receive
PlaySPITObject(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
const string getPlayerID() const {
return m_PlayerID;
}
const string getSPITObjectID() const {
return m_SPITObjectID;
}
long long getFrameInsideObject() const {
return m_FrameInsideObject;
}
bool getPlayPrePosition() const {
return m_PlayPrePosition;
}
int getValue() const {
return m_Value;
}
char getValueFlag() const {
return m_ValueFlag;
}
// Send
PlaySPITObject();
void setPlayerID(string p_PlayerID);
void setID(string p_ID);
void setFrameInsideObject(long long p_TimeInside);
void setPlayPrePosition(bool p_PlayOldPosition);
void setValue(int p_Value);
void setValueFlag(char p_ValueFlag);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- PlaySPITEnd -----------
class PlaySPITEnd : public OPPart {
public:
static const int OPFLAG = 39;
static const int BYTESLENGTH = 45;
private:
string m_PlayerID;
void initMembers();
public:
~PlaySPITEnd();
PlaySPITEnd(const PlaySPITEnd& orig);
//Receive
PlaySPITEnd(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
const string getPlayerID() const {
return m_PlayerID;
}
// Send
public:
PlaySPITEnd();
void setPlayerID(string p_PlayerID);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------- ReportPlayStatus -----------
class ReportPlayStatus : public OPPart {
public:
static const int OPFLAG = 40;
static const int BYTESLENGTH = 57;
private:
string m_SPITObjectID;
long long m_FrameInsideObject; //Frames
int m_Value;
void initMembers();
public:
~ReportPlayStatus();
ReportPlayStatus(const ReportPlayStatus& orig);
//Receive
ReportPlayStatus(Header* p_Header);
bool parse(char* p_Bytes, int p_ByteCount);
const string getID() const {
return m_SPITObjectID;
}
long long getFrameInsideObject() const {
return m_FrameInsideObject;
}
int getValue() const {
return m_Value;
}
// Send
ReportPlayStatus();
void setID(string p_ID);
void setFrameInsideObject(long long p_TimeInside);
void setValue(int p_Value);
bool fillBytes(char* p_MessageBytes, int p_ByteCount);
};
//----------------------- static helper functions ----------------------------
public:
static bool isSystemLittleEndian();
static int getInt(char* p_Bytes, int p_ByteCount, int p_Offset);
static int setInt(int p_Value, char* p_Bytes, int p_ByteCount, int p_Offset);
static long long getLong(char* p_Bytes, int p_ByteCount, int p_Offset);
static int setLong(long long p_Value, char* p_Bytes, int p_ByteCount, int p_Offset);
static bool getBoolean(char* p_Bytes, int p_ByteCount, int p_Offset);
static int setBoolean(bool p_Value, char* p_Bytes, int p_ByteCount, int p_Offset);
static char getByte(char* p_Bytes, int p_ByteCount, int p_Offset);
static int setByte(int p_Value, char* p_Bytes, int p_ByteCount, int p_Offset);
/**
* Returns the string char* of the part of the byte sequence (0x00 null terminated).
* @param p_Bytes the byte array
* @param p_Offset the startposition of strings bytes
* @param p_Length the length of the string included the null terminate byte (0x00).<br>
* The length of the string will be p_Length -1.
* @return the String char*
* @throws Exception if p_Bytes == null<br>
* p_Offset less than 0<br>
* p_Bytes.length less than p_Offset + p_Length<br>
* No 0x00 null terminate byte is found
*/
static string getString(char* p_Bytes, int p_ByteCount, int p_Offset, int p_Length);
/**
* Fill the p_String in the byte array.<br>
* If p_String length is greater than p_Length -1, the p_String will be truncated.
* CAUTION the return value should be freed after use.
* @param p_String the string
* @param p_Bytes the byte array where the string is filled
* @param p_Offset the offset inside the byte array
* @param p_Length the maximal length of the string included the null character.<br>
* @throws Exception if p_String == NULL, p_Bytes == NULL<br>
* p_Offset less than 0<br>
* p_ByteCount less than p_Offset + p_Length
* @return p_Length
*/
static int setString(string p_String, char* p_Bytes, int p_ByteCount, int p_Offset, int p_Length);
/**
* Compares two strings for equality.
* @param p_String1 string terminated by null character
* @param p_String2 string terminated by null character
* @return true if both strings are equal<br>
* false if the strings are NULL or not equal or not terminated by "\0"
*/
// static bool stringEqual(const char* p_String1, const char* p_String2);
// static char* stringCopy(const char* p_String);
static char* createByteArray(const OPPart* p_OPPart, int* p_BytesCount);
};
#endif /* SPIT_MESSAGE_H */
+56
View File
@@ -0,0 +1,56 @@
/*
* 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"
#if defined(OS_MAC) || defined(OS_LINUX)
#include <ifaddrs.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <thread>
#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
#endif /* UNIXSOCKET_H */
+56
View File
@@ -0,0 +1,56 @@
/*
* 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>
#include <condition_variable>
#include <thread>
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;
mutex m_MutexLock;
condition_variable m_ConditionVariable;
thread* m_WatchdogThread;
bool m_Answered;
void runWatchdog();
public:
void startWatchdog();
void answerWatchdog();
void stopWatchdog();
};
#endif /* WATCHDOG_H */
+53
View File
@@ -0,0 +1,53 @@
/*
* 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: WindowsSocket.h
* Author: Hagi
*
* Created on 11. April 2019, 08:36
*/
#ifndef WINDOWSSOCKET_H
#define WINDOWSSOCKET_H
#include "_SPITMACROS.h"
#if defined(OS_WINDOWS)
#include "WindowsSocket.h"
#include <WinSock2.h>
#include <iphlpapi.h>
#include <ws2tcpip.h>
#include <thread>
#include "SPITSocket.h"
using namespace std;
class WindowsSocket : public SPITSocket{
public:
WindowsSocket();
virtual ~WindowsSocket();
private:
SOCKET m_UDPSocketIP4;
SOCKET 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
#endif /* WINDOWSSOCKET_H */
+57
View File
@@ -0,0 +1,57 @@
/*
* 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: _SPITMACROS.h
* Author: Hagi
*
* Created on 13. April 2019, 13:37
*/
#ifndef _SPITMACROS_H
#define _SPITMACROS_H
//To compile for a specific operating system, you must change the precompiler comments.
//In windows Ws2_32.lib Iphlpapi.lib (in gcc: -liphlpapi -lole32) should be added to the linker options
#ifndef OS_WINDOWS
// #define OS_WINDOWS
// #include <WinSock2.h> //include this here, because it must be included before string.h .. is included
#endif
#ifndef OS_MAC
// #define OS_MAC
// #include <unistd.h>
// #include<uuid/uuid.h>
#endif
#ifndef OS_LINUX
#define OS_LINUX
#include <unistd.h>
#include<uuid/uuid.h>
#endif
//To output debug information (printf calls in the code)
//you must set or comment out this precompiler definition
#ifndef DEBUGOUTPUT
#define DEBUGOUTPUT
#endif
#include <string>
using namespace std;
//--------- OS specific functions ---------
/** Returns an guid */
string createGUID();
/** Returns the name of the client's host computer*/
string getClientHostName();
#endif /* _SPITMACROS_H */