Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 348a1a1e14 | |||
| 118291f8ab | |||
| 4a97988227 | |||
| 7aec14cbb9 |
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
if(TgtEnv STREQUAL "Host")
|
||||
message("Using Host-Branch")
|
||||
enable_testing()
|
||||
add_subdirectory("test/unitOnHost")
|
||||
elseif(TgtEnv STREQUAL "Target")
|
||||
# add_subdirectory("test/unitOnTarget")
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "sad_DetectedServer.hpp"
|
||||
#include "spit_message.hpp"
|
||||
#include "spit_object.hpp"
|
||||
#include "spit_player.hpp"
|
||||
#include "spit_processor.hpp"
|
||||
#include "spit_repo.hpp"
|
||||
#include "spit_socket.hpp"
|
||||
#include "spit_type.hpp"
|
||||
#include "spit_message.hpp"
|
||||
#include "spit_repo.hpp"
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include "syslog.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -19,60 +18,34 @@ namespace spit {
|
||||
|
||||
class SClient : ISadClient {
|
||||
public:
|
||||
/** Maximal length of a SPITMessage*/
|
||||
static const int MAXSPITMESSAGEBYTECOUNT = 512;
|
||||
|
||||
using Callbacks = SProcessor::Callbacks;
|
||||
using ProjUpdate = SProcessor::ProjUpdate;
|
||||
using ServerEvent = SProcessor::ServerEvent;
|
||||
using ObjectEvent = SProcessor::ObjectEvent;
|
||||
using Connection = SProcessor::Connection;
|
||||
|
||||
//------ 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 constexpr char PLAYERTYPE_MAIN = 0x02;
|
||||
/** continous player. This player plays SPIT objects sometime during the project.*/
|
||||
static constexpr char PLAYERTYPE_CONTINOUS = 0x01;
|
||||
/** diescrete player. This player is used to transmit single discrete values.*/
|
||||
static constexpr char PLAYERTYPE_DISCRETE = 0x00;
|
||||
using PlayerType = SPlayer::PTypes;
|
||||
using ValueFlags = SPlayer::VFlags;
|
||||
|
||||
//------ Value Flag ------
|
||||
//------ used by sendRemoteObject
|
||||
public:
|
||||
/**Set the given value directly*/
|
||||
static constexpr char VALUEFLAG_DIRECT = 0x00;
|
||||
/**Increase the existing value by the given value.<br>This is usefull e.g. when instead of a fader a endless wheel is used*/
|
||||
static constexpr char VALUEFLAG_INCREASE = 0x01;
|
||||
/**Decrease the existing value by the given value.<br>This is usefull e.g. when instead of a fader a endless wheel is used*/
|
||||
static constexpr char VALUEFLAG_DECREASE = 0x02;
|
||||
static constexpr int MAX_OVERTAKING_SPIT_MESSAGES = 10;
|
||||
|
||||
//----- SClient -----
|
||||
public:
|
||||
SClient(string name, string projName, ISocket &socket, Callbacks calls);
|
||||
virtual ~SClient();
|
||||
|
||||
|
||||
private:
|
||||
Callbacks mCallbacks;
|
||||
|
||||
fos::TaskT<SClient &> *mThreadReceive{};
|
||||
fos::TaskT<SClient &> *mThreadProcess{};
|
||||
bool mStopReceiveMessages{};
|
||||
|
||||
Connection mConnectionStatus{Connection::None};
|
||||
bool mDisconnectedByServer{}; // flag true = when server disconnects
|
||||
string mID;
|
||||
string mName;
|
||||
string mProjName;
|
||||
string mComputerName;
|
||||
|
||||
SProcessor mProcessor;
|
||||
|
||||
string mClientProjectName;
|
||||
|
||||
uint8_t mMessageNumberSend{1};
|
||||
int mMessageNumberReceived{-1}; // set to -1 because the first received message will set the number (1..255)
|
||||
vector<unique_ptr<Message>> mOvertakingMessages;
|
||||
|
||||
// Server's info filled by parseConnectAnswer
|
||||
string mServerID{};
|
||||
@@ -80,19 +53,13 @@ class SClient : ISadClient {
|
||||
string mServerComputerName{};
|
||||
int mServerStepTime{-1};
|
||||
|
||||
//--- Server Project ---
|
||||
string mServerProjectID;
|
||||
string mServerProjectName;
|
||||
int mServerFramesPerSecond;
|
||||
|
||||
public:
|
||||
/** The ID of the client.<br>Every client instance should set an unique id*/
|
||||
string getID() { return mID; }
|
||||
string getID() { return mProcessor.getID(); }
|
||||
/** The name of the client, should be set by the user app*/
|
||||
string getName() { return mName; }
|
||||
//----- Computer Params -----
|
||||
string getName() { return mProcessor.getName(); }
|
||||
/** The name of the client's host computer*/
|
||||
string getComputerName() { return mComputerName; }
|
||||
string getComputerName() { return mProcessor.getComputerName(); }
|
||||
void setClientProjectName(string clientProjectName) { mClientProjectName = clientProjectName; }
|
||||
string getClientProjectName() { return mClientProjectName; }
|
||||
|
||||
@@ -117,8 +84,12 @@ class SClient : ISadClient {
|
||||
*/
|
||||
void clientProjectLoaded();
|
||||
|
||||
void setActionSPITType(string spitypeID, bool actionAssigned);
|
||||
void setActionSPITObject(string objectID, bool actionAssigned);
|
||||
void setActionType(string spitypeID, bool actionAssigned) {
|
||||
mProcessor.setActionType(spitypeID, actionAssigned);
|
||||
}
|
||||
void setActionObject(string objectID, bool actionAssigned) {
|
||||
mProcessor.setActionObject(objectID, actionAssigned);
|
||||
}
|
||||
|
||||
//--------------- SPITMessage ---------------
|
||||
private:
|
||||
@@ -129,7 +100,7 @@ class SClient : ISadClient {
|
||||
// Reconnect to the server when connection is lost see eventConnectionStatus and eventServerDetected
|
||||
bool _doReconnect{}; // true = on eventServerDetected connect to the server identified by mServerID
|
||||
public:
|
||||
int sendSPITMessage(Message::OPPart & spitMessageOPPart);
|
||||
int sendMessage(Message::OPPart &spitMessageOPPart);
|
||||
|
||||
//--------------- ServerAutoDetection SAD ---------------
|
||||
public:
|
||||
@@ -165,7 +136,7 @@ class SClient : ISadClient {
|
||||
private:
|
||||
void disconnectInternal(Connection cause);
|
||||
void resetMessageNumberReceived();
|
||||
void parseMessage(unique_ptr<Message> message);
|
||||
void parseMessage(Message& message);
|
||||
void checkParseMessage(unique_ptr<Message> message);
|
||||
void addOvertakingMessage(unique_ptr<Message> message);
|
||||
void parseConnectAnswer(Message::ConnectAnswer &message);
|
||||
@@ -179,22 +150,13 @@ class SClient : ISadClient {
|
||||
/** Used internally. When the connection to the SPITServer is lost an eventConnectionStatus will occur*/
|
||||
void eventWatchdogLost();
|
||||
//--------------- SPIT Project ---------------
|
||||
private:
|
||||
void parseReportProject(Message::ReportProject &message);
|
||||
void parseCloseProject(Message::CloseProject &message);
|
||||
|
||||
public:
|
||||
/** Returns the SPITServer's project ID - may be the same as the project's name*/
|
||||
string getServerProjectID();
|
||||
string getServerProjectID() { return mProcessor.getServerProjectID(); }
|
||||
/** Returns the SPITServer's project name*/
|
||||
string getServerProjectName();
|
||||
string getServerProjectName() { return mProcessor.getServerProjectName(); }
|
||||
/** Returns frame rate per second. This is the time resolution in which the server transmits time data. The unit of time data is always frames.*/
|
||||
int getServerFramesPerSecond();
|
||||
|
||||
private:
|
||||
void parseRequestProjectTransfer(Message::RequestProjectTransfer &message);
|
||||
void parseStartProjectTransfer(Message::StartProjectTransfer &message);
|
||||
void parseEndProjectTransfer(Message::EndProjectTransfer &message);
|
||||
int getServerFramesPerSecond() { return mProcessor.getServerFramesPerSecond(); }
|
||||
|
||||
public:
|
||||
static void sendProject(SClient *p_PtrSClient);
|
||||
@@ -214,76 +176,17 @@ class SClient : ISadClient {
|
||||
*/
|
||||
SType *createTypeFixed(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t 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.
|
||||
*/
|
||||
SType *createType(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration, bool fixed, bool projectIndepended);
|
||||
|
||||
private:
|
||||
// receive SPIT-Types
|
||||
void parseReportType(Message::ReportType &message);
|
||||
void parseRemoveSPITType(Message::RemoveType &message);
|
||||
int sendSPITTypeInternal(SType &spitType);
|
||||
public:
|
||||
bool changeType(SType *spitType) { return mProcessor.changeType(spitType); }
|
||||
int removeType(string spitypeID) { return mProcessor.removeType(spitypeID); }
|
||||
|
||||
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 spitypeID the id of the SPITType to remove.
|
||||
* @return 0 = is sended, -1 = is not sended
|
||||
*/
|
||||
bool changeSPITType(SType *spitType);
|
||||
/**
|
||||
* If a client wants to remove a SPITType, he should send it to the server.<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 spitypeID the id of the SPITType to remove.
|
||||
* @return 0 = is sended, -1 = is not sended
|
||||
*/
|
||||
int removeSPITType(string spitypeID);
|
||||
|
||||
public:
|
||||
//--------------- SPIT Objects ---------------
|
||||
private:
|
||||
void parseReportSPITObject(Message::ReportObject &message);
|
||||
void parseRemoveSPITObject(Message::RemoveObject &message);
|
||||
int sendSPITObjectInternal(SObject *ptrObject);
|
||||
|
||||
public:
|
||||
/**
|
||||
* When the client changes a SPITObject (normally the client should not do this), then it should send the changes to the SPITServer.<br>
|
||||
* The SPITServer may discard the changes and an eventSPITObject occurs.<br>
|
||||
* @param spitObject the pointer to the changed SPITObject.
|
||||
* @return 0 = sended, -1 = not sended
|
||||
*/
|
||||
bool changeSPITObject(SObject *spitObject);
|
||||
/**
|
||||
* When the client removes a SPITObject (normally the client should not do this), then he should send it to the SPITServer.<br>
|
||||
* The SPITServer may discard the deletion and an eventSPITObject occurs.<br>
|
||||
* @param objectID the id of the SPITObject to remove.
|
||||
* @return 0 = sended, -1 = not sended
|
||||
*/
|
||||
int removeSPITObject(string objectID);
|
||||
|
||||
public:
|
||||
//--------------- Play SPIT Objects ---------------
|
||||
private:
|
||||
void parsePlaySPITStart(Message::PlayStart &message);
|
||||
void parsePlaySPITObject(Message::PlayObject &message);
|
||||
void parsePlaySPITEnd(Message::PlayEnd &message);
|
||||
void parseReportPlayStatus(Message::ReportPlayStatus &message);
|
||||
|
||||
public:
|
||||
//--------- Remote ----------
|
||||
void sendRemoteObject(string objectID, int valuePpm = 0, char valueFlag = 0x00);
|
||||
bool changeObject(SObject *sObject) { return mProcessor.changeObject(sObject); }
|
||||
void sendRemoteObject(string objectID, int valuePpm = 0, char valueFlag = 0x00) {
|
||||
mProcessor.sendRemoteObject(objectID, valuePpm, valueFlag);
|
||||
}
|
||||
|
||||
private:
|
||||
static void processSocketTask(SClient &instance);
|
||||
@@ -295,9 +198,6 @@ class SClient : ISadClient {
|
||||
void answerWatchdog() {
|
||||
sAnswered = true;
|
||||
}
|
||||
|
||||
SpitRepo<SObject> mSpitObjects;
|
||||
SpitRepo<SObject> mRemoteSpitObjects;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace spit
|
||||
@@ -14,6 +14,9 @@ namespace spit {
|
||||
class Message {
|
||||
//----------- Header -----------
|
||||
public:
|
||||
/** Maximal length of a SPITMessage*/
|
||||
static const int MAX_MESSAGE_SIZE = 512;
|
||||
|
||||
class Header {
|
||||
public:
|
||||
static constexpr int BYTESLENGTH = 99;
|
||||
|
||||
@@ -9,6 +9,24 @@ class SPlayer {
|
||||
|
||||
//----- PlayObject used in PlaySequences: PlaySPITStart, PlaySPITObject,..., PlaySPITEnd ------
|
||||
public:
|
||||
enum PTypes {
|
||||
// diescrete player: This player is used to transmit single discrete values.
|
||||
PTYPE_DISCRETE = 0x00,
|
||||
// continous player: This player plays SPIT objects sometime during the project.
|
||||
PTYPE_CONTINOUS = 0x01,
|
||||
// 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.
|
||||
PTYPE_MAIN = 0x02,
|
||||
};
|
||||
|
||||
enum VFlags {
|
||||
// Set the given value directly
|
||||
VFLAG_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*/
|
||||
VFLAG_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*/
|
||||
VFLAG_DECREASE = 0x02,
|
||||
};
|
||||
|
||||
class PlayType {
|
||||
public:
|
||||
PlayType(SPlayer *spitPlayer, string spitObjectID);
|
||||
@@ -77,4 +95,4 @@ class SPlayer {
|
||||
uint64_t mTimeFrames;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace spit
|
||||
@@ -16,9 +16,6 @@ namespace spit {
|
||||
|
||||
class SProcessor {
|
||||
public:
|
||||
// /** Maximal length of a SPITMessage*/
|
||||
// static const int MAXSPITMESSAGEBYTECOUNT = 512;
|
||||
|
||||
enum class ProjUpdate {
|
||||
ServerLoaded,
|
||||
StartTransfer,
|
||||
@@ -57,28 +54,12 @@ class SProcessor {
|
||||
};
|
||||
|
||||
struct InternalCallbacks {
|
||||
function<int(SType &sType)> sendSpitTypeInternal;
|
||||
function<void(int ms)> delay;
|
||||
function<int(Message::OPPart &msg)> sendMessage;
|
||||
function<void(Message &msg)> parseMessage;
|
||||
};
|
||||
|
||||
// //------ 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 constexpr char PLAYERTYPE_MAIN = 0x02;
|
||||
// /** continous player. This player plays SPIT objects sometime during the project.*/
|
||||
// static constexpr char PLAYERTYPE_CONTINOUS = 0x01;
|
||||
// /** diescrete player. This player is used to transmit single discrete values.*/
|
||||
// static constexpr char PLAYERTYPE_DISCRETE = 0x00;
|
||||
|
||||
// //------ Value Flag ------
|
||||
// //------ used by sendRemoteObject
|
||||
// public:
|
||||
// /**Set the given value directly*/
|
||||
// static constexpr char VALUEFLAG_DIRECT = 0x00;
|
||||
// /**Increase the existing value by the given value.<br>This is usefull e.g. when instead of a fader a endless wheel is used*/
|
||||
// static constexpr char VALUEFLAG_INCREASE = 0x01;
|
||||
// /**Decrease the existing value by the given value.<br>This is usefull e.g. when instead of a fader a endless wheel is used*/
|
||||
// static constexpr char VALUEFLAG_DECREASE = 0x02;
|
||||
// static constexpr int MAX_OVERTAKING_SPIT_MESSAGES = 10;
|
||||
static constexpr int MAX_OVERTAKING_SPIT_MESSAGES = 10;
|
||||
|
||||
//----- SProcessor -----
|
||||
public:
|
||||
@@ -90,154 +71,40 @@ class SProcessor {
|
||||
Callbacks mCallbacks;
|
||||
InternalCallbacks mInternCallbacks;
|
||||
|
||||
// Connection mConnectionStatus{Connection::None};
|
||||
// bool mDisconnectedByServer{}; // flag true = when server disconnects
|
||||
string mGuid;
|
||||
string mName;
|
||||
string mGuid;
|
||||
string mProjName;
|
||||
string mComputerName;
|
||||
|
||||
// string mClientProjectName;
|
||||
uint8_t mMessageNumberSend{1};
|
||||
int mMessageNumberReceived{-1}; // set to -1 because the first received message will set the number (1..255)
|
||||
vector<unique_ptr<Message>> mOvertakingMessages;
|
||||
|
||||
// uint8_t mMessageNumberSend{1};
|
||||
// int mMessageNumberReceived{-1}; // set to -1 because the first received message will set the number (1..255)
|
||||
// vector<unique_ptr<Message>> mOvertakingMessages;
|
||||
string mServerID{};
|
||||
string mServerProjectID;
|
||||
string mServerProjectName;
|
||||
int mServerFramesPerSecond;
|
||||
|
||||
// // Server's info filled by parseConnectAnswer
|
||||
// string mServerID{};
|
||||
// string mServerName{};
|
||||
// string mServerComputerName{};
|
||||
// int mServerStepTime{-1};
|
||||
public:
|
||||
string getID() { return mGuid; }
|
||||
string getName() { return mName; }
|
||||
string getProjName() { return mProjName; }
|
||||
string getComputerName() { return mComputerName; }
|
||||
void setActionType(string spitypeID, bool actionAssigned);
|
||||
void setActionObject(string objectID, bool actionAssigned);
|
||||
void checkParseMessageData(vector<char> data);
|
||||
|
||||
// //--- Server Project ---
|
||||
// string mServerProjectID;
|
||||
// string mServerProjectName;
|
||||
// int mServerFramesPerSecond;
|
||||
unique_ptr<Message::Connect> createConnectMessage(string serverIP, string serverPort, string loginName, string loginPassword);
|
||||
|
||||
// public:
|
||||
// /** The ID of the client.<br>Every client instance should set an unique id*/
|
||||
// string getID() { return mGuid; }
|
||||
// /** The name of the client, should be set by the user app*/
|
||||
// string getName() { return mName; }
|
||||
// //----- Computer Params -----
|
||||
// /** The name of the client's host computer*/
|
||||
// string getComputerName() { return mComputerName; }
|
||||
// void setClientProjectName(string clientProjectName) { mClientProjectName = clientProjectName; }
|
||||
// string getClientProjectName() { return mClientProjectName; }
|
||||
std::vector<char> createMessage(Message::OPPart &spitMessageOPPart);
|
||||
void parseMessage(Message &message);
|
||||
void addOvertakingMessage(unique_ptr<Message> message);
|
||||
int sendOvertakingMessage(int msgNumRec);
|
||||
void resetMessageNumberReceived();
|
||||
|
||||
// // connected Server Infos
|
||||
// /** The ID of the connected SPITServer*/
|
||||
// string getServerID() { return mServerID; }
|
||||
// /** The host computername of the connected SPITServer*/
|
||||
// string getServerComputerName() { return mServerComputerName; }
|
||||
// /** The name of the connected SPITServer*/
|
||||
// string getServerName() { return mServerName; }
|
||||
|
||||
// /** Expected Refreah Rate of the connectd SPITServer.<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() { return mServerStepTime; }
|
||||
|
||||
// /** Should be called when the client wants to close his project*/
|
||||
// void clientProjectClose();
|
||||
// /**
|
||||
// * Should be called whenever the client has a project loaded
|
||||
// */
|
||||
// void clientProjectLoaded();
|
||||
|
||||
// void setActionSPITType(string spitypeID, bool actionAssigned);
|
||||
// void setActionSPITObject(string objectID, bool actionAssigned);
|
||||
|
||||
// //--------------- SPITMessage ---------------
|
||||
// private:
|
||||
// // Reconnect to the server when connection is lost see eventConnectionStatus and eventServerDetected
|
||||
// bool _doReconnect{}; // true = on eventServerDetected connect to the server identified by mServerID
|
||||
// public:
|
||||
// std::vector<char> createMessage(Message::OPPart & spitMessageOPPart);
|
||||
// void checkParseMessageData(vector<char> data);
|
||||
|
||||
// //--------------- ServerAutoDetection SAD ---------------
|
||||
// public:
|
||||
// /** Starts the autodetection of SPITServers in the local network. If a connection is tried, the autodetection should be stopped before.*/
|
||||
// void startServerAutoDetect();
|
||||
// /** Stops the autodetection of SPITServers in the local network*/
|
||||
// void stopServerAutoDetect();
|
||||
// /** Called every time a new SPITServer is detetced in the local network */
|
||||
// void eventServerDetected(SadDetectedServer &server);
|
||||
// /** Called every time a prior detected SPITServer is is no longer found.*/
|
||||
// void eventServerLost(SadDetectedServer &server);
|
||||
// void eventServerChanged(SadDetectedServer &server);
|
||||
|
||||
// //--------------- Connection ---------------
|
||||
// public:
|
||||
// /**
|
||||
// * Tries a connection to the SPITServer
|
||||
// * @param p_ServerIP ip address of the SPITServer
|
||||
// * @param p_ServerPort port of the SPITServer
|
||||
// * @param p_ClientIP IP of the client
|
||||
// * @param p_ClientPort if "0" any free port will be used
|
||||
// * @param p_LoginName maybe some SPITServer need a login - liveSHOWsoftware will not.
|
||||
// * @param p_LoginPassword maybe some SPITServer need a login - liveSHOWsoftware will not
|
||||
// * @return true = the connection try is ok, SPITServer will answer with COnnectAnswer and an eventConnectionStatus will occur.<br>
|
||||
// * false = something is going wrong. (client could not bind)
|
||||
// */
|
||||
// bool connect(string serverIP, string serverPort, string clientIP, string clientPort, string loginName = "", string loginPassword = "");
|
||||
// /**
|
||||
// * Terminates the connection to the SPITServer.
|
||||
// */
|
||||
// void disconnect();
|
||||
|
||||
// private:
|
||||
// void disconnectInternal(Connection cause);
|
||||
// void resetMessageNumberReceived();
|
||||
// void parseMessage(Message& message);
|
||||
// void addOvertakingMessage(unique_ptr<Message> message);
|
||||
// void parseConnectAnswer(Message::ConnectAnswer &message);
|
||||
// void parseDisconnect(Message::Disconnect &message);
|
||||
// void parseWatchdog(Message::Watchdog &message);
|
||||
// void parseWatchdogAnswer(Message::WatchdogAnswer &message);
|
||||
|
||||
// public:
|
||||
// /** Used internally*/
|
||||
// void sendWatchdog();
|
||||
// /** Used internally. When the connection to the SPITServer is lost an eventConnectionStatus will occur*/
|
||||
// void eventWatchdogLost();
|
||||
// //--------------- SPIT Project ---------------
|
||||
// private:
|
||||
// void parseReportProject(Message::ReportProject &message);
|
||||
// void parseCloseProject(Message::CloseProject &message);
|
||||
|
||||
// public:
|
||||
// /** Returns the SPITServer's project ID - may be the same as the project's name*/
|
||||
// string getServerProjectID();
|
||||
// /** Returns the SPITServer's project name*/
|
||||
// string getServerProjectName();
|
||||
// /** Returns frame rate per second. This is the time resolution in which the server transmits time data. The unit of time data is always frames.*/
|
||||
// int getServerFramesPerSecond();
|
||||
|
||||
// private:
|
||||
// void parseRequestProjectTransfer(Message::RequestProjectTransfer &message);
|
||||
// void parseStartProjectTransfer(Message::StartProjectTransfer &message);
|
||||
// void parseEndProjectTransfer(Message::EndProjectTransfer &message);
|
||||
|
||||
// public:
|
||||
// // static void sendProject(SClient *p_PtrSProcessor);
|
||||
|
||||
// // --------------- SPIT Types ---------------
|
||||
// public:
|
||||
// /**
|
||||
// * Creates a fixed SPITType for application actions that are always present and project independent.<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.
|
||||
// */
|
||||
// SType *createTypeFixed(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration);
|
||||
string getServerProjectID() { return mServerProjectID; }
|
||||
string getServerProjectName() { return mServerProjectName; }
|
||||
int getServerFramesPerSecond() { return mServerFramesPerSecond; }
|
||||
|
||||
// /**
|
||||
// * Creates a SPITType for application actions.<br>
|
||||
@@ -251,75 +118,51 @@ class SProcessor {
|
||||
// * @param p_ProjectIndepended true = the SPITType belongs to a specific project, false = the SpitType always exists for every project
|
||||
// * @return the pointer to the new SPITType.
|
||||
// */
|
||||
// SType *createType(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration, bool fixed, bool projectIndepended);
|
||||
SType *createType(string iD, string groupName, string name, uint64_t defaultDelay, uint64_t defaultDuration, bool fixed, bool projectIndepended);
|
||||
int sendTypeInternal(SType &sType);
|
||||
|
||||
/**
|
||||
* 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 spitypeID the id of the SPITType to remove.
|
||||
* @return 0 = is sended, -1 = is not sended
|
||||
*/
|
||||
bool changeType(SType *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 spitypeID the id of the SPITType to remove.
|
||||
* @return 0 = is sended, -1 = is not sended
|
||||
*/
|
||||
int removeType(string spitypeID);
|
||||
|
||||
int removeObject(string objectID);
|
||||
bool changeObject(SObject *sObject);
|
||||
void sendRemoteObject(string objectID, int valuePpm = 0, char valueFlag = 0x00);
|
||||
void resetConfirmedFlags() {
|
||||
SType::setConfirmedFalse(mSpitTypes);
|
||||
SObject::setConfirmedFalse(mSpitObjects);
|
||||
}
|
||||
|
||||
private:
|
||||
public: // @todo delete
|
||||
void parseReportProject(Message::ReportProject &message);
|
||||
void parseCloseProject(Message::CloseProject &message);
|
||||
void parseRequestProjectTransfer(Message::RequestProjectTransfer &message);
|
||||
void parseStartProjectTransfer(Message::StartProjectTransfer &message);
|
||||
void parseEndProjectTransfer(Message::EndProjectTransfer &message);
|
||||
void parseReportType(Message::ReportType &message);
|
||||
// void parseRemoveSPITType(Message::RemoveType &message);
|
||||
// int sendSPITTypeInternal(SType &sType);
|
||||
void parseRemoveType(Message::RemoveType &message);
|
||||
void parseReportObject(Message::ReportObject &message);
|
||||
void parseRemoveObject(Message::RemoveObject &message);
|
||||
void parsePlayStart(Message::PlayStart &message);
|
||||
void parsePlayObject(Message::PlayObject &message);
|
||||
void parsePlayEnd(Message::PlayEnd &message);
|
||||
void parseReportPlayStatus(Message::ReportPlayStatus &message);
|
||||
int sendObjectInternal(SObject *sObject);
|
||||
|
||||
// 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 spitypeID the id of the SPITType to remove.
|
||||
// * @return 0 = is sended, -1 = is not sended
|
||||
// */
|
||||
// bool changeSPITType(SType *spitType);
|
||||
// /**
|
||||
// * If a client wants to remove a SPITType, he should send it to the server.<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 spitypeID the id of the SPITType to remove.
|
||||
// * @return 0 = is sended, -1 = is not sended
|
||||
// */
|
||||
// int removeSPITType(string spitypeID);
|
||||
|
||||
// public:
|
||||
// //--------------- SPIT Objects ---------------
|
||||
// private:
|
||||
// void parseReportSPITObject(Message::ReportObject &message);
|
||||
// void parseRemoveSPITObject(Message::RemoveObject &message);
|
||||
// int sendSPITObjectInternal(SObject *ptrObject);
|
||||
|
||||
// public:
|
||||
// /**
|
||||
// * When the client changes a SPITObject (normally the client should not do this), then it should send the changes to the SPITServer.<br>
|
||||
// * The SPITServer may discard the changes and an eventSPITObject occurs.<br>
|
||||
// * @param spitObject the pointer to the changed SPITObject.
|
||||
// * @return 0 = sended, -1 = not sended
|
||||
// */
|
||||
// bool changeSPITObject(SObject *spitObject);
|
||||
// /**
|
||||
// * When the client removes a SPITObject (normally the client should not do this), then he should send it to the SPITServer.<br>
|
||||
// * The SPITServer may discard the deletion and an eventSPITObject occurs.<br>
|
||||
// * @param objectID the id of the SPITObject to remove.
|
||||
// * @return 0 = sended, -1 = not sended
|
||||
// */
|
||||
// int removeSPITObject(string objectID);
|
||||
|
||||
// public:
|
||||
// //--------------- Play SPIT Objects ---------------
|
||||
// private:
|
||||
// void parsePlaySPITStart(Message::PlayStart &message);
|
||||
// void parsePlaySPITObject(Message::PlayObject &message);
|
||||
// void parsePlaySPITEnd(Message::PlayEnd &message);
|
||||
// void parseReportPlayStatus(Message::ReportPlayStatus &message);
|
||||
|
||||
// public:
|
||||
// //--------- Remote ----------
|
||||
// void sendRemoteObject(string objectID, int valuePpm = 0, char valueFlag = 0x00);
|
||||
|
||||
// private:
|
||||
// bool mAbortSearch{};
|
||||
// bool sAnswered{};
|
||||
// void answerWatchdog() {
|
||||
// sAnswered = true;
|
||||
// }
|
||||
|
||||
// SpitRepo<SObject> mSpitObjects;
|
||||
// SpitRepo<SObject> mRemoteSpitObjects;
|
||||
public: // @todo remove
|
||||
SpitRepo<SObject> mSpitObjects;
|
||||
SpitRepo<SType> mSpitTypes;
|
||||
SpitRepo<SObject> mRemoteSpitObjects;
|
||||
SpitRepo<SType> mRemoteSpitTypes;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace spit {
|
||||
static const char *TAG = "SPIT";
|
||||
static fos::Queue<vector<char>> incommingSpit(64);
|
||||
static fos::Queue<vector<char>> incommingSpit(128);
|
||||
|
||||
|
||||
/**
|
||||
@@ -16,16 +16,14 @@ static fos::Queue<vector<char>> incommingSpit(64);
|
||||
SClient::SClient(string name, string projName, ISocket &socket, Callbacks calls)
|
||||
: ISadClient(),
|
||||
mCallbacks(calls),
|
||||
mName(name),
|
||||
mProjName(projName),
|
||||
mProcessor(name, projName, getClientHostName(), createGUID(), calls,
|
||||
{
|
||||
.sendSpitTypeInternal = [&](SType &sType) { return sendSPITTypeInternal(sType);}
|
||||
.delay = [&](int ms){ return fos::Task::delayMs(ms); },
|
||||
.sendMessage = [&](Message::OPPart &msg){ return sendMessage(msg); },
|
||||
.parseMessage = [&](Message& msg) { parseMessage(msg); }
|
||||
}
|
||||
),
|
||||
mSocket(socket) {
|
||||
mID = createGUID();
|
||||
mComputerName = getClientHostName();
|
||||
}
|
||||
|
||||
SClient::~SClient() {
|
||||
@@ -36,8 +34,8 @@ SClient::~SClient() {
|
||||
void SClient::clientProjectClose() {
|
||||
if (mConnectionStatus == Connection::Ok) {
|
||||
ESP_LOGI(TAG, " ... tidy up ressources");
|
||||
Message::CloseProject closeSPITProject(mProjName);
|
||||
if (sendSPITMessage(closeSPITProject) < 0) {
|
||||
Message::CloseProject closeSPITProject(mProcessor.getProjName());
|
||||
if (sendMessage(closeSPITProject) < 0) {
|
||||
ESP_LOGD(TAG, "Client could not send Client's ReportProject");
|
||||
}
|
||||
}
|
||||
@@ -45,58 +43,23 @@ void SClient::clientProjectClose() {
|
||||
|
||||
void SClient::clientProjectLoaded() {
|
||||
// set confirmed = false for all SPITTypes and SPITObjects
|
||||
SType::setConfirmedFalse(mProcessor.mSpitTypes);
|
||||
SObject::setConfirmedFalse(mSpitObjects);
|
||||
|
||||
mProcessor.resetConfirmedFlags();
|
||||
if (mConnectionStatus == Connection::Ok) {
|
||||
// send ReportProject to the server
|
||||
Message::ReportProject reportSPITProject(mProjName, mProjName);
|
||||
Message::ReportProject reportSPITProject(mProcessor.getProjName(), mProcessor.getProjName());
|
||||
reportSPITProject.setFramesPerSecond(0);
|
||||
if (sendSPITMessage(reportSPITProject) < 0) {
|
||||
if (sendMessage(reportSPITProject) < 0) {
|
||||
ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send Client's ReportProject");
|
||||
}
|
||||
|
||||
// send RequestProjectTransfer
|
||||
Message::RequestProjectTransfer sMRequestProjectTransfer;
|
||||
if (sendSPITMessage(sMRequestProjectTransfer) < 0) {
|
||||
if (sendMessage(sMRequestProjectTransfer) < 0) {
|
||||
ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send RequestProjectTransfer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual construct - means actionAssigned for SPITTypes is is not implemented in SPITProtocol.
|
||||
* This can used to setActionAssigned to all SPITObjects with this SPITType.
|
||||
* This may be used in the case when the same action should be done for every SPITObject with this SPITType associated.
|
||||
* This tells the server not what action is done, but it tells the server that there is an action.
|
||||
* @param typeId the id of the SPITType
|
||||
* @param actionAssigned
|
||||
*/
|
||||
void SClient::setActionSPITType(string typeId, bool actionAssigned) {
|
||||
SType *spitType = mProcessor.mSpitTypes.getEntry(typeId);
|
||||
if (spitType == nullptr)
|
||||
return;
|
||||
if (spitType->ActionAssigned.set(actionAssigned)) {
|
||||
sendSPITTypeInternal(*spitType);
|
||||
for (auto& [key, value] : mSpitObjects.getRepo()) {
|
||||
if (value->SPITTypeID.get() == spitType->getID()) {
|
||||
if (value->setActionAssignedType(actionAssigned) == true) {
|
||||
sendSPITObjectInternal(value.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** This should be called if the user wants to associate/remove an action with a SPITObject. */
|
||||
void SClient::setActionSPITObject(string spitObjId, bool actionAssigned) {
|
||||
SObject *spitObject = mSpitObjects.getEntry(spitObjId);
|
||||
if (spitObject == nullptr)
|
||||
return;
|
||||
if (spitObject->setActionAssigned(actionAssigned) == true) {
|
||||
sendSPITObjectInternal(spitObject);
|
||||
}
|
||||
}
|
||||
//---------- ServerAutoDetection SAD -----------
|
||||
|
||||
/** Starts the autodetection of SPITServers in the local network. If a connection is tried, the autodetection should be stopped before.
|
||||
@@ -205,13 +168,13 @@ void SClient::eventServerChanged(SadDetectedServer &server) {
|
||||
// // } //Excample
|
||||
// }
|
||||
|
||||
int SClient::sendSPITMessage(Message::OPPart &opPart) {
|
||||
int SClient::sendMessage(Message::OPPart &opPart) {
|
||||
if (mMessageNumberSend == 255)
|
||||
mMessageNumberSend = 1;
|
||||
else
|
||||
mMessageNumberSend++;
|
||||
opPart.setMessageNumber(mMessageNumberSend);
|
||||
opPart.setServerInfoInHeader(mID, mServerID);
|
||||
opPart.setServerInfoInHeader(mProcessor.getID(), mServerID);
|
||||
|
||||
int opFlag = opPart.getHeader()->getType();
|
||||
try {
|
||||
@@ -244,10 +207,10 @@ void SClient::stopReceiveSPITMessages() {
|
||||
}
|
||||
|
||||
void SClient::receiveSpitMessage(SClient &rM) {
|
||||
char buffer[MAXSPITMESSAGEBYTECOUNT + 1];
|
||||
char buffer[Message::MAX_MESSAGE_SIZE];
|
||||
int rdLen;
|
||||
while (rM.mStopReceiveMessages == false) {
|
||||
rdLen = rM.mSocket.receiveMessage(buffer, MAXSPITMESSAGEBYTECOUNT, nullptr);
|
||||
rdLen = rM.mSocket.receiveMessage(buffer, Message::MAX_MESSAGE_SIZE, nullptr);
|
||||
if (rdLen < 0) {
|
||||
if (rM.mStopReceiveMessages) {
|
||||
return;
|
||||
@@ -264,14 +227,14 @@ void SClient::processSpitMessage(SClient &rM) {
|
||||
while (true) {
|
||||
auto data = *incommingSpit.dequeue();
|
||||
auto spitMsg = make_unique<Message>(data);
|
||||
rM.parseMessage(move(spitMsg));
|
||||
rM.checkParseMessage(move(spitMsg));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SClient::resetMessageNumberReceived() {
|
||||
mMessageNumberReceived = -1;
|
||||
mOvertakingMessages.clear();
|
||||
mProcessor.resetMessageNumberReceived();
|
||||
}
|
||||
|
||||
void SClient::checkParseMessage(unique_ptr<Message> p_SPITMessage) {
|
||||
@@ -281,15 +244,15 @@ void SClient::checkParseMessage(unique_ptr<Message> p_SPITMessage) {
|
||||
return;
|
||||
}
|
||||
|
||||
int intActualMessageNumber = (int)(p_SPITMessage->getHeader()->getMessageNumber() & 0xFF);
|
||||
int msgNum = (int)(p_SPITMessage->getHeader()->getMessageNumber() & 0xFF);
|
||||
|
||||
if (intActualMessageNumber == 0) {
|
||||
parseMessage(std::move(p_SPITMessage));
|
||||
if (msgNum == 0) {
|
||||
parseMessage(*p_SPITMessage);
|
||||
return;
|
||||
}
|
||||
if (mMessageNumberReceived < 0) {
|
||||
mMessageNumberReceived = intActualMessageNumber;
|
||||
parseMessage(std::move(p_SPITMessage));
|
||||
mMessageNumberReceived = msgNum;
|
||||
parseMessage(*p_SPITMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -297,124 +260,41 @@ void SClient::checkParseMessage(unique_ptr<Message> p_SPITMessage) {
|
||||
if (intNextMessageNumber > 255 || intNextMessageNumber < 1)
|
||||
intNextMessageNumber = 1;
|
||||
|
||||
if (intActualMessageNumber == intNextMessageNumber) {
|
||||
mMessageNumberReceived = intActualMessageNumber;
|
||||
parseMessage(std::move(p_SPITMessage));
|
||||
|
||||
// check overtaking messages
|
||||
auto it = mOvertakingMessages.begin();
|
||||
while (mOvertakingMessages.size() > 0) {
|
||||
|
||||
intNextMessageNumber = mMessageNumberReceived + 1;
|
||||
if (intNextMessageNumber > 255 || intNextMessageNumber < 1)
|
||||
intNextMessageNumber = 1;
|
||||
|
||||
auto &ptrOvertakingSPIT_Message = *it;
|
||||
intActualMessageNumber = (int)(ptrOvertakingSPIT_Message->getHeader()->getMessageNumber() & 0xFF);
|
||||
|
||||
if (intActualMessageNumber == intNextMessageNumber) {
|
||||
mMessageNumberReceived = intActualMessageNumber;
|
||||
parseMessage(move(ptrOvertakingSPIT_Message));
|
||||
mOvertakingMessages.erase(it);
|
||||
|
||||
it = mOvertakingMessages.begin();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (msgNum == intNextMessageNumber) {
|
||||
mMessageNumberReceived = msgNum;
|
||||
parseMessage(*p_SPITMessage);
|
||||
|
||||
mMessageNumberReceived = mProcessor.sendOvertakingMessage(mMessageNumberReceived);
|
||||
} else {
|
||||
// p_SPITMessage has overtaken another message
|
||||
addOvertakingMessage(move(p_SPITMessage));
|
||||
mProcessor.addOvertakingMessage(move(p_SPITMessage));
|
||||
}
|
||||
}
|
||||
|
||||
void SClient::addOvertakingMessage(unique_ptr<Message> message) {
|
||||
if (!message) {
|
||||
return;
|
||||
}
|
||||
if (mOvertakingMessages.size() > MAX_OVERTAKING_SPIT_MESSAGES) {
|
||||
ESP_LOGD(TAG, "Client receiveing: perhaps message lost !!!!!");
|
||||
}
|
||||
|
||||
int intMessageNumber = (int)(message->getHeader()->getMessageNumber() & 0xFF);
|
||||
for (auto it = mOvertakingMessages.begin(); it != mOvertakingMessages.end(); ++it) {
|
||||
const auto &overtaking = *it;
|
||||
int intOvertakingMessageNumber = (int)(overtaking->getHeader()->getMessageNumber() & 0xFF);
|
||||
if (intMessageNumber < intOvertakingMessageNumber) {
|
||||
mOvertakingMessages.insert(it, move(message));
|
||||
return;
|
||||
}
|
||||
}
|
||||
mOvertakingMessages.push_back(move(message));
|
||||
}
|
||||
|
||||
void SClient::parseMessage(unique_ptr<Message> message) {
|
||||
void SClient::parseMessage(Message& message) {
|
||||
answerWatchdog();
|
||||
if (!message || !message->getHeader() || !message->getOPPart()) {
|
||||
if (!message.getHeader() || !message.getOPPart()) {
|
||||
ESP_LOGD(TAG, "Client::parseMessage incomplete message");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (message->getType()) {
|
||||
switch (message.getType()) {
|
||||
//----- Connection -----
|
||||
case Message::ConnectAnswer::OPFLAG:
|
||||
parseConnectAnswer(message->getAs<Message::ConnectAnswer>());
|
||||
parseConnectAnswer(message.getAs<Message::ConnectAnswer>());
|
||||
break;
|
||||
case Message::Disconnect::OPFLAG:
|
||||
parseDisconnect(message->getAs<Message::Disconnect>());
|
||||
break;
|
||||
case Message::ReportProject::OPFLAG:
|
||||
parseReportProject(message->getAs<Message::ReportProject>());
|
||||
parseDisconnect(message.getAs<Message::Disconnect>());
|
||||
break;
|
||||
case Message::Watchdog::OPFLAG:
|
||||
parseWatchdog(message->getAs<Message::Watchdog>());
|
||||
parseWatchdog(message.getAs<Message::Watchdog>());
|
||||
break;
|
||||
case Message::WatchdogAnswer::OPFLAG:
|
||||
parseWatchdogAnswer(message->getAs<Message::WatchdogAnswer>());
|
||||
break;
|
||||
//----- SPIT Project -----
|
||||
case Message::StartProjectTransfer::OPFLAG:
|
||||
parseStartProjectTransfer(message->getAs<Message::StartProjectTransfer>());
|
||||
break;
|
||||
case Message::CloseProject::OPFLAG:
|
||||
parseCloseProject(message->getAs<Message::CloseProject>());
|
||||
break;
|
||||
case Message::RequestProjectTransfer::OPFLAG:
|
||||
parseRequestProjectTransfer(message->getAs<Message::RequestProjectTransfer>());
|
||||
break;
|
||||
case Message::EndProjectTransfer::OPFLAG:
|
||||
parseEndProjectTransfer(message->getAs<Message::EndProjectTransfer>());
|
||||
break;
|
||||
//----- SPIT Types ------
|
||||
case Message::ReportType::OPFLAG:
|
||||
mProcessor.parseReportType(message->getAs<Message::ReportType>());
|
||||
break;
|
||||
case Message::RemoveType::OPFLAG:
|
||||
parseRemoveSPITType(message->getAs<Message::RemoveType>());
|
||||
//----- SPIT Objects ------
|
||||
break;
|
||||
case Message::ReportObject::OPFLAG:
|
||||
parseReportSPITObject(message->getAs<Message::ReportObject>());
|
||||
break;
|
||||
case Message::RemoveObject::OPFLAG:
|
||||
parseRemoveSPITObject(message->getAs<Message::RemoveObject>());
|
||||
break;
|
||||
//----- Play SPIT Objects ------
|
||||
case Message::PlayStart::OPFLAG:
|
||||
parsePlaySPITStart(message->getAs<Message::PlayStart>());
|
||||
break;
|
||||
case Message::PlayObject::OPFLAG:
|
||||
parsePlaySPITObject(message->getAs<Message::PlayObject>());
|
||||
break;
|
||||
case Message::PlayEnd::OPFLAG:
|
||||
parsePlaySPITEnd(message->getAs<Message::PlayEnd>());
|
||||
break;
|
||||
case Message::ReportPlayStatus::OPFLAG:
|
||||
parseReportPlayStatus(message->getAs<Message::ReportPlayStatus>());
|
||||
parseWatchdogAnswer(message.getAs<Message::WatchdogAnswer>());
|
||||
break;
|
||||
default:
|
||||
ESP_LOGD(TAG, "Client::parseMessage: Unknown Message");
|
||||
// pass object to SubProcessor
|
||||
mProcessor.parseMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,15 +316,8 @@ bool SClient::connect(string serverIP, string serverPort, string clientIP, strin
|
||||
mStopReceiveMessages = true;
|
||||
return false;
|
||||
}
|
||||
Message::Connect sMConnect(mComputerName, mName);
|
||||
sMConnect.setLoginName(loginName);
|
||||
sMConnect.setLoginPassword(loginPassword);
|
||||
sMConnect.setServerIP(serverIP);
|
||||
if (serverPort.length() <= 0) {
|
||||
serverPort = "0";
|
||||
}
|
||||
int intServerPort = stoi(serverPort);
|
||||
sMConnect.setServerPort(intServerPort);
|
||||
|
||||
auto connMsg = mProcessor.createConnectMessage(serverIP, serverPort, loginName, loginPassword);
|
||||
|
||||
if (startReceiveSPITMessages() == false) {
|
||||
mStopReceiveMessages = true;
|
||||
@@ -459,7 +332,7 @@ bool SClient::connect(string serverIP, string serverPort, string clientIP, strin
|
||||
|
||||
// sleep a little to make sure that the reception of the messages is started
|
||||
fos::Task::delayMs(500);
|
||||
if (sendSPITMessage(sMConnect) < 0) {
|
||||
if (sendMessage(*connMsg) < 0) {
|
||||
mConnectionStatus = Connection::None;
|
||||
mStopReceiveMessages = true;
|
||||
return false;
|
||||
@@ -483,7 +356,7 @@ void SClient::disconnectInternal(Connection cause) {
|
||||
break;
|
||||
case Connection::None: {
|
||||
Message::Disconnect sMDisconnect;
|
||||
sendSPITMessage(sMDisconnect);
|
||||
sendMessage(sMDisconnect);
|
||||
} break;
|
||||
case Connection::NoneServer:
|
||||
break;
|
||||
@@ -505,7 +378,7 @@ void SClient::disconnectInternal(Connection cause) {
|
||||
ESP_LOGD(TAG, "connection terminated by server");
|
||||
// call eventProjectClosed because this may not be sended by the server,
|
||||
// when the connection is closed
|
||||
mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, mServerProjectID);
|
||||
mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, mProcessor.getServerProjectID());
|
||||
|
||||
// Server has terminated the connection -> start a new game
|
||||
// _doReconnect = false;
|
||||
@@ -525,7 +398,7 @@ void SClient::disconnectInternal(Connection cause) {
|
||||
}
|
||||
|
||||
void SClient::parseConnectAnswer(Message::ConnectAnswer &message) {
|
||||
if (message.getClientID() != mID)
|
||||
if (message.getClientID() != mProcessor.getID())
|
||||
return;
|
||||
|
||||
mServerID = message.getServerID();
|
||||
@@ -536,7 +409,6 @@ void SClient::parseConnectAnswer(Message::ConnectAnswer &message) {
|
||||
if (message.getConnected() == false) {
|
||||
disconnectInternal(Connection::NoneServer);
|
||||
} else {
|
||||
message.getStepTime();
|
||||
mConnectionStatus = Connection::Ok;
|
||||
mDisconnectedByServer = false;
|
||||
ESP_LOGD(TAG, "connection established");
|
||||
@@ -556,10 +428,7 @@ void SClient::parseConnectAnswer(Message::ConnectAnswer &message) {
|
||||
*/
|
||||
void SClient::parseDisconnect(Message::Disconnect &message) {
|
||||
Connection intCauseDisconnect = Connection::NoneServer;
|
||||
/*
|
||||
function<void()> o_Callable = bind(&SClient::disconnectInternal, this, intCauseDisconnect);
|
||||
SPIT_Handler::addCallable(o_Callable);
|
||||
*/
|
||||
|
||||
mDisconnectedByServer = true;
|
||||
SClient::disconnectInternal(intCauseDisconnect);
|
||||
}
|
||||
@@ -572,9 +441,8 @@ void SClient::parseDisconnect(Message::Disconnect &message) {
|
||||
* @param message
|
||||
*/
|
||||
void SClient::parseWatchdog(Message::Watchdog &message) {
|
||||
// ESP_LOGD(TAG, "parse Watchdog ");
|
||||
Message::WatchdogAnswer o_WatchdogAnswer;
|
||||
sendSPITMessage(o_WatchdogAnswer);
|
||||
sendMessage(o_WatchdogAnswer);
|
||||
}
|
||||
/**
|
||||
* The SPIT server sends a watchdog message at regular intervals. The client responds immediately with WatchdogAnswer
|
||||
@@ -588,7 +456,7 @@ void SClient::parseWatchdogAnswer(Message::WatchdogAnswer &message) {
|
||||
void SClient::sendWatchdog() {
|
||||
int intResult;
|
||||
Message::Watchdog message;
|
||||
intResult = sendSPITMessage(message);
|
||||
intResult = sendMessage(message);
|
||||
if (intResult < 0) {
|
||||
ESP_LOGW("WDT", "Failed to send Watchdog msg");
|
||||
}
|
||||
@@ -601,130 +469,6 @@ void SClient::eventWatchdogLost() {
|
||||
}
|
||||
}
|
||||
|
||||
//----- SPIT Project ------
|
||||
void SClient::parseReportProject(Message::ReportProject &message) {
|
||||
ESP_LOGD(TAG, "parse ReportProject");
|
||||
mServerProjectID = message.getProjectID();
|
||||
mServerProjectName = message.getProjectName();
|
||||
mServerFramesPerSecond = message.getFramesPerSecond();
|
||||
mCallbacks.onProjectUpdate(ProjUpdate::ServerLoaded, mServerProjectID);
|
||||
|
||||
// Set all SPITTypes and SPITObjects confirmed = false
|
||||
SType::setConfirmedFalse(mProcessor.mSpitTypes);
|
||||
SObject::setConfirmedFalse(mSpitObjects);
|
||||
|
||||
// Send RequestProjectTransfer
|
||||
Message::RequestProjectTransfer sMRequestProjectTransfer;
|
||||
if (sendSPITMessage(sMRequestProjectTransfer) < 0) {
|
||||
ESP_LOGD(TAG, "Client::parseReportProject could not send RequestProjectTransfer");
|
||||
}
|
||||
|
||||
// todo Don't send the ReportProject here it should be sended after parseEndProjectTransfer
|
||||
// Send client's ReportProject
|
||||
Message::ReportProject reportProject(mProjName, mProjName);
|
||||
reportProject.setFramesPerSecond(0);
|
||||
if (sendSPITMessage(reportProject) < 0) {
|
||||
ESP_LOGD(TAG, "Client::parseReportProject could not send Client's ReportProject");
|
||||
}
|
||||
}
|
||||
void SClient::parseCloseProject(Message::CloseProject &p_CloseSPITProject) {
|
||||
ESP_LOGD(TAG, "parse CloseProject");
|
||||
string stringProjectID;
|
||||
mCallbacks.onProjectUpdate(ProjUpdate::ServerClosed, p_CloseSPITProject.getProjectID());
|
||||
SPlayer::clearPlayers();
|
||||
}
|
||||
|
||||
string SClient::getServerProjectID() { return mServerProjectID; }
|
||||
string SClient::getServerProjectName() { return mServerProjectName; }
|
||||
int SClient::getServerFramesPerSecond() { return mServerFramesPerSecond; }
|
||||
|
||||
void SClient::parseRequestProjectTransfer(Message::RequestProjectTransfer &message) {
|
||||
ESP_LOGD(TAG, "parse RequestProjectTransfer");
|
||||
// StartProjectTransfer
|
||||
Message::StartProjectTransfer sMStartProjectTransfer;
|
||||
if (sendSPITMessage(sMStartProjectTransfer) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// send all listes SPITTypes
|
||||
for (const auto& [key, value] : mProcessor.mSpitTypes.getRepo()) {
|
||||
sendSPITTypeInternal(*value);
|
||||
fos::Task::delayMs(10);
|
||||
}
|
||||
for (auto& [key, value] : mSpitObjects.getRepo()) {
|
||||
sendSPITObjectInternal(value.get());
|
||||
fos::Task::delayMs(10);
|
||||
}
|
||||
|
||||
// EndProjectTransfer
|
||||
Message::EndProjectTransfer sMEndProjectTransfer;
|
||||
sendSPITMessage(sMEndProjectTransfer);
|
||||
}
|
||||
|
||||
/* NEW IMPLEMENTATION
|
||||
|
||||
void SClient::parseRequestProjectTransfer(Message::RequestProjectTransfer* message) {
|
||||
// ESP_LOGD(TAG, "parse RequestProjectTransfer");
|
||||
thread* o_ThreadSend;
|
||||
o_ThreadSend = new thread(&this->sendProject, this);
|
||||
// int intResult;
|
||||
// Message::StartProjectTransfer* ptrSMStartProjectTransfer;
|
||||
// Message::EndProjectTransfer* ptrSMEndProjectTransfer;
|
||||
// int intCount;
|
||||
// SPITType* ptrSPITType;
|
||||
// SObject* ptrSPITObject;
|
||||
|
||||
|
||||
// //StartProjectTransfer
|
||||
// NotifyStartProjectTransfer_Client* o_RunnableStart = new NotifyStartProjectTransfer_Client(mSPITClientInterface);
|
||||
// SPIT_Handler::addRunnable(o_RunnableStart);
|
||||
|
||||
// ptrSMStartProjectTransfer = new Message::StartProjectTransfer();
|
||||
// intResult = sendSPITMessage(ptrSMStartProjectTransfer);
|
||||
// if (intResult < 0) {
|
||||
// return;
|
||||
// }
|
||||
// mWatchdog->answerWatchdog();
|
||||
// {
|
||||
// //send all listes SPITTypes
|
||||
// unique_lock<recursive_mutex> o_LockType(*SPITType::getMutex());
|
||||
// intCount = SPITType::getSPITTypeCount();
|
||||
// for (int i = 0; i < intCount; i++) {
|
||||
// ptrSPITType = mSpitTypes.getEntry(i);
|
||||
// if (ptrSPITType == nullptr) continue;
|
||||
// intResult = sendSPITTypeInternal(ptrSPITType);
|
||||
// if (intResult < 0) return;
|
||||
// mWatchdog->answerWatchdog();
|
||||
// this_thread::sleep_for(chrono::milliseconds(7));
|
||||
// }
|
||||
// }
|
||||
|
||||
// {
|
||||
// unique_lock<recursive_mutex> o_LockObject(*SObject::getMutex());
|
||||
// intCount = mSpitObjects.getEntryCount();
|
||||
// for (int i = 0; i < intCount; i++) {
|
||||
// ptrSPITObject = mSpitObjects.getEntry(i);
|
||||
// if (ptrSPITObject == nullptr) continue;
|
||||
// intResult = sendSPITObjectInternal(ptrSPITObject);
|
||||
// if (intResult < 0) return;
|
||||
// mWatchdog->answerWatchdog();
|
||||
// this_thread::sleep_for(chrono::milliseconds(7));
|
||||
// }
|
||||
// }
|
||||
|
||||
// //EndProjectTransfer
|
||||
// ptrSMEndProjectTransfer = new Message::EndProjectTransfer();
|
||||
// intResult = sendSPITMessage(ptrSMEndProjectTransfer);
|
||||
// if (intResult < 0) {
|
||||
// return;
|
||||
// }
|
||||
// mWatchdog->answerWatchdog();
|
||||
// NotifyEndProjectTransfer_Client* o_RunnableEnd = new NotifyEndProjectTransfer_Client(mSPITClientInterface);
|
||||
// SPIT_Handler::addRunnable(o_RunnableEnd);
|
||||
|
||||
// //Send act
|
||||
}
|
||||
*/
|
||||
|
||||
void SClient::sendProject(SClient *p_PtrSPIT_Client) {
|
||||
// int intResult;
|
||||
@@ -739,7 +483,7 @@ void SClient::sendProject(SClient *p_PtrSPIT_Client) {
|
||||
// SPIT_Handler::addRunnable(o_RunnableStart);
|
||||
|
||||
// ptrSMStartProjectTransfer = new Message::StartProjectTransfer();
|
||||
// intResult = p_PtrSPIT_Client->sendSPITMessage(ptrSMStartProjectTransfer);
|
||||
// intResult = p_PtrSPIT_Client->sendMessage(ptrSMStartProjectTransfer);
|
||||
// if (intResult < 0) {
|
||||
// return;
|
||||
// }
|
||||
@@ -753,7 +497,7 @@ void SClient::sendProject(SClient *p_PtrSPIT_Client) {
|
||||
// ptrSPITType = mSpitTypes.getEntry(i);
|
||||
// if (ptrSPITType == nullptr) continue;
|
||||
// if (ptrSPITType->getCreatedByClient() == false) continue;
|
||||
// intResult = p_PtrSPIT_Client->sendSPITTypeInternal(ptrSPITType);
|
||||
// intResult = p_PtrSPIT_Client->sendTypeInternal(ptrSPITType);
|
||||
// if (intResult < 0) return;
|
||||
// // mWatchdog->answerWatchdog();
|
||||
// this_thread::sleep_for(chrono::milliseconds(7));
|
||||
@@ -767,7 +511,7 @@ void SClient::sendProject(SClient *p_PtrSPIT_Client) {
|
||||
// ptrSPITObject = mSpitObjects.getEntry(i);
|
||||
// if (ptrSPITObject == nullptr) continue;
|
||||
// if (ptrSPITObject->getCreatedByClient() == false) continue;
|
||||
// intResult = p_PtrSPIT_Client->sendSPITObjectInternal(ptrSPITObject);
|
||||
// intResult = p_PtrSPIT_Client->sendObjectInternal(ptrSPITObject);
|
||||
// if (intResult < 0) return;
|
||||
// // mWatchdog->answerWatchdog();
|
||||
// this_thread::sleep_for(chrono::milliseconds(7));
|
||||
@@ -776,7 +520,7 @@ void SClient::sendProject(SClient *p_PtrSPIT_Client) {
|
||||
|
||||
// //EndProjectTransfer
|
||||
// ptrSMEndProjectTransfer = new Message::EndProjectTransfer();
|
||||
// intResult = p_PtrSPIT_Client->sendSPITMessage(ptrSMEndProjectTransfer);
|
||||
// intResult = p_PtrSPIT_Client->sendMessage(ptrSMEndProjectTransfer);
|
||||
// if (intResult < 0) {
|
||||
// return;
|
||||
// }
|
||||
@@ -787,431 +531,8 @@ void SClient::sendProject(SClient *p_PtrSPIT_Client) {
|
||||
// //Send act
|
||||
}
|
||||
|
||||
void SClient::parseStartProjectTransfer(Message::StartProjectTransfer &message) {
|
||||
mCallbacks.onProjectUpdate(ProjUpdate::StartTransfer, mServerProjectID);
|
||||
}
|
||||
void SClient::parseEndProjectTransfer(Message::EndProjectTransfer &message) {
|
||||
SObject::clearUnconfirmedObjects(mSpitObjects);
|
||||
mCallbacks.onProjectUpdate(ProjUpdate::EndTransfer, mServerProjectID);
|
||||
|
||||
// Send Message::ReportProject after the mSPITClientInterface is notfied of EndProjectTransfer
|
||||
Message::ReportProject reportSPITProject(mProjName, mProjName);
|
||||
reportSPITProject.setFramesPerSecond(0);
|
||||
if (sendSPITMessage(reportSPITProject) < 0) {
|
||||
ESP_LOGD(TAG, "Client::parseReportProject could not send Client's ReportProject");
|
||||
}
|
||||
}
|
||||
|
||||
void SClient::parseRemoveSPITType(Message::RemoveType &message) {
|
||||
ESP_LOGD(TAG, "parse RemoveType %s", message.getID().c_str());
|
||||
bool boolRemote = false;
|
||||
string stringSPITTypeID = message.getID();
|
||||
|
||||
SType *ptrSPITType = mProcessor.mRemoteSpitTypes.getEntry(stringSPITTypeID);
|
||||
if (!ptrSPITType) {
|
||||
boolRemote = true;
|
||||
} else {
|
||||
ptrSPITType = mProcessor.mSpitTypes.getEntry(stringSPITTypeID);
|
||||
if (!ptrSPITType) {
|
||||
boolRemote = false;
|
||||
} else {
|
||||
// No SPITType with stringSPITTypeID is listet
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptrSPITType->getCreatedByClient() && ptrSPITType->Fixed.get()) {
|
||||
// the SPITyte is created by client himself and it is fixed -> don't remove the SPITType!!
|
||||
// Send the SPITTyp back to the server
|
||||
sendSPITTypeInternal(*ptrSPITType);
|
||||
return;
|
||||
}
|
||||
|
||||
mCallbacks.onSpitType(ObjectEvent::Deleted, boolRemote, *ptrSPITType);
|
||||
if (boolRemote == false) {
|
||||
mProcessor.mSpitTypes.removeEntry(*ptrSPITType);
|
||||
} else {
|
||||
mProcessor.mRemoteSpitTypes.removeEntry(*ptrSPITType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a client has changed a SPITType, it should send it to the server to transmit the changes.
|
||||
* If the SPITType is a fixed one and not created by the client himself, then an eventSPITType can be sent from the server, which cancels the changes.
|
||||
* @param p_SPITType the pointer to the changed SPITType
|
||||
* @return 0 = is sended, -1 = is not sended
|
||||
*/
|
||||
int SClient::sendSPITTypeInternal(SType &p_SPITType) {
|
||||
Message::ReportType sMReportSPITType;
|
||||
p_SPITType.fillMessageOP(sMReportSPITType);
|
||||
return sendSPITMessage(sMReportSPITType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change an existing SPIT_Type.
|
||||
* @param p_SPITType the SPITType vont
|
||||
* @return true = changed, false = not changed maybe p_SPITType is NULL or the SPITType doesn't exists
|
||||
*/
|
||||
bool SClient::changeSPITType(SType *p_SPITType) {
|
||||
if (p_SPITType == nullptr)
|
||||
return false;
|
||||
SType *ptrSPITType = mProcessor.mSpitTypes.getEntry(p_SPITType->getID());
|
||||
if (ptrSPITType == nullptr)
|
||||
return false;
|
||||
|
||||
ptrSPITType->DefaultDelay.set(p_SPITType->DefaultDelay.get());
|
||||
ptrSPITType->DefaultDuration.set(p_SPITType->DefaultDuration.get());
|
||||
ptrSPITType->Fixed.set(p_SPITType->Fixed.get());
|
||||
ptrSPITType->GroupName.set(p_SPITType->GroupName.get());
|
||||
ptrSPITType->Name.set(p_SPITType->Name.get());
|
||||
ptrSPITType->ProjectIndepended.set(p_SPITType->ProjectIndepended.get());
|
||||
|
||||
mCallbacks.onSpitType(ObjectEvent::Changed, false, *ptrSPITType);
|
||||
sendSPITTypeInternal(*ptrSPITType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a client has removed a SPITType where id == p_SPITTypeID, it should send it to the server.
|
||||
* The corresponding SPITType if listet in SPITType will be deleted.
|
||||
* An eventRemoveSPITType will occur.
|
||||
* If a connection to a SPITServer is established, the SPITServer may dicard the deletion an an eventSPITType will occur
|
||||
* -> the SPITType will be listet again.
|
||||
* @param p_SPITType the id of the SPITType ro remove
|
||||
* @return 0 = is sended, -1 = is not sended
|
||||
*/
|
||||
int SClient::removeSPITType(string p_SPITTypeID) {
|
||||
if (p_SPITTypeID.length() <= 0)
|
||||
return -1;
|
||||
SType *ptrSPITType;
|
||||
{
|
||||
ptrSPITType = mProcessor.mSpitTypes.getEntry(p_SPITTypeID);
|
||||
if (ptrSPITType == nullptr)
|
||||
return -1;
|
||||
Message::RemoveType sMRemoveSPITType;
|
||||
ptrSPITType->fillMessageOP(sMRemoveSPITType);
|
||||
mCallbacks.onSpitType(ObjectEvent::Deleted, false, *ptrSPITType);
|
||||
mProcessor.mSpitTypes.removeEntry(*ptrSPITType);
|
||||
return sendSPITMessage(sMRemoveSPITType);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SType *SClient::createTypeFixed(string iD, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration) {
|
||||
return createType(iD, p_GroupName, p_Name, p_DefaultDelay, p_DefaultDuration, true, true);
|
||||
}
|
||||
|
||||
SType *SClient::createType(string p_ID, string p_GroupName, string p_Name, uint64_t p_DefaultDelay, uint64_t p_DefaultDuration, bool p_FIxed, bool p_ProjectIndepended) {
|
||||
bool boolNew;
|
||||
SType *ptrSPITType = mProcessor.mSpitTypes.getEntry(p_ID);
|
||||
if (ptrSPITType == nullptr) {
|
||||
auto spitType = make_unique<SType>(p_ID, p_GroupName, p_Name, p_FIxed, p_ProjectIndepended, p_DefaultDelay, p_DefaultDuration);
|
||||
ptrSPITType = spitType.get();
|
||||
mProcessor.mSpitTypes.addEntry(move(spitType));
|
||||
ptrSPITType->setCreatedByClient(true);
|
||||
boolNew = true;
|
||||
} else {
|
||||
ptrSPITType->GroupName.set(p_GroupName);
|
||||
ptrSPITType->Name.set(p_Name);
|
||||
ptrSPITType->Fixed.set(p_FIxed);
|
||||
ptrSPITType->ProjectIndepended.set(p_ProjectIndepended);
|
||||
ptrSPITType->DefaultDelay.set(p_DefaultDelay);
|
||||
ptrSPITType->DefaultDuration.set(p_DefaultDuration);
|
||||
boolNew = false;
|
||||
}
|
||||
|
||||
auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed;
|
||||
mCallbacks.onSpitType(eventType, false, *ptrSPITType);
|
||||
sendSPITTypeInternal(*ptrSPITType);
|
||||
return ptrSPITType;
|
||||
}
|
||||
|
||||
//----- SPIT Objects ------
|
||||
void SClient::parseReportSPITObject(Message::ReportObject &message) {
|
||||
ESP_LOGD(TAG, "parse ReportObject %s", message.getID().c_str());
|
||||
SObject *ptrSPITObject;
|
||||
SType *ptrSPITType;
|
||||
bool boolNew = false;
|
||||
bool boolRemote = false;
|
||||
bool boolChanged = false;
|
||||
{
|
||||
ESP_LOGD(TAG, "parse ReportObject %s / %s", message.getID().c_str(), message.getName().c_str());
|
||||
if (message.getServerRemote() == false) {
|
||||
boolRemote = false;
|
||||
ptrSPITObject = mSpitObjects.getEntry(message.getID());
|
||||
ptrSPITType = mProcessor.mSpitTypes.getEntry(message.getSPITTypeID());
|
||||
|
||||
if (ptrSPITType == nullptr) {
|
||||
// No associated SPITType found
|
||||
if (ptrSPITObject != nullptr) {
|
||||
// SpitObject exists but has no corresponding SPITType -> remove the SPITObject without sending a message
|
||||
// Maybe the SPITObject has changed the SPITTypeID to a SPITTypeID of another board
|
||||
mSpitObjects.removeEntry(*ptrSPITObject);
|
||||
}
|
||||
return;
|
||||
}
|
||||
bool isKnownType = ptrSPITType != nullptr;
|
||||
if (ptrSPITObject == nullptr) {
|
||||
// The user's app my veto the SPITType
|
||||
if (mCallbacks.onCheckSpitObjectVeto(isKnownType) == false) {
|
||||
ESP_LOGW(TAG, "ObjectVeto %s / %s", message.getID().c_str(), message.getName().c_str());
|
||||
return;
|
||||
}
|
||||
auto spitObj = make_unique<SObject>(message.getID());
|
||||
ptrSPITObject = spitObj.get();
|
||||
mSpitObjects.addEntry(move(spitObj));
|
||||
boolNew = true;
|
||||
} else {
|
||||
// The user's app my veto the SPITType
|
||||
if (mCallbacks.onCheckSpitObjectVeto(isKnownType) == false) {
|
||||
// SpitObject exists and User APp denied the SPITObject -> remove the SPITObject without sending a message
|
||||
mSpitObjects.removeEntry(*ptrSPITObject);
|
||||
ESP_LOGW(TAG, "TypeVeto %s / %s", message.getID().c_str(), message.getName().c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
boolRemote = true;
|
||||
ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID());
|
||||
ptrSPITType = mProcessor.mRemoteSpitTypes.getEntry(message.getSPITTypeID());
|
||||
if (ptrSPITType == nullptr) {
|
||||
// No associated SPITType found
|
||||
return;
|
||||
}
|
||||
if (ptrSPITObject == nullptr) {
|
||||
auto spitObj = make_unique<SObject>(message.getID());
|
||||
ptrSPITObject = spitObj.get();
|
||||
mRemoteSpitObjects.addEntry(move(spitObj));
|
||||
boolNew = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ptrSPITObject->setMessageOP(&message)) {
|
||||
ESP_LOGE(TAG, "Change not allowed");
|
||||
// setMessageOP error - the SPITObject can't be changed, it may be fixed and crated by this client
|
||||
sendSPITObjectInternal(ptrSPITObject);
|
||||
return;
|
||||
}
|
||||
|
||||
if (boolRemote == false) {
|
||||
// set the virtual action assignment
|
||||
ptrSPITObject->setActionAssignedType(ptrSPITType->ActionAssigned.get());
|
||||
}
|
||||
|
||||
auto eventType = boolNew ? ObjectEvent::Created : ObjectEvent::Changed;
|
||||
mCallbacks.onSpitObject(eventType, boolRemote, *ptrSPITType, *ptrSPITObject);
|
||||
|
||||
if (ptrSPITObject->setConfirmed(true) == true || boolChanged == true) {
|
||||
// Confirmation has changed
|
||||
sendSPITObjectInternal(ptrSPITObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
void SClient::parseRemoveSPITObject(Message::RemoveObject &message) {
|
||||
ESP_LOGD(TAG, "parse RemoveObject %s", message.getID().c_str());
|
||||
SObject *ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID());
|
||||
if (ptrSPITObject != nullptr) {
|
||||
SType *ptrSPITType = mProcessor.mRemoteSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get());
|
||||
if (ptrSPITType != nullptr) {
|
||||
mCallbacks.onSpitObject(ObjectEvent::Deleted, true, *ptrSPITType, *ptrSPITObject);
|
||||
}
|
||||
mRemoteSpitObjects.removeEntry(*ptrSPITObject);
|
||||
} else {
|
||||
// call removeSPITObject, this will notify the server that the object is removed
|
||||
removeSPITObject(message.getID());
|
||||
}
|
||||
}
|
||||
|
||||
int SClient::sendSPITObjectInternal(SObject *ptrSPITObject) {
|
||||
if (ptrSPITObject == nullptr)
|
||||
return -1;
|
||||
Message::ReportObject sMReportSPITObject;
|
||||
ptrSPITObject->fillMessageOP(sMReportSPITObject);
|
||||
|
||||
return sendSPITMessage(sMReportSPITObject);
|
||||
}
|
||||
/**
|
||||
* When the client changes an existing SPITObject (normally the client should not do this), then he should send the changes to the SPITServer.
|
||||
* An eventSPITObject occurs.
|
||||
* The SPITServer may discard the changes and a second eventSPITObject occurs to correct the changes.
|
||||
* @param obj the pointer to the changed SPITObject.
|
||||
* CAUTION: The SPITObject must already exist.
|
||||
* @return true = SPITObject is changed, false = not changed, maybe obj is NULL or the SPITObject doesn't exists
|
||||
*/
|
||||
bool SClient::changeSPITObject(SObject *obj) {
|
||||
if (obj == nullptr)
|
||||
return false;
|
||||
SObject *ptrSPITObject;
|
||||
SType *ptrSPITType;
|
||||
{
|
||||
ptrSPITObject = mSpitObjects.getEntry(obj->getID());
|
||||
if (ptrSPITObject == nullptr)
|
||||
return false;
|
||||
ptrSPITType = mProcessor.mSpitTypes.getEntry(obj->getID());
|
||||
if (ptrSPITObject == nullptr)
|
||||
return false;
|
||||
|
||||
ptrSPITObject->setActionAssigned(obj->getActionAssigned());
|
||||
;
|
||||
ptrSPITObject->Delay.set(obj->Delay.get());
|
||||
ptrSPITObject->Duration.set(obj->Delay.get());
|
||||
ptrSPITObject->Fixed.set(obj->Fixed.get());
|
||||
ptrSPITObject->FrameFadeInLength.set(obj->FrameFadeInLength.get());
|
||||
ptrSPITObject->FrameFadeOutLength.set(obj->FrameFadeOutLength.get());
|
||||
ptrSPITObject->FrameLength.set(obj->FrameLength.get());
|
||||
ptrSPITObject->FrameStart.set(obj->FrameStart.get());
|
||||
ptrSPITObject->Name.set(obj->Name.get());
|
||||
ptrSPITObject->Remark.set(obj->Remark.get());
|
||||
ptrSPITObject->SPITTypeID.set(obj->SPITTypeID.get());
|
||||
ptrSPITObject->ServerParams.set(obj->ServerParams.get());
|
||||
ptrSPITObject->Track.set(obj->Track.get());
|
||||
ptrSPITObject->ValueFactor.set(obj->ValueFactor.get());
|
||||
ptrSPITObject->ValueUse.set(obj->ValueUse.get());
|
||||
|
||||
mCallbacks.onSpitObject(ObjectEvent::Changed, false, *ptrSPITType, *ptrSPITObject);
|
||||
sendSPITObjectInternal(ptrSPITObject);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* When the client wants to remove a SPITObject with id == p_SPITObjectID (normally the client should not do this), then he should send it to the SPITServer.
|
||||
* The corresponding SPITObject if listet in SPITObject will be deleted.
|
||||
* An eventRemoveSPITType will occur.
|
||||
* If an connection to a SPITServer is established, the SPITServer may discard the deletion and an eventSPITObject occurs
|
||||
* -> the SPITObject is listet again.
|
||||
* @param objId the id of the SPITObject to remove.
|
||||
* @return 0 = sended to the SPITServer, -1 = not sended to the SPITServer or nos SPITObject with id == objId exists.
|
||||
*/
|
||||
int SClient::removeSPITObject(string objId) {
|
||||
if (objId.length() <= 0)
|
||||
return -1;
|
||||
SType *ptrSPITType;
|
||||
SObject *ptrSPITObject;
|
||||
{
|
||||
Message::RemoveObject sMRemoveSPITObject;
|
||||
|
||||
ptrSPITObject = mSpitObjects.getEntry(objId);
|
||||
if (ptrSPITObject == nullptr)
|
||||
return -1;
|
||||
ptrSPITType = mProcessor.mSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get());
|
||||
if (ptrSPITType == nullptr)
|
||||
return -1;
|
||||
ptrSPITObject->fillMessageOP(sMRemoveSPITObject);
|
||||
mCallbacks.onSpitObject(ObjectEvent::Deleted, false, *ptrSPITType, *ptrSPITObject);
|
||||
mSpitObjects.removeEntry(*ptrSPITObject);
|
||||
return sendSPITMessage(sMRemoveSPITObject);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//----- Play SPIT Objects ------
|
||||
|
||||
void SClient::parsePlaySPITStart(Message::PlayStart &message) {
|
||||
ESP_LOGD(TAG, "parse PlayStart ID: %s Name: %s Running: %d", message.getPlayerID().c_str(), message.getPlayerName().c_str(), (int)message.getPlayerIsRunning());
|
||||
SPlayer &spitPlayer = SPlayer::getSPITPlayer(message.getPlayerID());
|
||||
spitPlayer.setIsRunning(message.getPlayerIsRunning());
|
||||
spitPlayer.setName(message.getPlayerName());
|
||||
spitPlayer.setType(message.getPlayerType());
|
||||
spitPlayer.setTime(message.getTime());
|
||||
spitPlayer.startPlaySequence();
|
||||
|
||||
mCallbacks.onPlay(spitPlayer.getID(), spitPlayer.getName(), spitPlayer.getType(), spitPlayer.getIsRunning(), spitPlayer.getTime());
|
||||
}
|
||||
void SClient::parsePlaySPITObject(Message::PlayObject &message) {
|
||||
|
||||
SPlayer &ptrSPITPlayer = SPlayer::getSPITPlayer(message.getPlayerID());
|
||||
SObject *ptrSPITObject = mSpitObjects.getEntry(message.getSPITObjectID());
|
||||
|
||||
if (ptrSPITObject == nullptr) {
|
||||
return;
|
||||
}
|
||||
SPlayer::PlayType *ptrPlaySPITType = ptrSPITPlayer.addTypePlaying(ptrSPITObject->SPITTypeID.get());
|
||||
if (ptrPlaySPITType == nullptr) {
|
||||
return;
|
||||
}
|
||||
ptrPlaySPITType->setPlayerIsRunning(ptrSPITPlayer.getIsRunning());
|
||||
ptrPlaySPITType->addValue(((double)message.getValue() / 1000000), ((double)ptrSPITObject->ValueFactor.get() / 1000000));
|
||||
}
|
||||
|
||||
void SClient::parsePlaySPITEnd(Message::PlayEnd &message) {
|
||||
SPlayer &ptrSPITPlayer = SPlayer::getSPITPlayer(message.getPlayerID());
|
||||
|
||||
auto &ptrPlaySPITTypes = ptrSPITPlayer.getPlaySPITTypes();
|
||||
for (auto i = ptrPlaySPITTypes.begin(); i != ptrPlaySPITTypes.end(); i++) {
|
||||
SPlayer::PlayType *ptrPlaySPITType = i->second.get();
|
||||
bool boolStarted = ptrPlaySPITType->getIsNew();
|
||||
bool boolStopped = (ptrPlaySPITType->getIsPlayed() == false);
|
||||
SType *ptrSPITType = mProcessor.mSpitTypes.getEntry(ptrPlaySPITType->getSPITTypeID());
|
||||
if (ptrSPITType == nullptr) {
|
||||
// set isplayed to false, the ptrPlayObject will be removed by ptrSPITPlayer.endPlaySequence()
|
||||
ptrPlaySPITType->setIsPlayed(false);
|
||||
continue;
|
||||
}
|
||||
mCallbacks.onPlaySpitType(ptrPlaySPITType->getPlayerID(), ptrPlaySPITType->getSPITTypeID(), ptrPlaySPITType->getPlayerIsRunning(), boolStarted, boolStopped, ptrPlaySPITType->getValue());
|
||||
}
|
||||
ptrSPITPlayer.endPlaySequence();
|
||||
}
|
||||
|
||||
void SClient::parseReportPlayStatus(Message::ReportPlayStatus &message) {
|
||||
SType *ptrSPITType = NULL;
|
||||
|
||||
SObject *ptrSPITObject = mRemoteSpitObjects.getEntry(message.getID());
|
||||
if (ptrSPITObject == nullptr) {
|
||||
ptrSPITObject = mSpitObjects.getEntry(message.getID());
|
||||
if (ptrSPITObject == nullptr) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ptrSPITObject->ServerRemote.get() == false) {
|
||||
ptrSPITType = mProcessor.mSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get());
|
||||
} else {
|
||||
ptrSPITType = mProcessor.mRemoteSpitTypes.getEntry(ptrSPITObject->SPITTypeID.get());
|
||||
}
|
||||
|
||||
if (ptrSPITType == nullptr) {
|
||||
return;
|
||||
}
|
||||
mCallbacks.onPlayRemoteObjectStatus(*ptrSPITType, *ptrSPITObject, message.getFrameInsideObject(), message.getValue());
|
||||
}
|
||||
|
||||
//--------- Remote ----------
|
||||
|
||||
/**
|
||||
* Send a remote control command to the SPITServer.
|
||||
* There may be different command types:
|
||||
* a) Some don't use value e.g. go to next scene, olay a jingle
|
||||
* b) Some use values e.g. the main sound fader
|
||||
* @param p_SPITObjectID the id of the remote SPITObject (this represents the remote control command)
|
||||
* @param valuePpm the value in ppm
|
||||
* in case a) the value is ignored
|
||||
* in case b) the value is used
|
||||
* @param valueFlag indicates how the server should use valuePpm:
|
||||
* VALUEFLAG_DIRECT (0x00) The server overwrites its existing value with p_Value
|
||||
* VALUEFLAG_INCREASE (0x01) The server increases his existing value by valuePpm
|
||||
* VALUEFLAG_DECREASE (0x01) The server decreases his existing value by valuePpm
|
||||
*/
|
||||
void SClient::sendRemoteObject(string p_SPITObjectID, int valuePpm, char valueFlag) {
|
||||
SObject *ptrRemoteSPITObject = mRemoteSpitObjects.getEntry(p_SPITObjectID);
|
||||
if (ptrRemoteSPITObject == nullptr)
|
||||
return;
|
||||
|
||||
Message::PlayStart playSPITStart(mID, mProjName, PLAYERTYPE_DISCRETE);
|
||||
playSPITStart.setPlayerIsRunning(false);
|
||||
playSPITStart.setTime(0);
|
||||
sendSPITMessage(playSPITStart);
|
||||
|
||||
Message::PlayObject playSPITObject;
|
||||
playSPITObject.setID(ptrRemoteSPITObject->getID());
|
||||
playSPITObject.setPlayPrePosition(false);
|
||||
playSPITObject.setPlayerID(mID);
|
||||
playSPITObject.setValue(valuePpm);
|
||||
playSPITObject.setValueFlag(valueFlag);
|
||||
sendSPITMessage(playSPITObject);
|
||||
|
||||
Message::PlayEnd playSPITEnd(mID);
|
||||
sendSPITMessage(playSPITEnd);
|
||||
SType *SClient::createTypeFixed(string iD, string group, string name, uint64_t delay, uint64_t duration) {
|
||||
return mProcessor.createType(iD, group, name, delay, duration, true, true);
|
||||
}
|
||||
|
||||
fos::Semaphore SClient::sStartSad;
|
||||
@@ -1302,7 +623,7 @@ void SClient::processSocketTask(SClient &instance) {
|
||||
ESP_LOGW(TAG, "Finished searching");
|
||||
ESP_LOGW(TAG, "Start working");
|
||||
auto nextWdTrigger = fos::Timing::getMilliSec() + WATCHDOGTIME;
|
||||
auto nextWdCheck = nextWdTrigger + WATCHDOGTIME;
|
||||
// auto nextWdCheck = nextWdTrigger + WATCHDOGTIME;
|
||||
while (true) {
|
||||
// auto time = fos::Timing::getMilliSec();
|
||||
// if (time > nextWdTrigger) {
|
||||
|
||||
+639
-1126
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,5 @@
|
||||
-- COPY to: /usr/lib/x86_64-linux-gnu/wireshark/plugins/spit.lua
|
||||
|
||||
-- LiveShowSoftware SPIT-Protocol
|
||||
spit_proto = Proto("spit", "LiveShowSoftware SPIT")
|
||||
spit_sad_proto = Proto("spit_sad", "LiveShowSoftware SPIT SAD")
|
||||
@@ -9,7 +11,7 @@ local f_hLen = ProtoField.uint32("spit.len", "Length")
|
||||
local f_hSerId = ProtoField.string("spit.serverId", "ServerID")
|
||||
local f_hCliId = ProtoField.string("spit.clientId", "ClientID")
|
||||
local f_hType = ProtoField.uint8("spit.msgType", "MsgType")
|
||||
local f_pLen = ProtoField.uint32("spit.paylen", "Length")
|
||||
local f_pLen = ProtoField.uint32("spit.paylen", "Payload Length")
|
||||
|
||||
local f_pSession = ProtoField.string("spit.key", "Spit Session")
|
||||
local f_pKey = ProtoField.string("spit.key", "Spit Key")
|
||||
@@ -94,6 +96,17 @@ function extractVersionString(buffer)
|
||||
|
||||
end
|
||||
|
||||
function addBigEndianValue(tree, proto, buffer)
|
||||
local val = -1;
|
||||
-- local val = buffer(99,4):le_uint()
|
||||
if proto.type == ftypes.UINT32 then
|
||||
val = buffer:le_uint()
|
||||
elseif proto.type == ftypes.UINT64 then
|
||||
val = buffer:le_uint64()
|
||||
end
|
||||
tree:add(proto, buffer):set_text(proto.name .. ": " .. val)
|
||||
end
|
||||
|
||||
-- Heuristic dissector function
|
||||
function spit_proto.dissector(buffer, pinfo, tree)
|
||||
if buffer:len() < 6 then return false end
|
||||
@@ -114,8 +127,9 @@ function spit_proto.dissector(buffer, pinfo, tree)
|
||||
hTree:add(f_hType, buffer(98,1))
|
||||
|
||||
local pTree = subtree:add("Payload")
|
||||
local pLen = buffer(99,4):le_uint()
|
||||
pTree:add(f_pLen, buffer(99,4)):set_text("Pyload Length: " .. pLen)
|
||||
-- local pLen = buffer(99,4):le_uint()
|
||||
-- pTree:add(f_pLen, buffer(99,4)):set_text("Pyload Length: " .. pLen)
|
||||
addBigEndianValue(pTree, f_pLen, buffer(99,4))
|
||||
|
||||
local info_text = "Type: " .. type
|
||||
if type == 1 then -- Connect
|
||||
@@ -166,7 +180,7 @@ function spit_proto.dissector(buffer, pinfo, tree)
|
||||
|
||||
pTree:add(f_pProjectId, buffer(103,41))
|
||||
pTree:add(f_pProjectName, buffer(144,64))
|
||||
pTree:add(f_pFramesPerSec, buffer(208,4))
|
||||
addBigEndianValue(pTree, f_pFramesPerSec, buffer(208,4))
|
||||
info_text = string.format("%s -> %s | Report Project | Project: %s / %s",
|
||||
sessionInfos[tostring(pinfo.src)], sessionInfos[tostring(pinfo.dst)], buffer(103,41):string(), buffer(144,64):string())
|
||||
|
||||
@@ -202,8 +216,8 @@ function spit_proto.dissector(buffer, pinfo, tree)
|
||||
pTree:add(f_pProjIndep, buffer(147,1))
|
||||
pTree:add(f_pTypeGroupName, buffer(148,39))
|
||||
pTree:add(f_pTypeName, buffer(187,64))
|
||||
pTree:add(f_pDelay, buffer(251,8))
|
||||
pTree:add(f_pDuration, buffer(259,8))
|
||||
addBigEndianValue(pTree, f_pDelay, buffer(251,8))
|
||||
addBigEndianValue(pTree, f_pDuration, buffer(259,8))
|
||||
|
||||
local group = buffer(148,39):string()
|
||||
local name = buffer(187,64):string()
|
||||
@@ -226,17 +240,16 @@ function spit_proto.dissector(buffer, pinfo, tree)
|
||||
pTree:add(f_pObjectName, buffer(147,64))
|
||||
pTree:add(f_pTypeId, buffer(211,41))
|
||||
pTree:add(f_pSrvParam, buffer(252,64))
|
||||
pTree:add(f_pFrameStart, buffer(316,8))
|
||||
pTree:add(f_pFrameLength, buffer(324,8))
|
||||
pTree:add(f_pFrameFadeIn, buffer(332,8))
|
||||
pTree:add(f_pFrameFadeOut, buffer(340,8))
|
||||
local valueFactor = buffer(348,4):le_uint()
|
||||
pTree:add(f_pValueFactor, buffer(348,4)):set_text("Value Factor" .. valueFactor)
|
||||
addBigEndianValue(pTree, f_pFrameStart, buffer(316,8))
|
||||
addBigEndianValue(pTree, f_pFrameLength, buffer(324,8))
|
||||
addBigEndianValue(pTree, f_pFrameFadeIn, buffer(332,8))
|
||||
addBigEndianValue(pTree, f_pFrameFadeOut, buffer(340,8))
|
||||
addBigEndianValue(pTree, f_pValueFactor, buffer(348,4))
|
||||
pTree:add(f_pValueUse, buffer(349,1))
|
||||
pTree:add(f_pTrack, buffer(350,4))
|
||||
addBigEndianValue(pTree, f_pTrack, buffer(350,4))
|
||||
pTree:add(f_pRemark, buffer(354,64))
|
||||
pTree:add(f_pDelay, buffer(418,8))
|
||||
pTree:add(f_pDuration, buffer(426,8))
|
||||
addBigEndianValue(pTree, f_pDelay, buffer(418,8))
|
||||
addBigEndianValue(pTree, f_pDuration, buffer(426,8))
|
||||
pTree:add(f_pAssigned, buffer(435,1))
|
||||
|
||||
local name = buffer(147,64):string()
|
||||
@@ -257,17 +270,16 @@ function spit_proto.dissector(buffer, pinfo, tree)
|
||||
pTree:add(f_pPlayerName, buffer(144,64))
|
||||
pTree:add(f_pPlayerType, buffer(208,1))
|
||||
pTree:add(f_pPlayerRunning, buffer(209,1))
|
||||
pTree:add(f_pPlayerFrames, buffer(210,8))
|
||||
addBigEndianValue(pTree, f_pPlayerFrames, buffer(210,8))
|
||||
info_text = string.format("Play SPIT Start")
|
||||
|
||||
elseif type == 38 then -- Play Spit object
|
||||
pTree:add(f_pSession, extractSession(buffer, pinfo))
|
||||
|
||||
pTree:add(f_pPlayerId, buffer(103,41))
|
||||
pTree:add(f_pObjectId, buffer(144,41))
|
||||
pTree:add(f_pObjectsFrames, buffer(185,8))
|
||||
addBigEndianValue(pTree, f_pObjectsFrames, buffer(185,8))
|
||||
pTree:add(f_pPlayerPrePos, buffer(193,1))
|
||||
pTree:add(f_pValue, buffer(194,4))
|
||||
addBigEndianValue(pTree, f_pValue, buffer(194,4))
|
||||
pTree:add(f_pValueFlag, buffer(198,1))
|
||||
|
||||
local oId = buffer(144,41):string()
|
||||
@@ -281,10 +293,9 @@ function spit_proto.dissector(buffer, pinfo, tree)
|
||||
|
||||
elseif type == 40 then
|
||||
pTree:add(f_pSession, extractSession(buffer, pinfo))
|
||||
|
||||
pTree:add(f_pObjectId, buffer(103,41))
|
||||
pTree:add(f_pObjectsFrames, buffer(144,8))
|
||||
pTree:add(f_pValue, buffer(152,4))
|
||||
addBigEndianValue(pTree, f_pObjectsFrames, buffer(144,8))
|
||||
addBigEndianValue(pTree, f_pValue, buffer(152,4))
|
||||
info_text = string.format("Report Play Status")
|
||||
|
||||
else
|
||||
@@ -348,15 +359,3 @@ spit_proto:register_heuristic("udp", spit_proto.dissector)
|
||||
|
||||
spit_sad_proto:register_heuristic("udp", spit_sad_proto.dissector)
|
||||
|
||||
|
||||
-- local f_pFramesPerSec = ProtoField.uint32("spit.framesPerSec", "Frames per second")
|
||||
-- local f_pTrack = ProtoField.uint32("spit.track", "Track")
|
||||
-- local f_pObjectsFrames = ProtoField.uint64("spit.ObjectFrames", "Object Frames")
|
||||
-- local f_pValue = ProtoField.uint64("spit.Value", "Value")
|
||||
-- local f_pFrameStart = ProtoField.uint64("spit.frameStart", "Frame Start")
|
||||
-- local f_pFrameLength = ProtoField.uint64("spit.frameLength", "Frame Length")
|
||||
-- local f_pFrameFadeIn = ProtoField.uint64("spit.fadeInLength", "Fade In Length")
|
||||
-- local f_pFrameFadeOut = ProtoField.uint64("spit.fadeOutLength", "Fade Out Length")
|
||||
-- local f_pDelay = ProtoField.uint64("spit.delay", "Delay")
|
||||
-- local f_pDuration = ProtoField.uint64("spit.duration", "Duration")
|
||||
-- local f_pPlayerFrames = ProtoField.uint64("spit.PlayerFrame", "Player Frames")
|
||||
|
||||
@@ -46,6 +46,8 @@ class ClientMock {
|
||||
|
||||
class SpitClientFix {
|
||||
protected:
|
||||
std::vector<string> messages;
|
||||
|
||||
ClientMock client;
|
||||
SProcessor::Callbacks callbacks{
|
||||
.onServerEvent = [&](SProcessor::ServerEvent event, const SadDetectedServer &detectedServer) { client.onServerEvent(event, detectedServer); },
|
||||
@@ -58,11 +60,18 @@ class SpitClientFix {
|
||||
.onPlayRemoteObjectStatus = [&](const SType &t, const SObject &o, uint64_t p_FrameInsideObject, int value) { client.onPlayRemoteObjectStatus(t, o, p_FrameInsideObject, value); },
|
||||
.onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient) { return client.onCheckSpitTypeVeto(knownType, createdByClient); },
|
||||
.onCheckSpitObjectVeto = [&](bool knownType) { return client.onCheckSpitObjectVeto(knownType); }};
|
||||
SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks};
|
||||
SProcessor::InternalCallbacks intCallbacks{
|
||||
.delay = [&](int ms) { return; },
|
||||
.sendMessage = [&](Message::OPPart &msg) { return 0; },
|
||||
.parseMessage = [&](Message &msg) {
|
||||
// auto o = fmt::format("msg-{}", msg.getHeader()->getMessageNumber());
|
||||
// messages.push_back(o);
|
||||
},
|
||||
};
|
||||
SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks, intCallbacks};
|
||||
};
|
||||
|
||||
TEST_CASE_FIXTURE(SpitClientFix, "Spit types") {
|
||||
|
||||
{
|
||||
Message::ReportType t;
|
||||
t.setConfirmed(false);
|
||||
@@ -168,3 +177,174 @@ TEST_CASE_FIXTURE(SpitClientFix, "Spit types") {
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
}
|
||||
|
||||
TEST_CASE_FIXTURE(SpitClientFix, "Message Counter") {
|
||||
Message::ReportType t1;
|
||||
t1.setID("type#1");
|
||||
t1.setServerRemote(true);
|
||||
auto m1 = sut.createMessage(t1);
|
||||
|
||||
Message::ReportType t2;
|
||||
t2.setID("type#2");
|
||||
t2.setServerRemote(true);
|
||||
auto m2 = sut.createMessage(t2);
|
||||
|
||||
Message::ReportType t3;
|
||||
t3.setID("type#3");
|
||||
t3.setServerRemote(true);
|
||||
auto m3 = sut.createMessage(t3);
|
||||
|
||||
Message::ReportType t4;
|
||||
t4.setID("type#4");
|
||||
t4.setServerRemote(true);
|
||||
auto m4 = sut.createMessage(t4);
|
||||
|
||||
Message::ReportType t5;
|
||||
t5.setID("type#5");
|
||||
t5.setServerRemote(true);
|
||||
auto m5 = sut.createMessage(t5);
|
||||
|
||||
Message::ReportType t6;
|
||||
t6.setID("type#6");
|
||||
t6.setServerRemote(true);
|
||||
auto m6 = sut.createMessage(t6);
|
||||
|
||||
CHECK(cbEvents.empty());
|
||||
SUBCASE("Normal order") {
|
||||
REQUIRE(cbEvents.size() == 0);
|
||||
sut.checkParseMessageData(m1);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m2);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m3);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m4);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
}
|
||||
|
||||
CHECK(cbEvents.empty());
|
||||
SUBCASE("overtakes one") {
|
||||
REQUIRE(cbEvents.size() == 0);
|
||||
sut.checkParseMessageData(m1);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m3);
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m2);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m4);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
}
|
||||
|
||||
CHECK(cbEvents.empty());
|
||||
SUBCASE("overtakes two") {
|
||||
REQUIRE(cbEvents.size() == 0);
|
||||
sut.checkParseMessageData(m1);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m4);
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m2);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m3);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m5);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#5 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
}
|
||||
|
||||
CHECK(cbEvents.empty());
|
||||
SUBCASE("many overtakes") {
|
||||
REQUIRE(cbEvents.size() == 0);
|
||||
sut.checkParseMessageData(m1);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m5);
|
||||
CHECK(cbEvents.empty());
|
||||
sut.checkParseMessageData(m6);
|
||||
CHECK(cbEvents.empty());
|
||||
sut.checkParseMessageData(m4);
|
||||
CHECK(cbEvents.empty());
|
||||
sut.checkParseMessageData(m3);
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m2);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#5 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#6 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
}
|
||||
|
||||
CHECK(cbEvents.empty());
|
||||
SUBCASE("reverse order") {
|
||||
REQUIRE(cbEvents.size() == 0);
|
||||
sut.checkParseMessageData(m1);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m6);
|
||||
CHECK(cbEvents.empty());
|
||||
sut.checkParseMessageData(m5);
|
||||
CHECK(cbEvents.empty());
|
||||
sut.checkParseMessageData(m4);
|
||||
CHECK(cbEvents.empty());
|
||||
sut.checkParseMessageData(m3);
|
||||
CHECK(cbEvents.empty());
|
||||
|
||||
sut.checkParseMessageData(m2);
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#5 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK_MESSAGE(cbEvents.front() == "0: true type#6 ", cbEvents.front());
|
||||
cbEvents.pop();
|
||||
CHECK(cbEvents.empty());
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,12 @@ class SpitClientCmplsFix {
|
||||
.onPlayRemoteObjectStatus = [&](const SType &t, const SObject &o, uint64_t p_FrameInsideObject, int value) { client.onPlayRemoteObjectStatus(t, o, p_FrameInsideObject, value); },
|
||||
.onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient) { return client.onCheckSpitTypeVeto(knownType, createdByClient); },
|
||||
.onCheckSpitObjectVeto = [&](bool knownType) { return client.onCheckSpitObjectVeto(knownType); }};
|
||||
SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks};
|
||||
SProcessor::InternalCallbacks intCallbacks {
|
||||
.delay = [&](int ms){ return ; },
|
||||
.sendMessage = [&](Message::OPPart &msg){ return 0; },
|
||||
.parseMessage = [&](Message &msg) { },
|
||||
};
|
||||
SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks, intCallbacks};
|
||||
};
|
||||
|
||||
static void spoofMsgCounter(std::vector<uint8_t> &msg, uint8_t cnt) {
|
||||
|
||||
@@ -3,15 +3,17 @@
|
||||
#include "stepperDrv.hpp"
|
||||
#include "stepperMotor.hpp"
|
||||
#include <cmath>
|
||||
#include "logging.hpp"
|
||||
|
||||
class WatchMotor {
|
||||
static constexpr uint8_t Positions = 6;
|
||||
|
||||
public:
|
||||
using AllmostFinishedCb = void (*)(uint8_t newIdx);
|
||||
WatchMotor(IStepperMotor &stepper, AllmostFinishedCb onDone)
|
||||
using AlmostFinishedCb = void (*)(uint8_t newIdx);
|
||||
WatchMotor(IStepperMotor &stepper, AlmostFinishedCb onDone, ILogging &logger)
|
||||
: _stepper(stepper),
|
||||
_onFinCb(onDone) {
|
||||
_onFinCb(onDone),
|
||||
_logger(logger) {
|
||||
}
|
||||
|
||||
void moveTo(uint8_t position, uint8_t profile, int minJumps, float accel, float speed) {
|
||||
@@ -44,7 +46,12 @@ class WatchMotor {
|
||||
|
||||
ESP_LOGD("MV", "Moving to %d by %.2f + %.2f", sign, delta, corr);
|
||||
|
||||
_stepper.moveBy(delta + corr, profile, accel, speed, [&]() {
|
||||
_stepper.moveBy(delta + corr, profile, accel, speed, [&](int diff) {
|
||||
_logger.logv(ILogging::Severity::Debug,"Almost done with head=%i",diff);
|
||||
if (diff < 6) {
|
||||
_logger.logv(ILogging::Severity::Warning,"Low headroom in Profile pipeline=%i",diff);
|
||||
}
|
||||
|
||||
if (_onFinCb) {
|
||||
_onFinCb(position);
|
||||
}
|
||||
@@ -58,5 +65,6 @@ class WatchMotor {
|
||||
private:
|
||||
IStepperMotor &_stepper;
|
||||
uint8_t _currentIndex{};
|
||||
AllmostFinishedCb _onFinCb{};
|
||||
AlmostFinishedCb _onFinCb{};
|
||||
ILogging &_logger;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
UnitTestsFrame()
|
||||
target_link_libraries(${moduleName} PUBLIC
|
||||
devHal
|
||||
bases
|
||||
)
|
||||
@@ -19,7 +19,7 @@ class StepperMotorMock : public IStepperMotor {
|
||||
lastAngle = angle;
|
||||
lastProfile = profile;
|
||||
}
|
||||
void moveBy(float angle, uint8_t profile, float accel, float speed, std::function<void()> profileDone = nullptr) override {
|
||||
void moveBy(float angle, uint8_t profile, float accel, float speed, std::function<void(int diff)> profileDone = nullptr) override {
|
||||
lastAngle = angle;
|
||||
lastProfile = profile;
|
||||
}
|
||||
@@ -37,6 +37,12 @@ class StepperMotorMock : public IStepperMotor {
|
||||
float nextPos{};
|
||||
};
|
||||
|
||||
class LoggerMock : public ILogging {
|
||||
void output(Severity severity, std::string message) override {
|
||||
// do nothing
|
||||
}
|
||||
};
|
||||
|
||||
void onFin(uint8_t idx) {
|
||||
}
|
||||
|
||||
@@ -47,7 +53,8 @@ class WatchFaceFixture {
|
||||
protected:
|
||||
static constexpr int MicroSteps = 32;
|
||||
StepperMotorMock motor;
|
||||
WatchMotor sut{motor, onFin};
|
||||
LoggerMock logger;
|
||||
WatchMotor sut{motor, onFin, logger};
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
+1
-1
Submodule core updated: e09e7dc576...37e288c012
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -7,6 +7,7 @@ struct {
|
||||
const char *mqttBroker = "mqttBroker"; // example: "172.16.16.10"
|
||||
const char *mqttPrefix = "mqttPrefix"; // example: "SomeTag"
|
||||
const char *spitServer = "spitServer"; // example: "172.16.16.10"
|
||||
const char *motorPower = "motorPower"; // example: "50"
|
||||
} ConfigKeys;
|
||||
|
||||
// MQTT Topics
|
||||
+112
-36
@@ -17,7 +17,7 @@
|
||||
// activeState.speed = (min .5 / max 3)
|
||||
|
||||
#include "watchMain.hpp"
|
||||
#include "interconConfig.hpp"
|
||||
#include "config.hpp"
|
||||
|
||||
using namespace spit;
|
||||
|
||||
@@ -104,7 +104,7 @@ void testPictoIllum(Cli::CArgs args) {
|
||||
int p = std::stoi(args[0]);
|
||||
pictoIllumQue.enqueue(std::make_unique<PictoIllumCommand>(p));
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGI(TAG, "Failed to parse %s and %s", args[0].c_str(), args[1].c_str());
|
||||
ESP_LOGI(TAG, "Failed to parse %s", args[0].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,10 +121,10 @@ void testMovement(Cli::CArgs args) {
|
||||
activeState.profile = std::min(4, std::stoi(args[1]));
|
||||
}
|
||||
if (args.size() >= 3) {
|
||||
activeState.minJumps = std::min(20, std::stoi(args[2])) ;
|
||||
activeState.minJumps = std::min(20, std::stoi(args[2]));
|
||||
}
|
||||
if (args.size() >= 4) {
|
||||
activeState.minJumps = std::min(40, std::stoi(args[3])) ;
|
||||
activeState.minJumps = std::min(40, std::stoi(args[3]));
|
||||
}
|
||||
commandQueue.enqueue(std::make_unique<MoveCommand>(MoveType::StepTo, p));
|
||||
} catch (const std::exception &e) {
|
||||
@@ -132,6 +132,25 @@ void testMovement(Cli::CArgs args) {
|
||||
}
|
||||
}
|
||||
|
||||
void testFeedback(Cli::CArgs args) {
|
||||
ESP_LOGI(TAG, "on triggerMovement:");
|
||||
if (args.size() != 1) {
|
||||
pShell->writeLine("need target position (1..6) or 0 for moving");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
int p = std::stoi(args[0]);
|
||||
if (p == 0) {
|
||||
responseQueue.enqueue(std::make_unique<WatchIndex>(ResponseType::StartMoving, 0));
|
||||
} else {
|
||||
responseQueue.enqueue(std::make_unique<WatchIndex>(ResponseType::StepAt, p));
|
||||
}
|
||||
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGI(TAG, "Failed to parse %s", args[0].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void setConfig(Cli::CArgs args) {
|
||||
if (args.size() != 2) {
|
||||
pShell->writeLine("Needs string key and value");
|
||||
@@ -179,7 +198,7 @@ void showProcessValues(Cli::CArgs args) {
|
||||
pShell->writeLine("Process values:");
|
||||
char buff[256];
|
||||
|
||||
sprintf(buff, "%02x,%02x,%02x", activeState.color.getRed(),activeState.color.getGreen(),activeState.color.getBlue());
|
||||
sprintf(buff, "%02x,%02x,%02x", activeState.color.getRed(), activeState.color.getGreen(), activeState.color.getBlue());
|
||||
pShell->writeLine(std::string{" Color RGB: "} + buff);
|
||||
sprintf(buff, "%.2f / %.2f", activeState.accel, activeState.speed);
|
||||
pShell->writeLine(std::string{" Accel/Speed: "} + buff);
|
||||
@@ -187,9 +206,22 @@ void showProcessValues(Cli::CArgs args) {
|
||||
pShell->writeLine(std::string{" Provile: "} + std::to_string((int)activeState.profile));
|
||||
}
|
||||
|
||||
void startDemoMovement(Cli::CArgs args) {
|
||||
ESP_LOGI(TAG, "on startDemoMovement:");
|
||||
commandQueue.enqueue(std::make_unique<MoveCommand>(MoveType::Demo));
|
||||
void setSyslogLevel(Cli::CArgs args) {
|
||||
if (args.size() != 1) {
|
||||
pShell->writeLine("Needs SyslogLevel Warning = 4, Notice = 5, Informational = 6, Debug = 7");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
auto lvl = std::stoi(args[0]);
|
||||
if (lvl >= (int)Syslog::Severity::Warning && lvl <= (int)Syslog::Severity::Debug) {
|
||||
Syslog::setSeverity((Syslog::Severity)lvl);
|
||||
} else {
|
||||
pShell->writeLine("New level was not accepted");
|
||||
}
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGI(TAG, "Failed to parse %s", args[0].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,8 +241,11 @@ static void telnetSocketTask(int addrFamily) {
|
||||
{"update", "Start OTA-Update-Process",
|
||||
[](Cli::CArgs a) { startUpdate(a); }});
|
||||
pShell->addBinding(
|
||||
{"logserver_set", "Set log server config ip",
|
||||
{"setLogserver", "Set log server config ip",
|
||||
[](Cli::CArgs a) { setLogServerConfig(a); }});
|
||||
pShell->addBinding(
|
||||
{"setLogLevel", "Set severity log server",
|
||||
[](Cli::CArgs a) { setSyslogLevel(a); }});
|
||||
|
||||
pShell->addBinding(
|
||||
{"getcfg", "Get configuration value for key",
|
||||
@@ -220,7 +255,7 @@ static void telnetSocketTask(int addrFamily) {
|
||||
[](Cli::CArgs a) { setConfig(a); }});
|
||||
|
||||
pShell->addBinding(
|
||||
{"dyn_set", "set dynamics of movement (velocity,accelerations) as floats",
|
||||
{"setDyn", "set dynamics of movement (velocity,accelerations) as floats",
|
||||
[](Cli::CArgs a) { setDynamics(a); }});
|
||||
pShell->addBinding(
|
||||
{"tstMove", "start movement (profile-idx,steps) as integers ",
|
||||
@@ -228,6 +263,9 @@ static void telnetSocketTask(int addrFamily) {
|
||||
pShell->addBinding(
|
||||
{"tstIllum", "test illumination command 0=off /1..6",
|
||||
[](Cli::CArgs a) { testPictoIllum(a); }});
|
||||
pShell->addBinding(
|
||||
{"tstFb", "test feedback-channel to control 0=Move /1..6=FinalPos",
|
||||
[](Cli::CArgs a) { testFeedback(a); }});
|
||||
pShell->addBinding(
|
||||
{"showData", "Show process values that are input by DMX, MQTT and SPIT",
|
||||
[](Cli::CArgs a) { showProcessValues(a); }});
|
||||
@@ -404,28 +442,28 @@ static void initialize_ethernet(void) {
|
||||
}
|
||||
|
||||
namespace Effect {
|
||||
extern const WaveForm_t OffsetPulseWave{gau8_offsetPulse, cu16_TemplateLength};
|
||||
extern const WaveForm_t InitSlopeWave{gau8_initSlope, cu16_TemplateLength};
|
||||
extern const WaveForm_t OffsetSlopeWave{gau8_offsetSlope, cu16_TemplateLength};
|
||||
extern const WaveForm_t FullSlopeWave{gau8_fullSlope, cu16_TemplateLength};
|
||||
extern const WaveForm_t FullPulseWave{gau8_fullPulse, cu16_TemplateLength};
|
||||
extern const WaveForm_t OffsetPulseWave{gau8_offsetPulse, cu16_TemplateLength};
|
||||
extern const WaveForm_t InitSlopeWave{gau8_initSlope, cu16_TemplateLength};
|
||||
extern const WaveForm_t OffsetSlopeWave{gau8_offsetSlope, cu16_TemplateLength};
|
||||
extern const WaveForm_t FullSlopeWave{gau8_fullSlope, cu16_TemplateLength};
|
||||
extern const WaveForm_t FullPulseWave{gau8_fullPulse, cu16_TemplateLength};
|
||||
|
||||
const Macro macDemoStart = {
|
||||
const Macro macDemoStart = {
|
||||
{64, 1, &InitSlopeWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 1, StateMachine::UpdateIdle, 0xFF},
|
||||
};
|
||||
};
|
||||
|
||||
const Macro macDemoPulse = {
|
||||
const Macro macDemoPulse = {
|
||||
{64, 1, &InitSlopeWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 2, StateMachine::UpdateIdle, 0xFF},
|
||||
{64, 1, &OffsetPulseWave, StateMachine::UpdateWave, 0xFF},
|
||||
};
|
||||
};
|
||||
|
||||
const Macro macDemoFlicker = {
|
||||
const Macro macDemoFlicker = {
|
||||
{16, 1, &InitSlopeWave, StateMachine::UpdateWave, 0xFF},
|
||||
{32, 1, StateMachine::UpdateFlicker, 0xFF},
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace Effect
|
||||
|
||||
void LightingTask() {
|
||||
ESP_LOGI(TAG, "Start Lighting");
|
||||
@@ -475,7 +513,7 @@ void LightingTask() {
|
||||
};
|
||||
|
||||
while (true) {
|
||||
auto onPos = pictoIllumQue.dequeue(0);
|
||||
auto onPos = pictoIllumQue.tryDequeue();
|
||||
if (onPos) {
|
||||
ESP_LOGI(TAG, "Changing picto-Illum to pos = %i", onPos->pos);
|
||||
ESP_LOGI(TAG, "Current color set r%i g%i b%i ",
|
||||
@@ -520,7 +558,20 @@ void MovementTask() {
|
||||
{LEDC_CHANNEL_0, LEDC_CHANNEL_1, LEDC_CHANNEL_2, LEDC_CHANNEL_3},
|
||||
{GPIO_NUM_21, GPIO_NUM_20, GPIO_NUM_23, GPIO_NUM_22},
|
||||
};
|
||||
StepperDriverDrv8833 stepperDriver(stepperPins, MicroSteps, 0.25F);
|
||||
|
||||
float power = 0.25F;
|
||||
// try
|
||||
// {
|
||||
// auto pwr = store.getValue(ConfigKeys.motorPower);
|
||||
// power = std::stof(pwr);
|
||||
// }
|
||||
// catch(...)
|
||||
// {
|
||||
// std::cerr << e.what() << '\n';
|
||||
// ESP_LOGI("Stepper", "Applying default");
|
||||
// }
|
||||
|
||||
StepperDriverDrv8833 stepperDriver(stepperPins, MicroSteps, power);
|
||||
stepperDriver.setPos(0);
|
||||
|
||||
StepperConfig stepperCfg{1.8F, MicroSteps};
|
||||
@@ -534,10 +585,11 @@ void MovementTask() {
|
||||
|
||||
StepperMotor stepper(stepperCfg, stepperDriver, initSens);
|
||||
|
||||
SyslogInst logger;
|
||||
WatchMotor watch(stepper, [](uint8_t newPos) {
|
||||
pictoIllumQue.enqueue(std::make_unique<PictoIllumCommand>(newPos));
|
||||
responseQueue.enqueue(std::make_unique<WatchIndex>(ResponseType::StepAt, newPos));
|
||||
});
|
||||
}, logger);
|
||||
|
||||
ESP_LOGI("Stepper", "Find Home");
|
||||
stepper.findRef();
|
||||
@@ -583,6 +635,33 @@ void MovementTask() {
|
||||
// pictoIllumQue.enqueue(std::make_unique<PictoIllumCommand>(newPos));
|
||||
// responseQueue.enqueue(std::make_unique<WatchIndex>(ResponseType::StepAt, newPos));
|
||||
}
|
||||
} else if (cmd->type == MoveType::Shuffle) {
|
||||
Syslog::logv(Syslog::Severity::Informational,
|
||||
"Starting Shuffle mode");
|
||||
while (true) {
|
||||
int pos = Random::randomWithIn(1,6);
|
||||
int profile = Random::randomWithIn(0,3);
|
||||
if (stepper.isIdle()) {
|
||||
Syslog::logv(Syslog::Severity::Notice,
|
||||
"Running Stepper to %i by min%i steps with prof=%i a=%.2f w=%.2f",
|
||||
pos, activeState.minJumps, activeState.profile, activeState.accel, activeState.speed);
|
||||
pictoIllumQue.enqueue(std::make_unique<PictoIllumCommand>(0));
|
||||
responseQueue.enqueue(std::make_unique<WatchIndex>(ResponseType::StartMoving, 0));
|
||||
auto &as = activeState;
|
||||
watch.moveTo(pos, profile, as.minJumps, as.accel, as.speed);
|
||||
}
|
||||
// int delay = Random::randomWithIn(20000,100000)/portTICK_PERIOD_MS;
|
||||
int delay = Random::randomWithIn(2000,3000)/portTICK_PERIOD_MS;
|
||||
Syslog::logv(Syslog::Severity::Informational,
|
||||
"ShuffleMode Wait for %i", delay);
|
||||
auto cmd = commandQueue.tryDequeueFor(delay);
|
||||
if (cmd) {
|
||||
if (cmd->type != MoveType::Shuffle) {
|
||||
commandQueue.enqueue(std::move(cmd));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (cmd->type == MoveType::Demo) {
|
||||
ESP_LOGI(TAG, "Running Demo");
|
||||
for (size_t i = ProfileGenerator::Smooth; i < ProfileGenerator::NumProfiles; i++) {
|
||||
@@ -776,14 +855,14 @@ void onPlay(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_Pl
|
||||
ESP_LOGD(TAG, "eventPlay Player: %s Runs: %d Time: %lld", p_PlayerName.data(), p_PlayerIsRunning, p_TimeFrames);
|
||||
|
||||
switch (p_PlayerType) {
|
||||
case SClient::PLAYERTYPE_MAIN:
|
||||
case SClient::PlayerType::PTYPE_MAIN:
|
||||
// p_FrameTimes contains the position inside the server's project, we can use it like a timecode
|
||||
// int intMilliseconds = (int)(((double)p_TimeFrames / (double)m_ServerFramesPerSecond) * 1000);
|
||||
break;
|
||||
case SClient::PLAYERTYPE_CONTINOUS:
|
||||
case SClient::PlayerType::PTYPE_CONTINOUS:
|
||||
// The olayer is playing only single Object sequences sometime during the project
|
||||
break;
|
||||
case SClient::PLAYERTYPE_DISCRETE:
|
||||
case SClient::PlayerType::PTYPE_DISCRETE:
|
||||
// Only discrete values where submitted, e.g the fader position of remote faders.
|
||||
break;
|
||||
}
|
||||
@@ -856,7 +935,7 @@ void SpitClientApp() {
|
||||
|
||||
for (auto &obj : ProvidedObj) {
|
||||
SType *ptrSPITType1Fix = spitClient.createTypeFixed(obj.iD, obj.groupName, obj.name, 0, 0);
|
||||
spitClient.setActionSPITType(ptrSPITType1Fix->getID(), true); // should be executed whenever a SPITObject with this SPITType is played
|
||||
spitClient.setActionType(ptrSPITType1Fix->getID(), true); // should be executed whenever a SPITObject with this SPITType is played
|
||||
}
|
||||
spitClient.clientProjectLoaded();
|
||||
spitClient.startServerAutoDetect();
|
||||
@@ -913,12 +992,11 @@ void app_main(void) {
|
||||
initialize_ethernet();
|
||||
NvsApi::init();
|
||||
static fos::Task lightingTask(LightingTask, "Lights", 0x8000uL);
|
||||
static fos::Task movementTask(MovementTask, "Motor", 0x8000uL);
|
||||
static fos::Task movementTask(MovementTask, "Motor", 0x8000uL, fos::Task::MAX_PRIORITY-4 );
|
||||
|
||||
etherActive.take();
|
||||
fos::Task::delayMs(10000);
|
||||
ESP_LOGI(TAG, "Start net services");
|
||||
// esp_log_level_set("SPIT", esp_log_level_t::ESP_LOG_DEBUG);
|
||||
|
||||
static int ipVersion = AF_INET;
|
||||
static fos::TaskT<int> telnetSocket(telnetSocketTask, ipVersion, "tcpServer", 4096);
|
||||
@@ -942,10 +1020,8 @@ void app_main(void) {
|
||||
while (true) {
|
||||
fos::Task::delayMs(5000);
|
||||
// ToDo send
|
||||
Syslog::logv(Syslog::Severity::Notice, "Health state");
|
||||
// ESP_LOGI(TAG, "Min heap size: %" PRIu32 " / FreeHeap %" PRIu32 "\n",
|
||||
// ESP_LOGI(TAG, "Min heap size: %u / FreeHeap %lu",
|
||||
// heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT),
|
||||
// esp_get_free_heap_size());
|
||||
Syslog::logv(Syslog::Severity::Notice, "Min heap size: %u / FreeHeap %lu",
|
||||
heap_caps_get_minimum_free_size(MALLOC_CAP_DEFAULT),
|
||||
esp_get_free_heap_size());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-16
@@ -40,22 +40,7 @@
|
||||
#include "nvsFunctions.hpp"
|
||||
#include "mqttClient.hpp"
|
||||
#include "watchFace.hpp"
|
||||
|
||||
// #include "esp_chip_info.h"
|
||||
// #include "esp_flash.h"
|
||||
// #include "esp_ota_ops.h"
|
||||
// #include "esp_partition.h"
|
||||
// #include "esp_random.h"
|
||||
// #include "esp_system.h"
|
||||
// #include "fileSystem.hpp"
|
||||
// #include "lwip/apps/netbiosns.h"
|
||||
// #include "mdns.h"
|
||||
// #include "soc/soc_caps.h"
|
||||
// #include "systemFunctions.hpp"
|
||||
// #include <inttypes.h>
|
||||
// #include <sys/param.h>
|
||||
// #include <unistd.h>
|
||||
|
||||
#include "random.hpp"
|
||||
#include "sad_DetectedServer.hpp"
|
||||
#include "spit_object.hpp"
|
||||
#include "spit_player.hpp"
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
.PHONY: start test clean
|
||||
|
||||
start:
|
||||
./startCode
|
||||
|
||||
# testConfig: buildTestOnTarget
|
||||
|
||||
test:
|
||||
cmake -DTgtEnv:STRING=Target -S . -B buildTestOnTarget
|
||||
cmake --build buildTestOnTarget --parallel
|
||||
idf.py -B buildTestOnTarget -p /dev/ttyACM0 flash monitor
|
||||
|
||||
uTest:
|
||||
cmake -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++ -DTgtEnv:STRING=Host -S . -B buildUTest
|
||||
cmake --build buildUTest --parallel
|
||||
ctest --test-dir buildUTest
|
||||
|
||||
clean:
|
||||
rm -rf build buildTestOnTarget
|
||||
@@ -1,12 +1,12 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(UnitTests)
|
||||
include(../../core/test/unitOnHost/test_core.cmake)
|
||||
|
||||
UnitTestSetup()
|
||||
enable_testing()
|
||||
|
||||
project(UnitTests)
|
||||
addSubDirs_ofRoot("${CMAKE_CURRENT_LIST_DIR}/../../components")
|
||||
addSubDirs_ofRoot("${CMAKE_CURRENT_LIST_DIR}/../../core/components")
|
||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../core/test/unitOnHost/hwMock" hwMock)
|
||||
# add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../core/test/unitOnHost/freeRtos" freeRtos)
|
||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../core/test/unitOnHost/netMock" netMock)
|
||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../core/test/unitOnHost/osMock" osMock)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user