refactor: simplifying message queue

This commit is contained in:
2025-04-08 00:35:46 +02:00
parent 407c155c4d
commit d1f582e6ba
20 changed files with 268 additions and 345 deletions
+6 -14
View File
@@ -16,12 +16,11 @@
#include "SPITSocket.h"
#include "esp_log.h"
/**
* clears all unconfirmed SPITObjects not created by this SPIT_Client.
*/
void SPITObject::clearUnconfirmedSPITObjects(SpitRepo<SPITObject>& repo) {
auto& entries = repo.getRepo();
void SPITObject::clearUnconfirmedSPITObjects(SpitRepo<SPITObject> &repo) {
auto &entries = repo.getRepo();
for (auto i = entries.begin(); i != entries.end(); i++) {
SPITObject *ptrSPITObject = i->second.get();
if (ptrSPITObject->getCreatedByClient() == false && ptrSPITObject->getConfirmed() == false) {
@@ -30,8 +29,8 @@ void SPITObject::clearUnconfirmedSPITObjects(SpitRepo<SPITObject>& repo) {
}
}
void SPITObject::eventProjectClosed(SpitRepo<SPITObject>& repo, SpitRepo<SPITObject>& remoteRepo) {
auto& entries = repo.getRepo();
void SPITObject::eventProjectClosed(SpitRepo<SPITObject> &repo, SpitRepo<SPITObject> &remoteRepo) {
auto &entries = repo.getRepo();
for (auto i = entries.begin(); i != entries.end(); i++) {
SPITObject *ptrSPITObject = i->second.get();
if (ptrSPITObject->getCreatedByClient() == true) {
@@ -46,8 +45,8 @@ void SPITObject::eventProjectClosed(SpitRepo<SPITObject>& repo, SpitRepo<SPITObj
* sets confirmed = false for all SPITObjects.
* This should be called when the client has loaded a project.
*/
void SPITObject::setConfirmedFalse(SpitRepo<SPITObject>& repo) {
auto& entries = repo.getRepo();
void SPITObject::setConfirmedFalse(SpitRepo<SPITObject> &repo) {
auto &entries = repo.getRepo();
for (auto i = entries.begin(); i != entries.end(); i++) {
i->second->setConfirmed(false);
}
@@ -215,13 +214,6 @@ void SPITObject::fillMessageOP(SPIT_Message::RemoveSPITObject &p_RemoveSPITObjec
p_RemoveSPITObject.setID(m_ID);
}
void SPITObject::setID(const string &id) {
m_ID = id;
}
void SPITObject::setCreatedByClient(bool p_CreatedByClient) {
m_CreatedByClient = p_CreatedByClient;
}
/**
* This is used by the server and client to tell if the other side has registered the changes.
* @param p_Confirmed
+198 -252
View File
@@ -20,31 +20,27 @@
static const char *TAG = "SPIT";
/**
* Create a new SPIT_client instance, should be done once by the user app.<br>
* Create a new SPIT_client instance, should be done once by the user app.
* @param p_SPITClientInterface the user app should implement the SPIT_ClientInterface.
*/
SPIT_Client::SPIT_Client(string name, string projName, Callbacks calls)
: I_SAD_Client(), mCallbacks(calls), m_Name(name), m_ProjName(projName) {
m_ConnectionStatus = CONNECTION_NONE;
m_ID = createGUID();
m_ComputerName = getClientHostName();
auto ip = SPITSocket::getAdaptersInfo();
mSPITSocket = new SPITSocket(ip);
m_MessageNumber_Send = 1;
m_MessageNumber_Received = -1; // set to -1 because the first received message will set the number (1..255)
}
SPIT_Client::~SPIT_Client() {
stopServerAutoDetect();
disconnectInternal(CONNECTION_NONE);
disconnectInternal(Connection::None);
}
void SPIT_Client::clientProjectClose() {
if (m_ConnectionStatus == CONNECTION_OK) {
if (m_ConnectionStatus == Connection::Ok) {
ESP_LOGI(TAG, " ... tidy up ressources");
auto msg = make_unique<SPIT_Message::CloseSPITProject>(m_ProjName);
if (sendSPITMessage(move(msg)) < 0) {
SPIT_Message::CloseSPITProject closeSPITProject(m_ProjName);
if (sendSPITMessage(closeSPITProject) < 0) {
ESP_LOGD(TAG, "SPIT_Client could not send Client's ReportSPITProject");
}
}
@@ -55,42 +51,42 @@ void SPIT_Client::clientProjectLoaded() {
SPITType::setConfirmedFalse(mSpitTypes);
SPITObject::setConfirmedFalse(mSpitObjects);
if (m_ConnectionStatus == CONNECTION_OK) {
if (m_ConnectionStatus == Connection::Ok) {
// send ReportSPITProject to the server
auto sMReportSPITProject = make_unique<SPIT_Message::ReportSPITProject>(m_ProjName, m_ProjName);
sMReportSPITProject->setFramesPerSecond(0);
if (sendSPITMessage(move(sMReportSPITProject)) < 0) {
SPIT_Message::ReportSPITProject reportSPITProject(m_ProjName, m_ProjName);
reportSPITProject.setFramesPerSecond(0);
if (sendSPITMessage(reportSPITProject) < 0) {
ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send Client's ReportSPITProject");
}
// send RequestProjectTransfer
auto sMRequestProjectTransfer = make_unique<SPIT_Message::RequestProjectTransfer>();
if (sendSPITMessage(move(sMRequestProjectTransfer)) < 0) {
SPIT_Message::RequestProjectTransfer sMRequestProjectTransfer;
if (sendSPITMessage(sMRequestProjectTransfer) < 0) {
ESP_LOGD(TAG, "SPIT_CLient::clientProjectLoaded could not send RequestProjectTransfer");
}
}
}
/**
* Virtual construct - means ActionAssigned for SPITTypes is is not implemented in SPITProtocol.<br>
* This can used to setActionAssigned to all SPITObjects with this SPITType.<br>
* This may be used in the case when the same action should be done for every SPITObject with this SPITType associated.<br>
* This tells the server not what action is done, but it tells the server that there is an action.<br>
* @param p_SPITTypeID the id of the SPITType
* 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 p_ActionAssigned
*/
void SPIT_Client::setActionSPITType(string p_SPITTypeID, bool p_ActionAssigned) {
SPITType *ptrSPITType = mSpitTypes.getEntry(p_SPITTypeID);
if (ptrSPITType == nullptr)
void SPIT_Client::setActionSPITType(string typeId, bool p_ActionAssigned) {
SPITType *spitType = mSpitTypes.getEntry(typeId);
if (spitType == nullptr)
return;
if (ptrSPITType->setActionAssigned(p_ActionAssigned) == true) {
sendSPITTypeInternal(*ptrSPITType);
if (spitType->setActionAssigned(p_ActionAssigned)) {
sendSPITTypeInternal(*spitType);
for (int i = 0; i < mSpitObjects.getEntryCount(); i++) {
SPITObject *ptrSPITObject = mSpitObjects.getEntry(i);
if (ptrSPITObject == nullptr)
continue;
if (ptrSPITObject->getSPITTypeID() == ptrSPITType->getID()) {
if (ptrSPITObject->getSPITTypeID() == spitType->getID()) {
if (ptrSPITObject->setActionAssignedType(p_ActionAssigned) == true) {
sendSPITObjectInternal(ptrSPITObject);
}
@@ -99,61 +95,42 @@ void SPIT_Client::setActionSPITType(string p_SPITTypeID, bool p_ActionAssigned)
}
}
/**
* This should be called if the user wants to associate/remove an action with a SPITObject.
* @param p_SPITObjectID
* @param p_ActionAssigned
*/
void SPIT_Client::setActionSPITObject(string p_SPITObjectID, bool p_ActionAssigned) {
SPITObject *ptrSPITObject;
{
ptrSPITObject = mSpitObjects.getEntry(p_SPITObjectID);
if (ptrSPITObject == nullptr)
return;
if (ptrSPITObject->setActionAssigned(p_ActionAssigned) == true) {
sendSPITObjectInternal(ptrSPITObject);
}
/** This should be called if the user wants to associate/remove an action with a SPITObject. */
void SPIT_Client::setActionSPITObject(string spitObjId, bool actionAssigned) {
SPITObject *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.<br>
/** Starts the autodetection of SPITServers in the local network. If a connection is tried, the autodetection should be stopped before.
* If a SPITServer is detected in the locale network an eventServerDetected occurs.
*/
void SPIT_Client::startServerAutoDetect() {
if (m_DisconnectedByServer == true) {
// Server has previously disconnected -> do not start ServerAutodetect directly
// sleep a little to give the SPITServer time to clean up its stuff -
fos::Task::delayMs(1000);
fos::Task::delayMs(1000); // sleep a little to give the SPITServer time to clean up its stuff
}
SAD_DetectedServer::clearDetectedServers();
if (!sThread) {
sThread = new fos::TaskT<SPIT_Client &>(SPIT_Client::processSocketTask, *this, "spitSock", fos::Task::DefaultStackSize * 2);
}
abortSearch = false;
mAbortSearch = false;
sStartSad.give();
}
/**
* Stops the auto detection of SPIT servers.
*/
/** Stops the auto detection of SPIT servers. */
void SPIT_Client::stopServerAutoDetect() {
abortSearch = true;
mAbortSearch = true;
}
/**
* If a new server was found by the ServerAutoDetect mechanism, this function is called.<br>
* To do so the SAD_Client ServerAutoDetect has to be startet - see SAD_Client::startServerAutoDetect.<br>
* If a server can be reached via several IP addresses, the IP address is selected according to the following preference:<br>
* 1.) If a loopback address is available, it is used.<br>
* 2.) If an IP4 address is available, it is used.<br>
* 3.) In the other cases the IP6 address is used.<br>
* @param p_ID the id of the server (every started server should generate an id)
* @param p_Name the name of the SPIT server
* @param p_ComputerName the Hostname of the cpmputer on which the SPIT server is running
* @param p_IP the selected ip address of the SPIT server
* @param p_Port the port of the SPIT server
* @param p_Addition sometimes server may have additional informations
* If a new server was found by the ServerAutoDetect mechanism, this function is called.
* To do so the SAD_Client ServerAutoDetect has to be startet - see SAD_Client::startServerAutoDetect.
* If a server can be reached via several IP addresses, the IP address is selected according to the following preference:
*/
void SPIT_Client::eventServerDetected(SAD_DetectedServer &server) {
mCallbacks.onServerEvent(ServerEvent::Detect, server);
@@ -171,21 +148,14 @@ void SPIT_Client::eventServerDetected(SAD_DetectedServer &server) {
// Stop auto detection because a suitable server was found
stopServerAutoDetect();
ESP_LOGI(TAG, "connect to %s / %s", server.getIP().data(), server.getPort().data());
// ClientPort = "0" meeans use any port
if (!connect(server.getIP(), server.getPort(), server.getClientIP(), "0")) {
if (!connect(server.getIP(), server.getPort(), server.getClientIP(), "0" /*= any port*/)) {
// connection message could not be sent -> better to restart AutoDetection
startServerAutoDetect();
}
}
/**
* If a SPITServer is not more found, this function is called.
* To do so the SAD_Client ServerAutoDetect has to be startet - see SAD_Client::startServerAutoDetect.<br>
* @param p_ID the id of the server (every started server should generate an id)
* @param p_Name the name of the SPIT server
* @param p_ComputerName the Hostname of the cpmputer on which the SPIT server is running
* @param p_IP the selected ip address of the SPIT server
* @param p_Port the port of the SPIT server
* @param p_Addition sometimes server may have additional informations
* To do so the SAD_Client ServerAutoDetect has to be startet - see SAD_Client::startServerAutoDetect.
*/
void SPIT_Client::eventServerLost(SAD_DetectedServer &server) {
mCallbacks.onServerEvent(ServerEvent::Lost, server);
@@ -196,87 +166,69 @@ void SPIT_Client::eventServerChanged(SAD_DetectedServer &server) {
// tryConnection(p_DetectedServer);
}
// void MyApp::tryConnection(const SAD_DetectedServer& p_DetectedServer) {
// //fetch the infoemations from the p_DetectedServer
// bool boolPossibleConnect;
// bool boolSuccess;
// void MyApp::tryConnection(const SAD_DetectedServer &detected) {
// // fetch the infoemations from the detected
// bool boolSuccess = false;
// bool boolPossibleConnect = checkPossibleConnection(detected);
// boolPossibleConnect = checkPossibleConnection(p_DetectedServer);
// if (boolPossibleConnect == false)
// return;
// if (boolPossibleConnect == false) return;
// // --------------------------------------
// // You have three Options to use the detected server
// // OPTION 1 Use the first server found
// // OPTION 2 Use the first server found that fulfills specific conditions
// // OPTION 3 take a copy of the detected and do connection later
// // SAD_DetectedServer o_DetectedServer = detected; //this will call the copy constructor
// // ---------------------------------------
// // --------------------------------------
// // You have three Options to use the detected server
// // OPTION 1 Use the first server found
// // OPTION 2 Use the first server found that fulfills specific conditions
// // OPTION 3 take a copy of the p_DetectedServer and do connection later
// // SAD_DetectedServer o_DetectedServer = p_DetectedServer; //this will call the copy constructor
// // ---------------------------------------
// // Excample use the first detected LOOPBACK server, means the server runs on the same computer as this client
// // if (detected.getIpIsLoopback() == true) { //omit the if condition if you want to use the first server found
// //Excample use the first detected LOOPBACK server, means the server runs on the same computer as this client
// //if (p_DetectedServer.getIpIsLoopback() == true) { //omit the if condition if you want to use the first server found
// boolSuccess = false;
// //Stop auto detection because a suitable server was found
// stopServerAutoDetect();
// if (m_SPIT_Client != nullptr) {
// m_ServerProjectName = p_DetectedServer.getProjectName();
// m_ServerIP = p_DetectedServer.getIP();
// boolSuccess = false;
// // Stop auto detection because a suitable server was found
// stopServerAutoDetect();
// if (m_SPIT_Client != nullptr) {
// m_ServerProjectName = detected.getProjectName();
// m_ServerIP = detected.getIP();
// #if defined(DEBUGOUTPUT)
// printf("MySPITApp: connect to %s ", p_DetectedServer.getIP().data());
// printf("MySPITApp: connect to %s ", detected.getIP().data());
// #endif
// //Use the m_BoardNumber as login name
// string stringLoginName = "";
// string stringLoginPassword = "";
// boolSuccess = m_SPIT_Client->connect(p_DetectedServer.getIP(), p_DetectedServer.getPort(), p_DetectedServer.getClientIP(), stringLoginName, stringLoginPassword); //ClientPort = "0" meeans use any port
// }
// if (boolSuccess == false) {
// //connection message could not be sent
// //perhaps restart AutoDetection
// startServerAutoDetect();
// }
// else {
// //WAITING FOR CONNECTION ANSWER
// //If the Server is closed in the meantime no answer will return
// //-> connect(..) has started the watchdog
// }
// // Use the m_BoardNumber as login name
// string stringLoginName = "";
// string stringLoginPassword = "";
// boolSuccess = m_SPIT_Client->connect(detected.getIP(), detected.getPort(), detected.getClientIP(), stringLoginName, stringLoginPassword); // ClientPort = "0" meeans use any port
// }
// if (boolSuccess == false) {
// // connection message could not be sent
// // perhaps restart AutoDetection
// startServerAutoDetect();
// } else {
// // WAITING FOR CONNECTION ANSWER
// // If the Server is closed in the meantime no answer will return
// //-> connect(..) has started the watchdog
// }
// // } //Excample
// // } //Excample
// }
void SPIT_Client::fillHeader(SPIT_Message::Header *p_Header) {
if (p_Header == nullptr)
return;
p_Header->setClientID(m_ID);
p_Header->setServerID(m_ServerID);
}
int SPIT_Client::sendSPITMessage(unique_ptr<SPIT_Message::OPPart> spitMessageOPPart) {
if (!spitMessageOPPart) {
return -1;
}
auto &opPart = *spitMessageOPPart.get();
fillHeader(opPart.getHeader());
int SPIT_Client::sendSPITMessage(SPIT_Message::OPPart& opPart) {
if (m_MessageNumber_Send == 255)
m_MessageNumber_Send = 1;
else
m_MessageNumber_Send++;
opPart.setMessageNumber(m_MessageNumber_Send);
opPart.setServerInfoInHeader(m_ID, m_ServerID);
opPart.getHeader()->setMessageNumber(m_MessageNumber_Send);
int opFlag = 0;
int opFlag = opPart.getHeader()->getOPFlag();
try {
auto spitMessage = make_unique<SPIT_Message>(move(spitMessageOPPart));
opFlag = spitMessage->getOPFlag();
auto optMessageBytes = spitMessage->getMessageBytes();
if (optMessageBytes == nullptr) {
auto spitMessage = SPIT_Message::createMessage(opPart);
if (spitMessage.empty()) {
return -1;
}
const auto &messageBytes = *optMessageBytes;
int intResult = mSPITSocket->sendMessage(messageBytes.data(), messageBytes.size());
int intResult = mSPITSocket->sendMessage(spitMessage.data(), spitMessage.size());
if (intResult < 0) {
ESP_LOGD(TAG, "client could not send message OPFlage: %d", opFlag);
}
@@ -286,6 +238,7 @@ int SPIT_Client::sendSPITMessage(unique_ptr<SPIT_Message::OPPart> spitMessageOPP
}
return -1;
}
bool SPIT_Client::startReceiveSPITMessages() {
{
if (!mSPITSocket->getIsBound())
@@ -295,6 +248,7 @@ bool SPIT_Client::startReceiveSPITMessages() {
}
return true;
}
void SPIT_Client::stopReceiveSPITMessages() {
m_StopReceiveSPITMessages = true;
}
@@ -489,7 +443,7 @@ void SPIT_Client::parseSPIT_Message(unique_ptr<SPIT_Message> p_SPITMessage) {
//----- Connection ------
/**
* Tries to connect to a SPITServer.<br>
* Tries to connect to a SPITServer.
* @param p_ServerIP the ip address of the SPIT server
* @param p_ServerPort the port number of the SPIT server
* @param p_ClientIP the local IP address of the client
@@ -499,41 +453,37 @@ void SPIT_Client::parseSPIT_Message(unique_ptr<SPIT_Message> p_SPITMessage) {
* @return false = an error has occured, true = the connect was sent to the server
*/
bool SPIT_Client::connect(string p_ServerIP, string p_ServerPort, string p_ClientIP, string p_ClientPort, string p_LoginName, string p_LoginPassword) {
int intResult;
disconnect();
mSPITSocket->setConnectionParams(p_ServerIP, p_ServerPort, p_ClientIP, p_ClientPort);
intResult = mSPITSocket->bindSocket(p_ClientIP, p_ClientPort);
if (intResult < 0) {
if (mSPITSocket->bindSocket(p_ClientIP, p_ClientPort) < 0) {
m_StopReceiveSPITMessages = true;
return false;
}
auto sMConnect = make_unique<SPIT_Message::Connect>(m_ComputerName, m_Name);
sMConnect->setLoginName(p_LoginName);
sMConnect->setLoginPassword(p_LoginPassword);
sMConnect->setServerIP(p_ServerIP);
SPIT_Message::Connect sMConnect(m_ComputerName, m_Name);
sMConnect.setLoginName(p_LoginName);
sMConnect.setLoginPassword(p_LoginPassword);
sMConnect.setServerIP(p_ServerIP);
if (p_ServerPort.length() <= 0) {
p_ServerPort = "0";
}
int intServerPort;
intServerPort = stoi(p_ServerPort);
sMConnect->setServerPort(intServerPort);
int intServerPort = stoi(p_ServerPort);
sMConnect.setServerPort(intServerPort);
if (startReceiveSPITMessages() == false) {
m_StopReceiveSPITMessages = true;
return false;
}
resetMessageNumberReceived();
int intOldConnectionStatus = m_ConnectionStatus;
Connection intOldConnectionStatus = m_ConnectionStatus;
m_ConnectionStatus = CONNECTION_TRYCONNECTION;
m_ConnectionStatus = Connection::TryConnection;
mCallbacks.onConnectionStatus(m_ServerID, m_ServerComputerName, m_ServerName, m_ServerStepTime,
m_ConnectionStatus, intOldConnectionStatus);
// sleep a little to make sure that the reception of the messages is started
fos::Task::delayMs(500);
intResult = sendSPITMessage(move(sMConnect));
if (intResult < 0) {
m_ConnectionStatus = CONNECTION_NONE;
if (sendSPITMessage(sMConnect) < 0) {
m_ConnectionStatus = Connection::None;
m_StopReceiveSPITMessages = true;
return false;
}
@@ -544,37 +494,38 @@ bool SPIT_Client::connect(string p_ServerIP, string p_ServerPort, string p_Clien
* Terminates the connection to the SPITServer.
*/
void SPIT_Client::disconnect() {
disconnectInternal(CONNECTION_NONE);
disconnectInternal(Connection::None);
}
void SPIT_Client::disconnectInternal(int p_Cause) {
int intOldConnectionStatus = m_ConnectionStatus;
void SPIT_Client::disconnectInternal(Connection p_Cause) {
Connection intOldConnectionStatus = m_ConnectionStatus;
int intResult;
m_ConnectionStatus = p_Cause;
switch (m_ConnectionStatus) {
case CONNECTION_LOST:
case Connection::Lost:
break;
case CONNECTION_NONE: {
auto sMDisconnect = make_unique<SPIT_Message::Disconnect>();
intResult = sendSPITMessage(move(sMDisconnect));
if (intResult < 0) {
// ESP_LOGD(TAG, "Failed to disconnect");
}
case Connection::None: {
SPIT_Message::Disconnect sMDisconnect;
sendSPITMessage(sMDisconnect);
} break;
case CONNECTION_NONESERVER:
case Connection::NoneServer:
break;
default:
break;
}
stopReceiveSPITMessages();
mCallbacks.onConnectionStatus(m_ServerID, m_ServerComputerName, m_ServerName, m_ServerStepTime,
m_ConnectionStatus, intOldConnectionStatus);
if (intOldConnectionStatus != CONNECTION_NONE && intOldConnectionStatus != CONNECTION_NONESERVER) {
ESP_LOGI(TAG, "eventConnectionStatus %d ", m_ConnectionStatus);
if (intOldConnectionStatus != Connection::None && intOldConnectionStatus != Connection::NoneServer) {
ESP_LOGI(TAG, "eventConnectionStatus %d ", (int)m_ConnectionStatus);
switch (m_ConnectionStatus) {
case SPIT_Client::CONNECTION_NONE:
case SPIT_Client::Connection::None:
ESP_LOGD(TAG, "not connected");
break;
case SPIT_Client::CONNECTION_NONESERVER:
case SPIT_Client::Connection::NoneServer:
ESP_LOGD(TAG, "connection terminated by server");
// call eventProjectClosed because this may not be sended by the server,
// when the connection is closed
@@ -584,19 +535,21 @@ void SPIT_Client::disconnectInternal(int p_Cause) {
// _doReconnect = false;
startServerAutoDetect();
break;
case SPIT_Client::CONNECTION_LOST:
case SPIT_Client::Connection::Lost:
ESP_LOGD(TAG, "connection lost");
// Maybe you want to reconnect, see eventServerDetected(...)
// We have lost the connection -> set the flag to true and start the autodetection to reconnect at eventServerDetected(...)
// _doReconnect = true;
startServerAutoDetect();
break;
default:
break;
}
}
}
void SPIT_Client::parseConnectAnswer(SPIT_Message::ConnectAnswer *p_ConnectAnswer) {
int intOldConnectionStatus = m_ConnectionStatus;
Connection intOldConnectionStatus = m_ConnectionStatus;
if (p_ConnectAnswer->getClientID() != m_ID)
return;
@@ -607,10 +560,10 @@ void SPIT_Client::parseConnectAnswer(SPIT_Message::ConnectAnswer *p_ConnectAnswe
m_ServerStepTime = p_ConnectAnswer->getStepTime();
if (p_ConnectAnswer->getConnected() == false) {
disconnectInternal(CONNECTION_NONESERVER);
disconnectInternal(Connection::NoneServer);
} else {
p_ConnectAnswer->getStepTime();
m_ConnectionStatus = CONNECTION_OK;
m_ConnectionStatus = Connection::Ok;
m_DisconnectedByServer = false;
ESP_LOGD(TAG, "connection established");
stopServerAutoDetect(); // normally you should stop the autodetection before you try a connection
@@ -628,7 +581,7 @@ void SPIT_Client::parseConnectAnswer(SPIT_Message::ConnectAnswer *p_ConnectAnswe
* @param p_Disconnect
*/
void SPIT_Client::parseDisconnect(SPIT_Message::Disconnect *p_Disconnect) {
int intCauseDisconnect = CONNECTION_NONESERVER;
Connection intCauseDisconnect = Connection::NoneServer;
/*
function<void()> o_Callable = bind(&SPIT_Client::disconnectInternal, this, intCauseDisconnect);
SPIT_Handler::addCallable(o_Callable);
@@ -639,20 +592,20 @@ void SPIT_Client::parseDisconnect(SPIT_Message::Disconnect *p_Disconnect) {
//----- Watchdog ------
/**
* The SPIT server sends a watchdog message at regular intervals. The client responds immediately with WatchdogAnswer<br>
* Conversely, the client also sends a watchdog message at regular intervals and waits for a WatchdogAnswer message.<br>
* This is used to check if the other side is still present.<br>
* The SPIT server sends a watchdog message at regular intervals. The client responds immediately with WatchdogAnswer
* Conversely, the client also sends a watchdog message at regular intervals and waits for a WatchdogAnswer message.
* This is used to check if the other side is still present.
* @param p_Watchdog
*/
void SPIT_Client::parseWatchdog(SPIT_Message::Watchdog *p_Watchdog) {
// printf("parse Watchdog \n");
auto o_WatchdogAnswer = make_unique<SPIT_Message::WatchdogAnswer>();
sendSPITMessage(move(o_WatchdogAnswer));
SPIT_Message::WatchdogAnswer o_WatchdogAnswer;
sendSPITMessage(o_WatchdogAnswer);
}
/**
* The SPIT server sends a watchdog message at regular intervals. The client responds immediately with WatchdogAnswer<br>
* Conversely, the client also sends a watchdog message at regular intervals and waits for a WatchdogAnswer message.<br>
* This is used to check if the other side is still present.<br>
* The SPIT server sends a watchdog message at regular intervals. The client responds immediately with WatchdogAnswer
* Conversely, the client also sends a watchdog message at regular intervals and waits for a WatchdogAnswer message.
* This is used to check if the other side is still present.
* @param p_Watchdog
*/
void SPIT_Client::parseWatchdogAnswer(SPIT_Message::WatchdogAnswer *p_WatchdogAnswer) {
@@ -661,17 +614,17 @@ void SPIT_Client::parseWatchdogAnswer(SPIT_Message::WatchdogAnswer *p_WatchdogAn
}
void SPIT_Client::sendWatchdog() {
int intResult;
auto sMWatchdog = make_unique<SPIT_Message::Watchdog>();
intResult = sendSPITMessage(move(sMWatchdog));
SPIT_Message::Watchdog sMWatchdog;
intResult = sendSPITMessage(sMWatchdog);
if (intResult < 0) {
ESP_LOGW("WDT", "Failed to send Watchdog msg");
}
}
void SPIT_Client::eventWatchdogLost() {
if (m_ConnectionStatus == CONNECTION_TRYCONNECTION) {
disconnectInternal(CONNECTION_NONESERVER);
if (m_ConnectionStatus == Connection::TryConnection) {
disconnectInternal(Connection::NoneServer);
} else {
disconnectInternal(CONNECTION_LOST);
disconnectInternal(Connection::Lost);
}
}
@@ -690,16 +643,16 @@ void SPIT_Client::parseReportSPITProject(SPIT_Message::ReportSPITProject *p_Repo
SPITObject::setConfirmedFalse(mSpitObjects);
// Send RequestProjectTransfer
auto sMRequestProjectTransfer = make_unique<SPIT_Message::RequestProjectTransfer>();
if (sendSPITMessage(move(sMRequestProjectTransfer)) < 0) {
SPIT_Message::RequestProjectTransfer sMRequestProjectTransfer;
if (sendSPITMessage(sMRequestProjectTransfer) < 0) {
ESP_LOGD(TAG, "SPIT_Client::parseReportSPITProject could not send RequestProjectTransfer\n");
}
// todo Don't send the ReportSPITProject here it should be sended after parseEndProjectTransfer
// Send client's ReportSPITProject
auto sMReportSPITProject = make_unique<SPIT_Message::ReportSPITProject>(m_ProjName, m_ProjName);
sMReportSPITProject->setFramesPerSecond(0);
if (sendSPITMessage(move(sMReportSPITProject)) < 0) {
SPIT_Message::ReportSPITProject reportSPITProject(m_ProjName, m_ProjName);
reportSPITProject.setFramesPerSecond(0);
if (sendSPITMessage(reportSPITProject) < 0) {
ESP_LOGD(TAG, "SPIT_Client::parseReportSPITProject could not send Client's ReportSPITProject");
}
}
@@ -719,9 +672,8 @@ int SPIT_Client::getServerFramesPerSecond() { return m_ServerFramesPerSecond; }
void SPIT_Client::parseRequestProjectTransfer(SPIT_Message::RequestProjectTransfer *p_RequestProjectTransfer) {
// printf("parse RequestProjectTransfer \n");
// StartProjectTransfer
auto sMStartProjectTransfer = make_unique<SPIT_Message::StartProjectTransfer>();
fillHeader(sMStartProjectTransfer->getHeader());
int intResult = sendSPITMessage(move(sMStartProjectTransfer));
SPIT_Message::StartProjectTransfer sMStartProjectTransfer;
int intResult = sendSPITMessage(sMStartProjectTransfer);
if (intResult < 0) {
return;
}
@@ -730,7 +682,7 @@ void SPIT_Client::parseRequestProjectTransfer(SPIT_Message::RequestProjectTransf
int cntT = mSpitTypes.getEntryCount();
for (int i = 0; i < cntT; i++) {
SPITType *ptrSPITType = mSpitTypes.getEntry(i);
if (ptrSPITType == nullptr)
if (!ptrSPITType)
break;
sendSPITTypeInternal(*ptrSPITType);
fos::Task::delayMs(10);
@@ -746,11 +698,8 @@ void SPIT_Client::parseRequestProjectTransfer(SPIT_Message::RequestProjectTransf
}
// EndProjectTransfer
auto sMEndProjectTransfer = make_unique<SPIT_Message::EndProjectTransfer>();
fillHeader(sMEndProjectTransfer->getHeader());
intResult = sendSPITMessage(move(sMEndProjectTransfer));
if (intResult < 0) {
}
SPIT_Message::EndProjectTransfer sMEndProjectTransfer;
sendSPITMessage(sMEndProjectTransfer);
}
/* NEW IMPLEMENTATION
@@ -887,9 +836,9 @@ void SPIT_Client::parseEndProjectTransfer(SPIT_Message::EndProjectTransfer *p_En
mCallbacks.onProjectUpdate(ProjUpdate::EndTransfer, m_ServerProjectID);
// Send SPIT_Message::ReportSPITProject after the m_SPITClientInterface is notfied of EndProjectTransfer
auto sMReportSPITProject = make_unique<SPIT_Message::ReportSPITProject>(m_ProjName, m_ProjName);
sMReportSPITProject->setFramesPerSecond(0);
if (sendSPITMessage(move(sMReportSPITProject)) < 0) {
SPIT_Message::ReportSPITProject reportSPITProject(m_ProjName, m_ProjName);
reportSPITProject.setFramesPerSecond(0);
if (sendSPITMessage(reportSPITProject) < 0) {
ESP_LOGD(TAG, "SPIT_Client::parseReportSPITProject could not send Client's ReportSPITProject");
}
}
@@ -978,19 +927,19 @@ void SPIT_Client::parseRemoveSPITType(SPIT_Message::RemoveSPITType *p_RemoveSPIT
}
/**
* If a client has changed a SPITType, it should send it to the server to transmit the changes.<br>
* 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.<br>
* 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 SPIT_Client::sendSPITTypeInternal(SPITType &p_SPITType) {
auto sMReportSPITType = make_unique<SPIT_Message::ReportSPITType>();
p_SPITType.fillMessageOP(*sMReportSPITType);
return sendSPITMessage(move(sMReportSPITType));
SPIT_Message::ReportSPITType sMReportSPITType;
p_SPITType.fillMessageOP(sMReportSPITType);
return sendSPITMessage(sMReportSPITType);
}
/**
* Change an existing SPIT_Type.<br>
* 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
*/
@@ -1014,11 +963,11 @@ bool SPIT_Client::changeSPITType(SPITType *p_SPITType) {
return true;
}
/**
* If a client has removed a SPITType where id == p_SPITTypeID, it should send it to the server.<br>
* The corresponding SPITType if listet in SPITType will be deleted.<br>
* An eventRemoveSPITType will occur.<br>
* If a connection to a SPITServer is established, the SPITServer may dicard the deletion an an eventSPITType will occur<br>
* -> the SPITType will be listet again.<br>
* 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
*/
@@ -1030,11 +979,11 @@ int SPIT_Client::removeSPITType(string p_SPITTypeID) {
ptrSPITType = mSpitTypes.getEntry(p_SPITTypeID);
if (ptrSPITType == nullptr)
return -1;
auto sMRemoveSPITType = make_unique<SPIT_Message::RemoveSPITType>();
ptrSPITType->fillMessageOP(*sMRemoveSPITType);
SPIT_Message::RemoveSPITType sMRemoveSPITType;
ptrSPITType->fillMessageOP(sMRemoveSPITType);
mCallbacks.onSpitType(ObjectEvent::Deleted, false, *ptrSPITType);
mSpitTypes.removeEntry(*ptrSPITType);
return sendSPITMessage(move(sMRemoveSPITType));
return sendSPITMessage(sMRemoveSPITType);
}
return -1;
}
@@ -1053,7 +1002,6 @@ SPITType *SPIT_Client::createSPITType(string p_ID, string p_GroupName, string p_
ptrSPITType->setCreatedByClient(true);
boolNew = true;
} else {
ptrSPITType->setID(p_ID);
ptrSPITType->setGroupName(p_GroupName);
ptrSPITType->setName(p_Name);
ptrSPITType->setFixed(p_FIxed);
@@ -1173,16 +1121,16 @@ void SPIT_Client::parseRemoveSPITObject(SPIT_Message::RemoveSPITObject *p_Remove
int SPIT_Client::sendSPITObjectInternal(SPITObject *ptrSPITObject) {
if (ptrSPITObject == nullptr)
return -1;
auto sMReportSPITObject = make_unique<SPIT_Message::ReportSPITObject>();
ptrSPITObject->fillMessageOP(*sMReportSPITObject);
SPIT_Message::ReportSPITObject sMReportSPITObject;
ptrSPITObject->fillMessageOP(sMReportSPITObject);
return sendSPITMessage(move(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.<br>
* An eventSPITObject occurs.<br>
* The SPITServer may discard the changes and a second eventSPITObject occurs to correct the changes.<br>
* @param p_SPITObject the pointer to the changed SPITObject.<br>
* 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 p_SPITObject the pointer to the changed SPITObject.
* CAUTION: The SPITObject must already exist.
* @return true = SPITObject is changed, false = not changed, maybe p_SPITObject is NULL or the SPITObject doesn't exists
*/
@@ -1223,11 +1171,11 @@ bool SPIT_Client::changeSPITObject(SPITObject *p_SPITObject) {
}
/**
* 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.<br>
* The corresponding SPITObject if listet in SPITObject will be deleted.<br>
* 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<br>
* -> the SPITObject is listet again.<br>
* If an connection to a SPITServer is established, the SPITServer may discard the deletion and an eventSPITObject occurs
* -> the SPITObject is listet again.
* @param p_SPITObjectID the id of the SPITObject to remove.
* @return 0 = sended to the SPITServer, -1 = not sended to the SPITServer or nos SPITObject with id == p_SPITObjectID exists.
*/
@@ -1237,7 +1185,7 @@ int SPIT_Client::removeSPITObject(string p_SPITObjectID) {
SPITType *ptrSPITType;
SPITObject *ptrSPITObject;
{
auto sMRemoveSPITObject = make_unique<SPIT_Message::RemoveSPITObject>();
SPIT_Message::RemoveSPITObject sMRemoveSPITObject;
ptrSPITObject = mSpitObjects.getEntry(p_SPITObjectID);
if (ptrSPITObject == nullptr)
@@ -1245,10 +1193,10 @@ int SPIT_Client::removeSPITObject(string p_SPITObjectID) {
ptrSPITType = mSpitTypes.getEntry(ptrSPITObject->getSPITTypeID());
if (ptrSPITType == nullptr)
return -1;
ptrSPITObject->fillMessageOP(*sMRemoveSPITObject);
ptrSPITObject->fillMessageOP(sMRemoveSPITObject);
mCallbacks.onSpitObject(ObjectEvent::Deleted, false, *ptrSPITType, *ptrSPITObject);
mSpitObjects.removeEntry(*ptrSPITObject);
return sendSPITMessage(move(sMRemoveSPITObject));
return sendSPITMessage(sMRemoveSPITObject);
}
return -1;
}
@@ -1357,42 +1305,40 @@ void SPIT_Client::parseReportPlayStatus(SPIT_Message::ReportPlayStatus *p_Report
//--------- Remote ----------
/**
* Send a remote control command to the SPITServer.<br>
* Send a remote control command to the SPITServer.
* There may be different command types:
* a) Some don't use value e.g. go to next scene, olay a jingle
* b) Some use values e.g. the main sound fader
* @param p_SPITObjectID the id of the remote SPITObject (this represents the remote control command)
* @param p_Valueppm the value in ppm <br>
* in case a) the value is ignored<br>
* @param p_Valueppm the value in ppm
* in case a) the value is ignored
* in case b) the value is used
* @param p_ValueFlag indicates how the server should use p_Valueppm:<br>
* VALUEFLAG_DIRECT (0x00) The server overwrites its existing value with p_Value<br>
* @param p_ValueFlag indicates how the server should use p_Valueppm:
* VALUEFLAG_DIRECT (0x00) The server overwrites its existing value with p_Value
* VALUEFLAG_INCREASE (0x01) The server increases his existing value by p_Valueppm
* VALUEFLAG_DECREASE (0x01) The server decreases his existing value by p_Valueppm
*/
void SPIT_Client::sendRemoteObject(string p_SPITObjectID, int p_Valueppm, char p_ValueFlag) {
SPITObject *ptrRemoteSPITObject;
{
ptrRemoteSPITObject = mRemoteSpitObjects.getEntry(p_SPITObjectID);
SPITObject *ptrRemoteSPITObject = mRemoteSpitObjects.getEntry(p_SPITObjectID);
if (ptrRemoteSPITObject == nullptr)
return;
auto playSPITStart = make_unique<SPIT_Message::PlaySPITStart>(m_ID, m_ProjName, PLAYERTYPE_DISCRETE);
playSPITStart->setPlayerIsRunning(false);
playSPITStart->setTime(0);
sendSPITMessage(move(playSPITStart));
SPIT_Message::PlaySPITStart playSPITStart(m_ID, m_ProjName, PLAYERTYPE_DISCRETE);
playSPITStart.setPlayerIsRunning(false);
playSPITStart.setTime(0);
sendSPITMessage(playSPITStart);
auto playSPITObject = make_unique<SPIT_Message::PlaySPITObject>();
playSPITObject->setID(ptrRemoteSPITObject->getID());
playSPITObject->setPlayPrePosition(false);
playSPITObject->setPlayerID(m_ID);
playSPITObject->setValue(p_Valueppm);
playSPITObject->setValueFlag(p_ValueFlag);
sendSPITMessage(move(playSPITObject));
SPIT_Message::PlaySPITObject playSPITObject;
playSPITObject.setID(ptrRemoteSPITObject->getID());
playSPITObject.setPlayPrePosition(false);
playSPITObject.setPlayerID(m_ID);
playSPITObject.setValue(p_Valueppm);
playSPITObject.setValueFlag(p_ValueFlag);
sendSPITMessage(playSPITObject);
auto playSPITEnd = make_unique<SPIT_Message::PlaySPITEnd>(m_ID);
sendSPITMessage(move(playSPITEnd));
}
SPIT_Message::PlaySPITEnd playSPITEnd(m_ID);
sendSPITMessage(playSPITEnd);
}
fos::Semaphore SPIT_Client::sStartSad;
@@ -1413,7 +1359,7 @@ void SPIT_Client::processSocketTask(SPIT_Client &instance) {
string stringDatagram = SERVERAUTODETECT_PRECODE + SERVERAUTODETECT_SEPERATOR + SERVERAUTODETECT_TASKID;
int intDatagramLength = stringDatagram.length();
while (searching) {
if (instance.abortSearch)
if (instance.mAbortSearch)
break;
SAD_DetectedServer::resetServerFlags();
@@ -1426,7 +1372,7 @@ void SPIT_Client::processSocketTask(SPIT_Client &instance) {
bool receiving = true;
while (receiving) {
if (instance.abortSearch) {
if (instance.mAbortSearch) {
break;
}
constexpr int SIZE = 512;
@@ -1474,8 +1420,8 @@ void SPIT_Client::processSocketTask(SPIT_Client &instance) {
fos::Task::delayMs(100);
SAD_DetectedServer::evaluateDetectedServers(instance);
instance.abortSearch = false;
// if(instance.m_ConnectionStatus == CONNECTION_OK) break;
instance.mAbortSearch = false;
// if(instance.m_ConnectionStatus == Connection::Ok) break;
fos::Task::delayMs(1000);
}
instance.mSPITSocket->setBroadcast(false);
+16 -33
View File
@@ -28,8 +28,7 @@ SPIT_Message::SPIT_Message(std::vector<char> message) {
return;
}
m_MessageBytes = message;
if (!parse()) {
if (!parse(message)) {
ESP_LOGE(TAG, "Failed ot parse message");
return;
}
@@ -37,10 +36,10 @@ SPIT_Message::SPIT_Message(std::vector<char> message) {
// Receive
bool SPIT_Message::parse() {
bool SPIT_Message::parse(std::vector<char> message) {
// parse Header
auto header = make_unique<Header>();
if (!header->parse(m_MessageBytes)) {
if (!header->parse(message)) {
return false;
}
@@ -109,43 +108,27 @@ bool SPIT_Message::parse() {
return false;
}
return m_OPPart->parse(m_MessageBytes);
return m_OPPart->parse(message);
}
//---------- Send ----------
SPIT_Message::SPIT_Message(unique_ptr<OPPart> p_OPPart) {
if (!p_OPPart) {
return;
std::vector<char> SPIT_Message::createMessage(OPPart &p_OPPart) {
if (!p_OPPart.getHeader()) {
return {};
}
m_OPPart = move(p_OPPart);
if (!m_OPPart->getHeader()) {
m_OPPart = nullptr;
return;
}
}
bool SPIT_Message::fillBytes() {
if (m_OPPart == nullptr)
return false;
try {
if (m_MessageBytes.empty()) {
int totalSize = Header::BYTESLENGTH + m_OPPart->getBytesCount();
m_MessageBytes = std::vector<char>(totalSize);
}
return m_OPPart->fillBytes(m_MessageBytes);
int totalSize = Header::BYTESLENGTH + p_OPPart.getBytesCount();
std::vector<char> msgByts(totalSize);
p_OPPart.fillBytes(msgByts);
return msgByts;
} catch (...) {
ESP_LOGE(TAG, "Failed to allocate memory");
return false;
}
return true;
}
const std::vector<char> *SPIT_Message::getMessageBytes() {
if (m_OPPart == nullptr)
return nullptr;
if (fillBytes() == false)
return nullptr;
return &m_MessageBytes;
return {};
}
//----------- Header -----------
SPIT_Message::Header::Header(const Header &orig) {
m_SPITID = &SPITID[0];
@@ -385,8 +368,8 @@ bool SPIT_Message::Disconnect::fillBytes(std::vector<char> &message) {
if (m_Header->fillBytes(message) == false)
return false;
try {
m_ParseOffset = Header::BYTESLENGTH;
m_ParseOffset += setInt(m_BytesCount, message, m_ParseOffset);
m_ParseOffset = Header::BYTESLENGTH;
m_ParseOffset += setInt(m_BytesCount, message, m_ParseOffset);
} catch (...) {
ESP_LOGE(TAG, "failed to create Disconnect message");
return false;