feature: Project builds with integrated SPIT client (however with some exclusions)

This commit is contained in:
2025-02-15 22:18:06 +01:00
parent 500641a6e2
commit 4e94d7ad78
15 changed files with 257 additions and 910 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
idf_component_register( idf_component_register(
SRC_DIRS "src" SRC_DIRS "src" "src/esp"
INCLUDE_DIRS "include" INCLUDE_DIRS "include"
REQUIRES esp_system esp_netif freeRtosApi
) )
+3 -8
View File
@@ -20,9 +20,6 @@
using namespace std; using namespace std;
int main();
class MyApp : SPIT_ClientInterface { class MyApp : SPIT_ClientInterface {
public: public:
MyApp(); MyApp();
@@ -30,10 +27,6 @@ public:
//Client's infos is set by the client //Client's infos is set by the client
static string s_ClientName; static string s_ClientName;
static string s_ClientProjectID;
static string s_ClientProjectName;
static int s_ClientDefaultFramesPerSecond;
void loadClientProject(); void loadClientProject();
private: private:
@@ -53,6 +46,8 @@ private:
string m_ServerProjectID; string m_ServerProjectID;
string m_ServerProjectName; string m_ServerProjectName;
int m_ServerFramesPerSecond; //set when the server reports his project, see eventProjectReport int m_ServerFramesPerSecond; //set when the server reports his project, see eventProjectReport
//liveSHOWsoftware will use 44100 frames per second as time resolution
//All times are given in frames,
//Reconnect to the server when connection is lost see eventConnectionStatus and eventServerDetected //Reconnect to the server when connection is lost see eventConnectionStatus and eventServerDetected
bool m_FlagReconnect; //true = on eventServerDetected connect to the server identified by m_ServerID bool m_FlagReconnect; //true = on eventServerDetected connect to the server identified by m_ServerID
@@ -63,7 +58,7 @@ private:
public: public:
//---------- SPIT_ClientInterface ------------- //---------- SPIT_ClientInterface -------------
string getClientProjectID(); //should return the client's project id, maybe the same as project name string getClientProjectID(); //should return the client's project id, maybe the same as project name
string getClientProjectName(); //should return the client's project name string getClientProjectName();
//----- ServerAutoDetection ----- //----- ServerAutoDetection -----
void startServerAutoDetect(); //starts the autodetection of SPITServers in the local network area (see eventServerDetected) void startServerAutoDetect(); //starts the autodetection of SPITServers in the local network area (see eventServerDetected)
-8
View File
@@ -15,12 +15,7 @@
#define SPIT_CLIENT_H #define SPIT_CLIENT_H
#include "_SPITMACROS.h" #include "_SPITMACROS.h"
#if defined OS_WINDOWS
#include "WindowsSocket.h"
#endif
#if defined OS_MAC || defined OS_LINUX
#include "UnixSocket.h" #include "UnixSocket.h"
#endif
#include "SPITSocket.h" #include "SPITSocket.h"
#include "SAD_Client.h" #include "SAD_Client.h"
@@ -35,9 +30,6 @@
#include "SPITPlayer.h" #include "SPITPlayer.h"
#include <chrono> #include <chrono>
//#include <thread>
using namespace std; using namespace std;
//static char nullChar[] = "\0"; //static char nullChar[] = "\0";
-4
View File
@@ -15,9 +15,6 @@
#define UNIXSOCKET_H #define UNIXSOCKET_H
#include "_SPITMACROS.h" #include "_SPITMACROS.h"
#if defined(OS_MAC) || defined(OS_LINUX)
#include <ifaddrs.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h> #include <netdb.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@@ -50,7 +47,6 @@ public:
int sendMessageTo(int p_InetFamily, string p_ServerIP, string p_ServerPort, const char* p_MessageBytes, int p_MessageLength); int sendMessageTo(int p_InetFamily, string p_ServerIP, string p_ServerPort, const char* p_MessageBytes, int p_MessageLength);
int receiveMessage(int p_InetFamily, char* p_Buffer, int p_BufferLength, string* p_ServerIP); int receiveMessage(int p_InetFamily, char* p_Buffer, int p_BufferLength, string* p_ServerIP);
}; };
#endif
#endif /* UNIXSOCKET_H */ #endif /* UNIXSOCKET_H */
-53
View File
@@ -1,53 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: WindowsSocket.h
* Author: Hagi
*
* Created on 11. April 2019, 08:36
*/
#ifndef WINDOWSSOCKET_H
#define WINDOWSSOCKET_H
#include "_SPITMACROS.h"
#if defined(OS_WINDOWS)
#include "WindowsSocket.h"
#include <WinSock2.h>
#include <iphlpapi.h>
#include <ws2tcpip.h>
#include <thread>
#include "SPITSocket.h"
using namespace std;
class WindowsSocket : public SPITSocket{
public:
WindowsSocket();
virtual ~WindowsSocket();
private:
SOCKET m_UDPSocketIP4;
SOCKET m_UDPSocketIP6;
public:
void getAdaptersInfo();
string getBroadcastIP4(IPAddress* p_IPAdress);
int setBroadcast(bool p_Broadcast);
static int init();
static int cleanUp();
bool createSocket_UDP();
int bindSocket(string p_ClientIP, string p_ClientPort);
int sendMessageTo(int p_InetFamily, string p_ServerIP, string p_ServerPort, const char* p_MessageBytes, int p_MessageLength);
int receiveMessage(int p_InetFamily, char* p_Buffer, int p_BufferLength, string* p_ServerIP);
};
#endif
#endif /* WINDOWSSOCKET_H */
+2 -41
View File
@@ -1,36 +1,7 @@
/* #pragma once
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: _SPITMACROS.h
* Author: Hagi
*
* Created on 13. April 2019, 13:37
*/
#ifndef _SPITMACROS_H
#define _SPITMACROS_H
//To compile for a specific operating system, you must change the precompiler comments.
//In windows Ws2_32.lib Iphlpapi.lib (in gcc: -liphlpapi -lole32) should be added to the linker options
#ifndef OS_WINDOWS
// #define OS_WINDOWS
// #include <WinSock2.h> //include this here, because it must be included before string.h .. is included
#endif
#ifndef OS_MAC
// #define OS_MAC
// #include <unistd.h>
// #include<uuid/uuid.h>
#endif
#ifndef OS_LINUX
#define OS_LINUX
#include <unistd.h> #include <unistd.h>
#include<uuid/uuid.h> // #include <uuid/uuid.h>
#endif
// To output debug information (printf calls in the code) // To output debug information (printf calls in the code)
// you must set or comment out this precompiler definition // you must set or comment out this precompiler definition
@@ -38,20 +9,10 @@
#define DEBUGOUTPUT #define DEBUGOUTPUT
#endif #endif
#include <string> #include <string>
using namespace std; using namespace std;
//--------- OS specific functions ---------
/** Returns an guid */ /** Returns an guid */
string createGUID(); string createGUID();
/** Returns the name of the client's host computer*/ /** Returns the name of the client's host computer*/
string getClientHostName(); string getClientHostName();
#endif /* _SPITMACROS_H */
+76 -271
View File
@@ -1,51 +1,13 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: MySPITApp.cpp
* Author: Hagi
*
* Created on 17. April 2019, 06:24 pm
* Changed on 01. May 2020, 12:00 am
*
* Description:
* A SPITClient defines actions (functions) and connects to a SPITServer.
* The actions are assigned to SPITTypes.
* The client may create its own SPITTypes, which are sended to the server or receives SPITTypes from the server.
* Each SPIType can trigger exactly one action.
* The server may use this SPITTypes to create and play SPITObjects, he can create several SPITObjects from one SPITType.
* Each SPITObject is assigned exactly one SPITType.
* When the server plays a SPITObject, an event function (eventPlayObject) is called in the client.
* The client can then trigger the action for the assigned SPITType.
* --------------------------------------------------------------------------------------------------
* all event.. functions are executed by a single SPIT_Handler thread.
* -> The event functions are called singlethreaded one after the other.
* --------------------------------------------------------------------------------------------------
*/
#include "MyApp.h" #include "MyApp.h"
#include "Task.hpp"
#include "esp_log.h"
string MyApp::s_ClientName = "MySPITApp_Client"; //Name of this Client string MyApp::s_ClientName = "MySPITApp_Client"; //Name of this Client
string MyApp::s_ClientProjectName = "MySPITAppProject"; //Name of the client'loaded project const char * TAG = "SPIT";
string MyApp::s_ClientProjectID = s_ClientProjectName; //ID of the client's project - maybe the same as the name or a specific id
#if defined(OS_WINDOWS) void SpitClientApp() {
//Win32 Main Function - application entry auto ptrMyApp = std::make_unique<MyApp>();
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, INT nCmdShow) {
return main();
}
#endif
//UNIX and Win64 Main function - application entry
int main() {
MyApp* ptrMyApp;
//Create a MyApp instance
ptrMyApp = new MyApp();
//load a client project //load a client project
//the client project may belong to a server's project or may be independend of server's projects //the client project may belong to a server's project or may be independend of server's projects
@@ -61,41 +23,19 @@ int main() {
//autodetection of SPITServers ends automaticallay when this SPITClient is connected to a SPITServer //autodetection of SPITServers ends automaticallay when this SPITClient is connected to a SPITServer
ptrMyApp->startServerAutoDetect(); ptrMyApp->startServerAutoDetect();
//This application is multthreaded, in the background all is done by several threads while (true) {
//all events are delegated to SPIT_Handler fos::Task::delayMs(10000);
//-> the eventxxx functions are called by the one and only SPIT_Handler's thread s_HandlerThread
//-> the eventxxx functions are called singlethreaded
//Normally MyApp will have a user interface to decide when the app has to be closed.
//Actual we have no user interface -> sleep a while
//We can put the actual thread to sleep, because the events are executed by the SPIT_Handler-Thread s_HandlerThread.
printf("---THE APPLICATION RUNS FOR 60 SECONDS AND STOPS AUTOMATICALLY---\n\n");
this_thread::sleep_for(chrono::milliseconds(30000));
ptrMyApp->testLiveShowRemote(); //This is an excample how to remote control the liveSHOWsoftware ptrMyApp->testLiveShowRemote(); //This is an excample how to remote control the liveSHOWsoftware
this_thread::sleep_for(chrono::milliseconds(30000)); }
//perhaps you should save the client project
//close MyApp instance
delete ptrMyApp;
return 0;
} }
MyApp::MyApp() { MyApp::MyApp() {
//create a new SPIT_Client instance
//the SPIT_Client will do the main work for you (receiving/sending SPIT_Messages ....)
m_SPIT_Client = new SPIT_Client(this); m_SPIT_Client = new SPIT_Client(this);
//You need to give your application a descriptive name //You need to give your application a descriptive name
m_SPIT_Client->setName(s_ClientName); m_SPIT_Client->setName(s_ClientName);
//The following members are set in loadClientProject function. //The following members are set in loadClientProject function.
m_ClientProjectName = ""; m_ClientProjectID = "";
m_ClientProjectID = ""; //id can be the same as the project name
//The following members are set in the eventConnectionStatus //The following members are set in the eventConnectionStatus
m_ServerID = ""; m_ServerID = "";
@@ -107,18 +47,11 @@ MyApp::MyApp() {
m_ServerProjectID = ""; m_ServerProjectID = "";
m_ServerProjectName = ""; m_ServerProjectName = "";
m_ServerFramesPerSecond = 44100; //is reset in eventProjectReport. m_ServerFramesPerSecond = 44100; //is reset in eventProjectReport.
//perhaps you may save the value from the last connection and set it here
//liveSHOWsoftware will use 44100 frames per second as time resolution
//All times are given in frames,
//with this parameter you can convert the times into milliseconds/seconds ...
//Used to decide if a reconnection is tried after the connection is lost //Used to decide if a reconnection is tried after the connection is lost
//see eventServerDetected and eventConnectionStatus
m_FlagReconnect = false; m_FlagReconnect = false;
} }
MyApp::~MyApp() { MyApp::~MyApp() {
//To close the connection and all other stuff delete the SPIT_Client instance //To close the connection and all other stuff delete the SPIT_Client instance
if (m_SPIT_Client != NULL) { if (m_SPIT_Client != NULL) {
@@ -128,71 +61,40 @@ MyApp::~MyApp() {
//Following functions fullfill the SPIT_ClientInterface //Following functions fullfill the SPIT_ClientInterface
//They are needed when the server sends his project, see eventProjectReport //They are needed when the server sends his project, see eventProjectReport
//and they should be set in loadClientProject
string MyApp::getClientProjectID() { string MyApp::getClientProjectID() {
return m_ClientProjectID; return m_ClientProjectID;
} }
//Following functions fullfill the SPIT_ClientInterface
//They are needed when the server sends his project, see eventProjectReport
string MyApp::getClientProjectName() { string MyApp::getClientProjectName() {
return m_ClientProjectName; return m_ClientProjectName;
} }
void MyApp::loadClientProject() { void MyApp::loadClientProject() {
//----- close the actual client project ----- //----- close current client project -----
//inform the SPIT_Client that the actual project will close
//If there is actual no connection to the server nothing happens
if (m_SPIT_Client != NULL) { if (m_SPIT_Client != NULL) {
m_SPIT_Client->clientProjectClose(); m_SPIT_Client->clientProjectClose();
} }
//close the project
//----- load new client project -----
// Add your loading code here
//If your application is a small one using only a few fixed actions
//you may keep the things simple and code all loading here
m_ClientProjectID = s_ClientProjectID; //maybe the same as s_ClientProjectName
m_ClientProjectName = s_ClientProjectName;
//Create SPITTypes for all functions of this client
//--- Excample ---
//the client owns two fixed functionality named "Action1" and "Action2"
if (m_SPIT_Client != NULL) { if (m_SPIT_Client != NULL) {
//FIXED SPITTYPES
//Create SPITTypes for all discrete and unchangable functions of this client. Fixed means the server can't change or remove the SPITType. //Create SPITTypes for all discrete and unchangable functions of this client. Fixed means the server can't change or remove the SPITType.
//-> Create a SPITTypes according to the following patterns
//Excample "Action1"
SPITType* ptrSPITType1Fix; SPITType* ptrSPITType1Fix;
ptrSPITType1Fix = m_SPIT_Client->createSPITTypeFixed("MySPITAPP_Action1ID", "MyActionGroupName", "FixedAction1", 0, 0); ptrSPITType1Fix = m_SPIT_Client->createSPITTypeFixed("MySPITAPP_Action1ID", "ActionGroupName", "Action1Name", 0, 0);
//When an action exist which shpuld be done whenever a SPITObject with this SPITType is played, <br>
SPITType* ptrSPITType2Fix;
ptrSPITType2Fix = m_SPIT_Client->createSPITTypeFixed("MySPITAPP_Action2ID", "ActionGroupName", "Action2Name", 0, 0);
//When an action exist which should be done whenever a SPITObject with this SPITType is played, <br>
//then you should 'setAssignedActionType' to true //then you should 'setAssignedActionType' to true
m_SPIT_Client->setActionSPITType(ptrSPITType1Fix->getID(), true); m_SPIT_Client->setActionSPITType(ptrSPITType1Fix->getID(), true);
//Excample "Action2"
SPITType* ptrSPITType2Fix;
ptrSPITType2Fix = m_SPIT_Client->createSPITTypeFixed("MySPITAPP_Action2ID", "MyActionGroupName", "FixedAction2", 0, 0);
//When an action exist which shpuld be done whenever a SPITObject with this SPITType is played, <br>
//then you should 'setAssignedActionType' to true
m_SPIT_Client->setActionSPITType(ptrSPITType2Fix->getID(), true); m_SPIT_Client->setActionSPITType(ptrSPITType2Fix->getID(), true);
//later in the eventPlayObject you can react with your action code for "Action1" and "Action2" //later in the eventPlayObject you can react with your action code for "Action1" and "Action2"
//CHANGABLE SPITYPES
//Create SPITTypes which are changable or temporarly, the server may change or delete them.
ptrSPITType2Fix = m_SPIT_Client->createSPITType("MySPITAPP_ActionTemp1ID", "MyActionGroupName", "TempAction1", 0, 0, false, true);
//When an action exist which shpuld be done whenever a SPITObject with this SPITType is played, <br>
//then you should 'setAssignedActionType' to true
m_SPIT_Client->setActionSPITType(ptrSPITType2Fix->getID(), true);
} }
//--- End Excample ---
//----- inform the SPIT_Client that a new project is loaded -----
if (m_SPIT_Client != NULL) { if (m_SPIT_Client != NULL) {
m_SPIT_Client->clientProjectLoaded(); m_SPIT_Client->clientProjectLoaded();
} }
} }
//----------------------------------------- //-----------------------------------------
@@ -223,33 +125,24 @@ void MyApp::stopServerAutoDetect() {
*/ */
void MyApp::eventServerDetected(const SAD_DetectedServer& p_DetectedServer) { void MyApp::eventServerDetected(const SAD_DetectedServer& p_DetectedServer) {
//fetch the infoemations from the p_DetectedServer //fetch the infoemations from the p_DetectedServer
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "SERVER DETECTED");
printf("mySPITApp\n"); ESP_LOGD(TAG, " Name: %s", p_DetectedServer.getName().data());
printf("-----> SERVER DETECTED\n"); ESP_LOGD(TAG, " ID: %s", p_DetectedServer.getID().data());
printf(" Name: %s\n", p_DetectedServer.getName().data()); ESP_LOGD(TAG, " Computer: %s", p_DetectedServer.getComputerName().data());
printf(" ID: %s\n", p_DetectedServer.getID().data()); ESP_LOGD(TAG, " IP: %s", p_DetectedServer.getIP().data());
printf(" Computer: %s\n", p_DetectedServer.getComputerName().data()); ESP_LOGD(TAG, " Port: %s", p_DetectedServer.getPort().data());
printf(" IP: %s\n", p_DetectedServer.getIP().data()); ESP_LOGD(TAG, " Addition: %s", p_DetectedServer.getAdditions().data());
printf(" Port: %s\n", p_DetectedServer.getPort().data()); ESP_LOGD(TAG, " ClientIP: %s", p_DetectedServer.getClientIP().data());
printf(" Addition: %s\n", p_DetectedServer.getAdditions().data());
printf(" ClientIP: %s\n", p_DetectedServer.getClientIP().data());
printf("\n");
#endif
bool boolSuccess;
bool boolSuccess = false;
//---------- RECONNECTION ---------- //---------- RECONNECTION ----------
//If a connection has been established and the connection is lost -> reconnect //If a connection has been established and the connection is lost -> reconnect
boolSuccess = false;
if (m_FlagReconnect == true) { if (m_FlagReconnect == true) {
//check if the server is the same as prior connected //check if the server is the same as prior connected
if (m_ServerID == p_DetectedServer.getID()) { if (m_ServerID == p_DetectedServer.getID()) {
//reconnect
if (m_SPIT_Client != NULL) { if (m_SPIT_Client != NULL) {
stopServerAutoDetect(); stopServerAutoDetect();
#if defined(DEBUGOUTPUT) ESP_LOGI(TAG,"reconnect to %s", p_DetectedServer.getIP().data());
printf("MySPITApp: reconnect to %s ", p_DetectedServer.getIP().data());
#endif
boolSuccess = m_SPIT_Client->connect(p_DetectedServer.getIP(), p_DetectedServer.getPort(), p_DetectedServer.getClientIP(), "0"); //ClientPort = "0" meeans use any port boolSuccess = m_SPIT_Client->connect(p_DetectedServer.getIP(), p_DetectedServer.getPort(), p_DetectedServer.getClientIP(), "0"); //ClientPort = "0" meeans use any port
if (boolSuccess == true) { if (boolSuccess == true) {
return; return;
@@ -258,33 +151,21 @@ void MyApp::eventServerDetected(const SAD_DetectedServer& p_DetectedServer) {
} }
} }
// --------------------------------------
// 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 //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 if (p_DetectedServer.getIpIsLoopback() == true) { //omit the if condition if you want to use the first server found
return;
}
boolSuccess = false; boolSuccess = false;
//Stop auto detection because a suitable server was found //Stop auto detection because a suitable server was found
stopServerAutoDetect(); stopServerAutoDetect();
if (m_SPIT_Client != NULL) { if (m_SPIT_Client != NULL) {
#if defined(DEBUGOUTPUT) ESP_LOGI(TAG,"connect to %s", p_DetectedServer.getIP().data());
printf("MySPITApp: connect to %s ", p_DetectedServer.getIP().data());
#endif
boolSuccess = m_SPIT_Client->connect(p_DetectedServer.getIP(), p_DetectedServer.getPort(), p_DetectedServer.getClientIP(), "0"); //ClientPort = "0" meeans use any port boolSuccess = m_SPIT_Client->connect(p_DetectedServer.getIP(), p_DetectedServer.getPort(), p_DetectedServer.getClientIP(), "0"); //ClientPort = "0" meeans use any port
} }
if (boolSuccess == false) { if (boolSuccess == false) {
//connection message could not be sent //connection message could not be sent -> better to restart AutoDetection
//perhaps restart AutoDetection
startServerAutoDetect(); startServerAutoDetect();
} }
// } //Excample
} }
@@ -300,12 +181,7 @@ void MyApp::eventServerDetected(const SAD_DetectedServer& p_DetectedServer) {
* After this function call the copy of the SAD_DetectedServer will be deleted!!<br> * After this function call the copy of the SAD_DetectedServer will be deleted!!<br>
*/ */
void MyApp::eventServerLost(const SAD_DetectedServer& p_DetectedServer) { void MyApp::eventServerLost(const SAD_DetectedServer& p_DetectedServer) {
#if defined(DEBUGOUTPUT) ESP_LOGW(TAG, "Server lost Name: %s IP: %s", p_DetectedServer.getName().data(), p_DetectedServer.getIP().data());
printf("\n");
printf("-----> SERVER LOST\n");
printf("Name: %s IP: %s\n", p_DetectedServer.getName().data(), p_DetectedServer.getIP().data());
printf("\n");
#endif
} }
@@ -313,19 +189,13 @@ void MyApp::eventServerLost(const SAD_DetectedServer& p_DetectedServer) {
//---------- Connecting event ---------- //---------- Connecting event ----------
void MyApp::eventConnectionStatus(string p_ServerID, string p_ServerComputerName, string p_ServerName, int p_ServerStepTime, int p_ConnectionStatus, int p_OldConnectionStatus) { void MyApp::eventConnectionStatus(string p_ServerID, string p_ServerComputerName, string p_ServerName, int p_ServerStepTime, int p_ConnectionStatus, int p_OldConnectionStatus) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventConnectionStatus %d ", p_ConnectionStatus);
printf("MySPITApp: eventConnectionStatus %d ", p_ConnectionStatus);
#endif
switch(p_ConnectionStatus) { switch(p_ConnectionStatus) {
case SPIT_Client::CONNECTION_NONE: case SPIT_Client::CONNECTION_NONE:
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "not connected");
printf(" not connected\n");
#endif
break; break;
case SPIT_Client::CONNECTION_NONESERVER: case SPIT_Client::CONNECTION_NONESERVER:
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "connection terminated by server");
printf(" connection terminated by server\n");
#endif
//call eventProjectClosed because this may not be sended by the server, //call eventProjectClosed because this may not be sended by the server,
//when the connstion is closed //when the connstion is closed
eventProjectClosed(m_ServerProjectID); eventProjectClosed(m_ServerProjectID);
@@ -335,9 +205,7 @@ void MyApp::eventConnectionStatus(string p_ServerID, string p_ServerComputerName
startServerAutoDetect(); startServerAutoDetect();
break; break;
case SPIT_Client::CONNECTION_OK: case SPIT_Client::CONNECTION_OK:
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "connection established");
printf(" connection established\n");
#endif
stopServerAutoDetect(); //normally you should stop the autodetection before you try a connection stopServerAutoDetect(); //normally you should stop the autodetection before you try a connection
//This is redundand //This is redundand
m_ServerID = p_ServerID; m_ServerID = p_ServerID;
@@ -350,9 +218,7 @@ void MyApp::eventConnectionStatus(string p_ServerID, string p_ServerComputerName
m_FlagReconnect = false; m_FlagReconnect = false;
break; break;
case SPIT_Client::CONNECTION_LOST: case SPIT_Client::CONNECTION_LOST:
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "connection lost");
printf(" connection lost\n");
#endif
//Maybe you want to reconnect, see eventServerDetected(...) //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(...) //We have lost the connection -> set the flag to true and start the autodetection to reconnect at eventServerDetected(...)
m_FlagReconnect = true; m_FlagReconnect = true;
@@ -376,10 +242,7 @@ void MyApp::eventConnectionStatus(string p_ServerID, string p_ServerComputerName
* @param p_FramesPerSeoond All times in SPIT are given in frames. FramesPerSecond can be used to convert frames to seconds.... * @param p_FramesPerSeoond All times in SPIT are given in frames. FramesPerSecond can be used to convert frames to seconds....
*/ */
void MyApp::eventProjectReport(string p_ProjectID, string p_ProjectName, int p_FramesPerSeoond) { void MyApp::eventProjectReport(string p_ProjectID, string p_ProjectName, int p_FramesPerSeoond) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventProjectReport ID: %s Name: %s FramesPerSecond: %d", p_ProjectID.data(), p_ProjectName.data(), p_FramesPerSeoond);
printf("\n");
printf("MySPITApp: eventProjectReport ID: %s Name: %s FramesPerSecond: %d\n", p_ProjectID.data(), p_ProjectName.data(), p_FramesPerSeoond);
#endif
m_ServerProjectID = p_ProjectID; m_ServerProjectID = p_ProjectID;
m_ServerProjectName = p_ProjectName; m_ServerProjectName = p_ProjectName;
m_ServerFramesPerSecond = p_FramesPerSeoond; m_ServerFramesPerSecond = p_FramesPerSeoond;
@@ -388,18 +251,15 @@ void MyApp::eventProjectReport(string p_ProjectID, string p_ProjectName, int p_F
m_ServerFramesPerSecond = p_FramesPerSeoond; m_ServerFramesPerSecond = p_FramesPerSeoond;
//When the this client's project depends on the server's project -> load some specific informations here //When the this client's project depends on the server's project -> load some specific informations here
} }
/** /**
* Called when the server closes his project.<br> * Called when the server closes his project.<br>
* @param p_ProjectID the id of the project<br> * @param p_ProjectID the id of the project<br>
* The server loads only one project at time-> the ID is not actually necessary * The server loads only one project at time-> the ID is not actually necessary
*/ */
void MyApp::eventProjectClosed(string p_ProjectID) { void MyApp::eventProjectClosed(string p_ProjectID) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventProjectClosed ID: %s", p_ProjectID.data());
printf("MySPITApp: eventProjectClosed ID: %s\n", p_ProjectID.data());
printf("\n");
#endif
//If we don't save SPITServer's project specific information //If we don't save SPITServer's project specific information
//perhaps close all SPITObjects and RemoteSPITObjects to avoid conflicts, when the SPITServer loads a new project //perhaps close all SPITObjects and RemoteSPITObjects to avoid conflicts, when the SPITServer loads a new project
//SPITObject::clearSPITObjects(); //SPITObject::clearSPITObjects();
@@ -413,23 +273,17 @@ void MyApp::eventProjectClosed(string p_ProjectID) {
* At the end eventEndProjectTransfer is called. * At the end eventEndProjectTransfer is called.
*/ */
void MyApp::eventStartProjectTransfer() { void MyApp::eventStartProjectTransfer() {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventStartProjectTransfer");
printf("MySPITApp: eventStartProjectTransfer\n");
#endif
} }
/** /**
* The transfer of the server's SPITTypes and SPITObjects is finished.<br> * The transfer of the server's SPITTypes and SPITObjects is finished.<br>
* AFter this all eventSPITType and eventSPITObject means that new types , objects are created or changed. * AFter this all eventSPITType and eventSPITObject means that new types , objects are created or changed.
*/ */
void MyApp::eventEndProjectTransfer() { void MyApp::eventEndProjectTransfer() {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventEndProjectTransfer");
printf("MySPITApp: eventEndProjectTransfer\n");
#endif
} }
//---------------------------------------------------- //----------------------------------------------------
//--------- SPITType events ---------- //--------- SPITType events ----------
@@ -475,19 +329,13 @@ void MyApp::eventSPITType(bool p_New, const SPITType& p_SPITType) {
//fetch information of the SPITType //fetch information of the SPITType
if (p_New) { if (p_New) {
//a new SPITType is created //a new SPITType is created
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITType NEW");
printf("MySPITApp: eventSPITType NEW");
#endif
} }
else { else {
//an existing SPITType is changed //an existing SPITType is changed
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITType CHANGED");
printf("MySPITApp: eventSPITType CHANGED");
#endif
} }
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, " ID: %s GroupName: %s Name: %s confirmed: %d", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data(), p_SPITType.getConfirmed());
printf(" ID: %s GroupName: %s Name: %s confirmed: %d\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data(), p_SPITType.getConfirmed());
#endif
//Check your actions //Check your actions
//Whenever you provide an action for this SPITType take this over in your code. //Whenever you provide an action for this SPITType take this over in your code.
@@ -515,9 +363,7 @@ void MyApp::eventSPITType(bool p_New, const SPITType& p_SPITType) {
*/ */
void MyApp::eventSPITTypeRemote(bool p_New, const SPITType& p_SPITType) { void MyApp::eventSPITTypeRemote(bool p_New, const SPITType& p_SPITType) {
if (p_New) { if (p_New) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITTypeRemote NEW");
printf("MySPITApp: eventSPITTypeRemote NEW");
#endif
} }
else { else {
//we had to inform all Remote SPITObjects using the p_SPITType //we had to inform all Remote SPITObjects using the p_SPITType
@@ -533,13 +379,10 @@ void MyApp::eventSPITTypeRemote(bool p_New, const SPITType& p_SPITType) {
eventSPITObjectRemote(false, p_SPITType, *ptrSPITObject); eventSPITObjectRemote(false, p_SPITType, *ptrSPITObject);
} }
} }
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITTypeRemote CHANGED");
printf("MySPITApp: eventSPITTypeRemote CHANGED");
#endif
} }
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "ID: %s GroupName: %s Name: %s confirmed: %d",
printf(" ID: %s GroupName: %s Name: %s confirmed: %d\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data(), p_SPITType.getConfirmed()); p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data(), p_SPITType.getConfirmed());
#endif
//this is a remote SPITType, if you want you can list this for later remote use. //this is a remote SPITType, if you want you can list this for later remote use.
} }
@@ -552,10 +395,8 @@ void MyApp::eventSPITTypeRemote(bool p_New, const SPITType& p_SPITType) {
* The reference is deleted after this function call!! * The reference is deleted after this function call!!
*/ */
void MyApp::eventSPITTypeRemoved(const SPITType& p_SPITType) { void MyApp::eventSPITTypeRemoved(const SPITType& p_SPITType) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITType Removed");
printf("MySPITApp: eventSPITType Removed"); ESP_LOGD(TAG, " ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data());
printf(" ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data());
#endif
//Check your actions //Check your actions
//take the removal of the SPITType over in your code //take the removal of the SPITType over in your code
@@ -573,10 +414,8 @@ void MyApp::eventSPITTypeRemoved(const SPITType& p_SPITType) {
* The reference is deleted after this function call!! * The reference is deleted after this function call!!
*/ */
void MyApp::eventSPITTypeRemoteRemoved(const SPITType& p_SPITType) { void MyApp::eventSPITTypeRemoteRemoved(const SPITType& p_SPITType) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITTypeRemote Removed");
printf("MySPITApp: eventSPITTypeRemote Removed"); ESP_LOGD(TAG, " ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data());
printf(" ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data());
#endif
//This is a remote SPITType //This is a remote SPITType
//If you have listet this prior you should remove it from the list //If you have listet this prior you should remove it from the list
@@ -626,18 +465,12 @@ void MyApp::eventSPITTypeRemoteRemoved(const SPITType& p_SPITType) {
*/ */
void MyApp::eventSPITObject(bool p_New, const SPITType& p_SPITType, const SPITObject& p_SPITObject) { void MyApp::eventSPITObject(bool p_New, const SPITType& p_SPITType, const SPITObject& p_SPITObject) {
if (p_New) { if (p_New) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITObject NEW");
printf("MySPITApp: eventSPITObject NEW");
#endif
} }
else { else {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITObject CHANGED");
printf("MySPITApp: eventSPITObject CHANGED");
#endif
} }
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, " ID: %s Name: %s -> SPITType: %s", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data());
printf(" ID: %s Name: %s -> SPITType: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data());
#endif
//check your actions //check your actions
//Whenever you provide an action for this SPITObject take this over in your code. //Whenever you provide an action for this SPITObject take this over in your code.
@@ -661,18 +494,12 @@ void MyApp::eventSPITObject(bool p_New, const SPITType& p_SPITType, const SPITOb
*/ */
void MyApp::eventSPITObjectRemote(bool p_New, const SPITType& p_SPITType, const SPITObject& p_SPITObject) { void MyApp::eventSPITObjectRemote(bool p_New, const SPITType& p_SPITType, const SPITObject& p_SPITObject) {
if (p_New) { if (p_New) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITObjectRemote NEW");
printf("MySPITApp: eventSPITObjectRemote NEW");
#endif
} }
else { else {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITObjectRemote CHANGED");
printf("MySPITApp: eventSPITObjectRemote CHANGED");
#endif
} }
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, " ID: %s Name: %s -> SPITType: %s", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data());
printf(" ID: %s Name: %s -> SPITType: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data());
#endif
//This is a remote SPITObject which can be used to remote control the server. //This is a remote SPITObject which can be used to remote control the server.
//If you want you can list this for later use //If you want you can list this for later use
@@ -689,10 +516,8 @@ void MyApp::eventSPITObjectRemote(bool p_New, const SPITType& p_SPITType, const
* The reference is deleted after this function call!! * The reference is deleted after this function call!!
*/ */
void MyApp::eventSPITObjectRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject) { void MyApp::eventSPITObjectRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITObject Removed");
printf("MySPITApp: eventSPITObject Removed"); ESP_LOGD(TAG, " ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data());
printf(" ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data());
#endif
//Check your actions //Check your actions
//take the removal of the SPITObject over in your code //take the removal of the SPITObject over in your code
@@ -712,10 +537,8 @@ void MyApp::eventSPITObjectRemoved(const SPITType& p_SPITType, const SPITObject&
* The reference is deleted after this function call!! * The reference is deleted after this function call!!
*/ */
void MyApp::eventSPITObjectRemoteRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject) { void MyApp::eventSPITObjectRemoteRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventSPITObjectRemote Removed");
printf("MySPITApp: eventSPITObjectRemote Removed"); ESP_LOGD(TAG, " ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data());
printf(" ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data());
#endif
//This is a remote SPITObject //This is a remote SPITObject
//If you have listet this prior you should remove it from the list //If you have listet this prior you should remove it from the list
@@ -740,9 +563,7 @@ void MyApp::eventSPITObjectRemoteRemoved(const SPITType& p_SPITType, const SPITO
// SPIT distinguishes between the different players. All eventPlay... functions contain the information which player plays the SPIT object. // SPIT distinguishes between the different players. All eventPlay... functions contain the information which player plays the SPIT object.
void MyApp::eventPlay(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_PlayerIsRunning, long long p_TimeFrames) { void MyApp::eventPlay(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_PlayerIsRunning, long long p_TimeFrames) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventPlay Player: %s Runs: %d Time: %lld", p_PlayerName.data(), p_PlayerIsRunning, p_TimeFrames);
printf("MySPITApp: eventPlay Player: %s Runs: %d Time: %lld\n", p_PlayerName.data(), p_PlayerIsRunning, p_TimeFrames);
#endif
switch(p_PlayerType) { switch(p_PlayerType) {
case SPIT_Client::PLAYERTYPE_MAIN: case SPIT_Client::PLAYERTYPE_MAIN:
@@ -786,10 +607,8 @@ void MyApp::eventPlayObject(string p_PlayerID, bool p_Started, bool p_Ended, con
//in liveSHOWsoftware the player may play two different position in the SPITObject to mix them down, e.g. a SceneBridge is played //in liveSHOWsoftware the player may play two different position in the SPITObject to mix them down, e.g. a SceneBridge is played
//We can get the second (pre played) position: p_PlayObject.getFrameInsidePrePosition(); //We can get the second (pre played) position: p_PlayObject.getFrameInsidePrePosition();
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventPlayObject Player: %s is running: %d Object Started: %d Stopped: %d", p_PlayObject.getPlayerName().data(), p_PlayObject.getPlayerIsRunning(), p_Started, p_Ended);
printf("MySPITApp: eventPlayObject Player: %s is running: %d Object Started: %d Stopped: %d\n", p_PlayObject.getPlayerName().data(), p_PlayObject.getPlayerIsRunning(), p_Started, p_Ended); ESP_LOGD(TAG, " SPITType: %s SPITObject: %s Position: %lld Value: %f\n", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_PlayObject.getFrameInside(), doubleValue);
printf(" SPITType: %s SPITObject: %s Position: %lld Value: %f\n", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_PlayObject.getFrameInside(), doubleValue);
#endif
//check for your actions to do //check for your actions to do
@@ -800,36 +619,24 @@ void MyApp::eventPlayObject(string p_PlayerID, bool p_Started, bool p_Ended, con
if (p_SPITType.getID() == "MySPITAPP_Action1ID") { //do Action 1 if (p_SPITType.getID() == "MySPITAPP_Action1ID") { //do Action 1
//we can get some information about the play status //we can get some information about the play status
if (p_Started == true) { if (p_Started == true) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "MyApp AKTION 1 started Value: %f and running: %d", doubleValue, boolPLayerIsRunning);
printf("MyApp AKTION 1 started Value: %f and running: %d\n", doubleValue, boolPLayerIsRunning);
#endif
} }
else if (p_Ended == true) { else if (p_Ended == true) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "MyApp AKTION 1 ended"); //p_PlayObject.getFrameInside() is -1
printf("MyApp AKTION 1 ended\n"); //p_PlayObject.getFrameInside() is -1
#endif
} }
else { else {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "MyApp AKTION 1 is played Value: %f and running: %d", doubleValue, boolPLayerIsRunning);
printf("MyApp AKTION 1 is played Value: %f and running: %d\n", doubleValue, boolPLayerIsRunning);
#endif
} }
} }
else if (p_SPITType.getID() == "MySPITAPP_Action2ID") { //do Action 2 else if (p_SPITType.getID() == "MySPITAPP_Action2ID") { //do Action 2
if (p_Started == true) { if (p_Started == true) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "AKTION 2 started Value: %f and running: %d", doubleValue, boolPLayerIsRunning);
printf("MyApp AKTION 2 started Value: %f and running: %d\n", doubleValue, boolPLayerIsRunning);
#endif
} }
else if (p_Ended == true) { else if (p_Ended == true) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "AKTION 2 ended"); //p_PlayObject.getFrameInside() is -1
printf("MyApp AKTION 2 ended\n"); //p_PlayObject.getFrameInside() is -1
#endif
} }
else { else {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "AKTION 2 is played Value: %f and running: %d", doubleValue, boolPLayerIsRunning);
printf("MyApp AKTION 2 is played Value: %f and running: %d\n", doubleValue, boolPLayerIsRunning);
#endif
} }
} }
} }
@@ -851,9 +658,7 @@ void MyApp::eventPlayObject(string p_PlayerID, bool p_Started, bool p_Ended, con
* @param p_Value the new value * @param p_Value the new value
*/ */
void MyApp::eventPlayRemoteObjectStatus(const SPITType& p_SPITType, const SPITObject& p_SPITObject, long long p_FrameInsideObject, int p_Value) { void MyApp::eventPlayRemoteObjectStatus(const SPITType& p_SPITType, const SPITObject& p_SPITObject, long long p_FrameInsideObject, int p_Value) {
#if defined(DEBUGOUTPUT) ESP_LOGD(TAG, "eventPlayRemoteObjectStatus RemoteSPITType: %s RemoteSPITObject: %s Position: %lld Value: %d", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_FrameInsideObject, p_Value);
printf("MySPITApp: eventPlayRemoteObjectStatus RemoteSPITType: %s RemoteSPITObject: %s Position: %lld Value: %d\n", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_FrameInsideObject, p_Value);
#endif
} }
/** /**
+6 -3
View File
@@ -1636,13 +1636,16 @@ const char* SPIT_Message::getMessageBytes() {
//---------------------------- static helper functions ----------------------- //---------------------------- static helper functions -----------------------
bool SPIT_Message::isSystemLittleEndian() { bool SPIT_Message::isSystemLittleEndian() {
// todo replace with #include <bit> then if constexpr (std::endian::native == std::endian::big)
int intOne = 1; int intOne = 1;
char* firstByte; char* firstByte;
firstByte = (char*)&intOne; firstByte = (char*)&intOne;
// firstByte = intOne & 0xff000000; if (*firstByte > 0) {
if (firstByte > 0) return false; return false;
else return true;
} }
return true;
}
int SPIT_Message::getInt(char* p_Bytes, int p_ByteCount, int p_Offset) { int SPIT_Message::getInt(char* p_Bytes, int p_ByteCount, int p_Offset) {
if (p_Offset < 0) throw "ParseError_received"; if (p_Offset < 0) throw "ParseError_received";
if (p_Bytes == NULL || p_ByteCount < p_Offset + 4) throw "ParseError_received"; if (p_Bytes == NULL || p_ByteCount < p_Offset + 4) throw "ParseError_received";
+19 -71
View File
@@ -16,10 +16,12 @@
#include "_SPITMACROS.h" #include "_SPITMACROS.h"
#if defined(OS_MAC) || defined(OS_LINUX)
#include "UnixSocket.h" #include "UnixSocket.h"
// #include <ifaddrs.h>
#include <thread>
#include "esp_netif.h"
#include "esp_log.h"
UnixSocket::UnixSocket() : SPITSocket(){ UnixSocket::UnixSocket() : SPITSocket(){
SPITSocket::FAMILY_IP4 = AF_INET; SPITSocket::FAMILY_IP4 = AF_INET;
@@ -63,7 +65,7 @@ int UnixSocket::cleanUp() {
*/ */
bool UnixSocket::createSocket_UDP() { bool UnixSocket::createSocket_UDP() {
bool boolSuccess = true; bool boolSuccess = true;
int intResult; int intResult = -1;
int intOptionValue4 = 1; int intOptionValue4 = 1;
int intOptionValue6 = 1; int intOptionValue6 = 1;
u_char charOptionValue = 0x01; u_char charOptionValue = 0x01;
@@ -145,12 +147,7 @@ int UnixSocket::bindSocket(string p_ClientIP, string p_ClientPort) {
memset(&o_IP4SocketAddress, 0, intSocklen); memset(&o_IP4SocketAddress, 0, intSocklen);
o_IP4SocketAddress.sin_addr = ptrIP4SocketAddress->sin_addr; o_IP4SocketAddress.sin_addr = ptrIP4SocketAddress->sin_addr;
o_IP4SocketAddress.sin_family = ptrIP4SocketAddress->sin_family; o_IP4SocketAddress.sin_family = ptrIP4SocketAddress->sin_family;
#if defined(OS_MAC)
o_IP4SocketAddress.sin_len = ptrIP4SocketAddress->sin_len;
#endif
#if defined(OS_LINUX)
//o_IP4SocketAddress.sin_zero = ptrIP4SocketAddress->sin_zero; //o_IP4SocketAddress.sin_zero = ptrIP4SocketAddress->sin_zero;
#endif
o_IP4SocketAddress.sin_port = ptrIP4SocketAddress->sin_port; o_IP4SocketAddress.sin_port = ptrIP4SocketAddress->sin_port;
intResult = bind(m_UDPSocketIP4, (const sockaddr*)(ptrIP4SocketAddress),(socklen_t)intSocklen); intResult = bind(m_UDPSocketIP4, (const sockaddr*)(ptrIP4SocketAddress),(socklen_t)intSocklen);
if (intResult < 0) { if (intResult < 0) {
@@ -360,71 +357,22 @@ string UnixSocket::getBroadcastIP4(SPITSocket::IPAddress* p_IPAddress) {
} }
void UnixSocket::getAdaptersInfo() { void UnixSocket::getAdaptersInfo() {
struct ifaddrs *ifaddr, *ifa;
struct sockaddr_in *o_sockaddr_in;
// struct sockaddr_in6 *o_sockaddr_in6;
char buffer[64];
string stringIP4;
string stringSubnet;
void *in_addr;
void *in_subnet;
resetFoundIPAddresses(); resetFoundIPAddresses();
// iterate over active interfaces, and print out IPs
esp_netif_t *netif = NULL;
while ((netif = esp_netif_next_unsafe(netif)) != NULL) {
ESP_LOGI("SPIT", "Connected to %s", esp_netif_get_desc(netif));
esp_netif_ip_info_t ip;
ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip));
ESP_LOGI("SPIT", "- IPv4 address: " IPSTR ",", IP2STR(&ip.ip));
ESP_LOGI("SPIT", "- IPv4 netmask: " IPSTR ",", IP2STR(&ip.netmask));
char buffer[64];
if (getifaddrs(&ifaddr) == -1) { sprintf(buffer, IPSTR, IP2STR(&ip.ip));
printf("UnixSocket::getAdaptersInfo getifaddrs < 0\n"); string stringIP4 = buffer;
return; sprintf(buffer, IPSTR, IP2STR(&ip.netmask));
} string stringSubnet = buffer;
struct sockaddr* ptrSockAddr;
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr == NULL) break;
switch (ifa->ifa_addr->sa_family) {
case AF_INET:
o_sockaddr_in = (struct sockaddr_in *)ifa->ifa_addr;
in_addr = &o_sockaddr_in->sin_addr;
o_sockaddr_in = (struct sockaddr_in *)ifa->ifa_netmask;
in_subnet = &o_sockaddr_in->sin_addr;
break;
case AF_INET6:
continue;
/*
o_sockaddr_in6 = (struct sockaddr_in6 *)ifa->ifa_addr;
in_addr = &o_sockaddr_in6->sin6_addr;
o_sockaddr_in6 = (struct sockaddr_in6 *)ifa->ifa_netmask;
in_subnet = &o_sockaddr_in6->sin6_addr;
break;
*/
default:
continue;
}
if (inet_ntop(ifa->ifa_addr->sa_family, in_addr, buffer, sizeof(buffer))) {
stringIP4 = buffer;
}
else {
continue;
}
if (inet_ntop(ifa->ifa_addr->sa_family, in_subnet, buffer, sizeof(buffer))) {
stringSubnet = buffer;
}
else {
continue;
}
#if defined(DEBUGOUTPUT)
printf("Networkadapter %s: %s Subnet %s\n", ifa->ifa_name, stringIP4.data(), stringSubnet.data());
#endif
addIPAddress(stringIP4, stringSubnet); addIPAddress(stringIP4, stringSubnet);
} }
//IP4 loopback maybe not ok
#if defined(DEBUGOUTPUT)
printf("Networkinterfaces add/change loopback 127.0.0.1 subnet 255.255.255.0\n");
#endif
addIPAddress("127.0.0.1", "255.255.255.0");
freeifaddrs(ifaddr);
removeNotFoundIPAddresses(); removeNotFoundIPAddresses();
} }
#endif
-400
View File
@@ -1,400 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* Windows implementation of a SPITSocket.
*
* File: WindowsSocket.cpp
* Author: Hagi
*
* Created on 11. April 2019, 08:36
*/
#include "_SPITMACROS.h"
#if defined(OS_WINDOWS)
#include "WindowsSocket.h"
//----- -----
WindowsSocket::WindowsSocket() : SPITSocket(){
SPITSocket::FAMILY_IP4 = AF_INET;
SPITSocket::FAMILY_IP6 = AF_INET6;
m_UDPSocketIP4 = INVALID_SOCKET;
m_UDPSocketIP6 = INVALID_SOCKET;
createSocket_UDP();
}
WindowsSocket::~WindowsSocket() {
int intResultIP4;
int intResultIP6;
if (m_UDPSocketIP4 != INVALID_SOCKET) {
// intResultIP4 = shutdown(m_UDPSocketIP4, 2);
intResultIP4 = closesocket(m_UDPSocketIP4);
m_UDPSocketIP4 = INVALID_SOCKET;
}
if (m_UDPSocketIP6 != INVALID_SOCKET) {
// intResultIP6 = shutdown(m_UDPSocketIP6, 2);
intResultIP6 = closesocket(m_UDPSocketIP6);
m_UDPSocketIP6 = INVALID_SOCKET;
}
this_thread::sleep_for(chrono::milliseconds(100));
}
/**
* Initialize WSAStartup
* @return
*/
int WindowsSocket::init() {
WSADATA wsa;
int intResult;
intResult = WSAStartup(MAKEWORD(2,2),&wsa);
return intResult;
}
/**
* Clean WSACleanup
* @return
*/
int WindowsSocket::cleanUp() {
int intResult;
intResult = WSACleanup();
return intResult;
}
/**
* Creates two new sockets.<br>
* One socket for IP4 and one for IP6.<br>
* If there exist some, they will be closed.<br>
* @return
*/
bool WindowsSocket::createSocket_UDP() {
bool boolSuccess = true;
int intResult = -1;
int intResultNonBlocking = 0;
BOOL o_OptionValue = TRUE;
//ip4
if (m_UDPSocketIP4 != INVALID_SOCKET) {
closesocket(m_UDPSocketIP4);
m_UDPSocketIP4 = INVALID_SOCKET;
}
if (m_UDPSocketIP6 != INVALID_SOCKET) {
closesocket(m_UDPSocketIP6);
m_UDPSocketIP6 = INVALID_SOCKET;
}
m_UDPSocketIP4 = socket(AF_INET,SOCK_DGRAM, 0);
if (m_UDPSocketIP4 == INVALID_SOCKET) {
boolSuccess = false;
}
else {
intResult = setsockopt(m_UDPSocketIP4, SOL_SOCKET, SO_REUSEADDR, (char*)&o_OptionValue, sizeof(o_OptionValue));
}
m_UDPSocketIP6 = socket(AF_INET6,SOCK_DGRAM,0);
if (m_UDPSocketIP6 == INVALID_SOCKET) {
boolSuccess = false;
closesocket(m_UDPSocketIP4);
m_UDPSocketIP4 = INVALID_SOCKET;
}
else {
intResult = setsockopt(m_UDPSocketIP6, SOL_SOCKET, SO_REUSEADDR, (char*)&o_OptionValue, sizeof(o_OptionValue));
}
if (intResult < 0) {
boolSuccess = false;
}
else {
//set the m_UDPSocketIP4 and m_UDPSocketIP6 in NON BLOCKING mode because
//if the UDPSockets are in blocking mode the receiveMessage does not return in every constellation
u_long blockingMode = 1; //1 = non blocking, 0 = blocking
intResultNonBlocking = ioctlsocket(m_UDPSocketIP4, FIONBIO, &blockingMode);
intResultNonBlocking = ioctlsocket(m_UDPSocketIP6, FIONBIO, &blockingMode);
if (intResultNonBlocking != 0) {
boolSuccess = false;
}
}
return boolSuccess;
}
/**
* Binds the socket to the client's ip address and port.<br>
* The socket option SO_REUSEADDR is set to true.<br>
* @param p_ClientIP ip address of the client
* @param p_ClientPort port of the client.<br>
* if p_Port == "0" any free port will be used<br>
* @return -1 id bind fails, o if bind is ok
*
*/
int WindowsSocket::bindSocket(string p_ClientIP, string p_ClientPort)
{
ADDRINFO *clientAI;
SOCKADDR_IN o_IP4SocketAddress;
SOCKADDR_IN6 o_IP6SocketAddress;
int socklen;
string stringClientPort;
if (p_ClientPort.length() <= 0) stringClientPort = "0";
else stringClientPort = p_ClientPort;
//int intResult = SOCKET_ERROR;
int intResult = 0;
if (getaddrinfo(p_ClientIP.data(), stringClientPort.data(), NULL, &clientAI) != 0) {
return SOCKET_ERROR;
}
BOOL o_OptionValue = TRUE;
switch(clientAI->ai_family) {
case AF_INET:
if (m_UDPSocketIP4 == INVALID_SOCKET) {
break;
}
intResult = bind(m_UDPSocketIP4, (const sockaddr*)clientAI->ai_addr, (int)clientAI->ai_addrlen);
if (intResult < 0) {
break;
}
setBoundClientFamily(AF_INET);
if (intResult == 0) {
socklen = sizeof (o_IP4SocketAddress);
if (getsockname(m_UDPSocketIP4, (SOCKADDR*)&o_IP4SocketAddress, &socklen) != -1) {
setBoundClientPort(to_string((int)o_IP4SocketAddress.sin_port));
}
}
break;
case AF_INET6:
if (m_UDPSocketIP6 == INVALID_SOCKET) {
break;
}
if (intResult < 0) {
break;
}
intResult = bind(m_UDPSocketIP6, (const sockaddr*)clientAI->ai_addr, (int)clientAI->ai_addrlen);
if (intResult < 0) {
break;
}
setBoundClientFamily(AF_INET6);
if (intResult == 0) {
socklen = sizeof (o_IP6SocketAddress);
if (getsockname(m_UDPSocketIP6, (SOCKADDR*)&o_IP6SocketAddress, &socklen) != -1) {
setBoundClientPort(to_string((int)o_IP6SocketAddress.sin6_port));
}
}
break;
default:
setBoundClientFamily(0);
intResult = SOCKET_ERROR;
break;
}
freeaddrinfo(clientAI);
if (intResult == SOCKET_ERROR) {
setIsBound(false);
}
else {
setIsBound(true);
}
return intResult;
}
/**
* Set the sockopt SO_BROADCAST to 0 or 1
* @param p_Broadcast true SO_BROADCAST is set<br>
* false = SO_BROADCAST is not set
* @return 0 = ok, -1 = error
*/
int WindowsSocket::setBroadcast(bool p_Broadcast) {
int intResult;
//IP4
BOOL o_BroadcastValue = FALSE;
if (p_Broadcast) {
o_BroadcastValue = TRUE;
}
else {
o_BroadcastValue = FALSE;
}
intResult = setsockopt(m_UDPSocketIP4, SOL_SOCKET, SO_BROADCAST, (char*)&o_BroadcastValue, sizeof(BOOL));
//IP6
DWORD loop = 1;
if (p_Broadcast) {
loop = 1;
}
else {
loop = 0;
}
intResult = setsockopt(m_UDPSocketIP6, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char*)&loop, sizeof (loop));
return intResult;
}
/**
*
* @param p_InetFamily AF_INET or AF_INET6
* @param p_ServerIP the ip address of the server
* @param p_ServerPort the port of the server
* @param p_MessageBytes buffer containing the message
* @param p_MessageLength the length of the message
* @return -1 send fails<br>
* 0 send is done
*/
int WindowsSocket::sendMessageTo(int p_InetFamily, string p_ServerIP, string p_ServerPort, const char* p_MessageBytes, int p_MessageLength) {
if (m_UDPSocketIP4 == INVALID_SOCKET && m_UDPSocketIP6 == INVALID_SOCKET) return -1;
ADDRINFO *ptrAddressInfo;
int intResult = SOCKET_ERROR;
// prepare AddressInfo
if (getaddrinfo(p_ServerIP.data(), p_ServerPort.data(), NULL, &ptrAddressInfo) != 0) {
return -1;
}
switch(ptrAddressInfo->ai_family) {
case AF_INET:
if (m_UDPSocketIP4 != INVALID_SOCKET) {
intResult = sendto(m_UDPSocketIP4, p_MessageBytes, p_MessageLength, 0, ptrAddressInfo->ai_addr, ptrAddressInfo->ai_addrlen);
freeaddrinfo(ptrAddressInfo);
}
break;
case AF_INET6:
if (m_UDPSocketIP6 != INVALID_SOCKET) {
intResult = sendto(m_UDPSocketIP6, p_MessageBytes, p_MessageLength, 0, ptrAddressInfo->ai_addr, ptrAddressInfo->ai_addrlen);
freeaddrinfo(ptrAddressInfo);
}
break;
default:
intResult = -1;
}
if (intResult == SOCKET_ERROR) {
return -1;
}
return 0;
}
/**
* Starts receiving a message
* @param p_InetFamily AF_INET or AF_INET6
* @param p_Buffer a char* buffer large enough to hold the expected data
* @param p_BufferLength the length of the buffer
* @param p_ServerIP = NULL, the ip address is not determined<br>
* != NULL after receiving a message p_ServerID contains the ip address of the sender/server
* @return
*/
int WindowsSocket::receiveMessage(int p_InetFamily, char* p_Buffer, int p_BufferLength, string* p_ServerIP) {
int intResult = SOCKET_ERROR;
// ADDRINFO *AI;
SOCKADDR_IN o_IP4SocketAddress;
SOCKADDR_IN6 o_IP6SocketAddress;
int socklen;
switch(p_InetFamily) {
case AF_INET:
if (m_UDPSocketIP4 == INVALID_SOCKET) {
break;
}
socklen = sizeof (o_IP4SocketAddress);
intResult = recvfrom(m_UDPSocketIP4, p_Buffer, p_BufferLength, 0, (SOCKADDR *)&o_IP4SocketAddress, &socklen);
if (intResult >= 0) {
if (p_ServerIP != NULL) {
*p_ServerIP = inet_ntoa(o_IP4SocketAddress.sin_addr);
}
}
break;
case AF_INET6:
if (m_UDPSocketIP6 == INVALID_SOCKET) {
break;
}
socklen = sizeof (o_IP6SocketAddress);
intResult = recvfrom(m_UDPSocketIP6, p_Buffer, p_BufferLength, 0, (SOCKADDR *)&o_IP6SocketAddress, &socklen);
if (intResult >= 0) {
if (p_ServerIP != NULL) {
char clienthost[NI_MAXHOST]; //The clienthost will hold the IP address.
char clientservice[NI_MAXSERV];
GetNameInfo((SOCKADDR *)&o_IP6SocketAddress, socklen, clienthost, sizeof(clienthost), clientservice, sizeof(clientservice), NI_NUMERICHOST|NI_NUMERICSERV);
*p_ServerIP = clienthost;
}
}
break;
}
return intResult;
}
/**
* Calculates the broadcast address from a ip4 address.<br>
* @param p_IPAddress the ip4 address
* @return returns the broadcast address
*/
string WindowsSocket::getBroadcastIP4(SPITSocket::IPAddress* p_IPAddress) {
struct in_addr broadcast;
unsigned long ulIPAddress;
unsigned long ulSubnetMask;
ulIPAddress = inet_addr(p_IPAddress->getIPAddress().data());
ulSubnetMask = inet_addr(p_IPAddress->getSubnetMask().data());
broadcast.s_addr = ulIPAddress | ~ulSubnetMask;
return inet_ntoa(broadcast);
}
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
/// Note: could also use malloc() and free()
/**
* Detect all ip-addresses
*/
void WindowsSocket::getAdaptersInfo() {
// It is possible for an adapter to have multiple
// IPv4 addresses, gateways, and secondary WINS servers
// assigned to the adapter.
//
PIP_ADAPTER_INFO pAdapterInfo;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
resetFoundIPAddresses();
ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO *) MALLOC(sizeof (IP_ADAPTER_INFO));
if (pAdapterInfo == NULL) {
printf("WindowsSocket::getAdaptersInfo Error allocating memory needed to call GetAdaptersinfo\n");
return ;
}
// Make an initial call to GetAdaptersInfo to get
// the necessary size into the ulOutBufLen variable
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
FREE(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *) MALLOC(ulOutBufLen);
if (pAdapterInfo == NULL) {
printf("WindowsSocket::getAdaptersInfo Error allocating memory needed to call GetAdaptersinfo\n");
return ;
}
}
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
pAdapter = pAdapterInfo;
while (pAdapter) {
if (strncmp(pAdapter->IpAddressList.IpAddress.String, "0.0.0.", 6) == 0) {
pAdapter = pAdapter->Next;
continue;
}
addIPAddress(pAdapter->IpAddressList.IpAddress.String, pAdapter->IpAddressList.IpMask.String);
pAdapter = pAdapter->Next;
}
} else {
printf("WindowsSocket::getAdaptersInfo failed with error: %ud\n", dwRetVal);
}
if (pAdapterInfo)
FREE(pAdapterInfo);
//loopback is not listet-> add manually
addIPAddress("127.0.0.1", "255.0.0.0");
removeNotFoundIPAddresses();
}
#endif
+17 -27
View File
@@ -5,41 +5,31 @@
*/ */
#include "_SPITMACROS.h" #include "_SPITMACROS.h"
#include "esp/uuid.h"
#include "esp_netif.h"
string createGUID() { string createGUID() {
#if defined(OS_WINDOWS) // uuid_t id;
GUID o_GUID; // uuid_generate(id);
CoCreateGuid(&o_GUID); // char *guid_string = new char[100];
char guid_string[37]; // 32 hex chars + 4 hyphens + null terminator // uuid_unparse(id, guid_string);
snprintf( // string stringGUID = guid_string;
guid_string, sizeof(guid_string) / sizeof(guid_string[0]), // return stringGUID;
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
o_GUID.Data1, o_GUID.Data2, o_GUID.Data3,
o_GUID.Data4[0], o_GUID.Data4[1], o_GUID.Data4[2],
o_GUID.Data4[3], o_GUID.Data4[4], o_GUID.Data4[5],
o_GUID.Data4[6], o_GUID.Data4[7]);
string stringGUID = guid_string;
return stringGUID;
#endif
uuid_t uu;
char uu_str[UUID_STR_LEN];
#if defined(OS_MAC) || defined(OS_LINUX) uuid_generate(uu);
uuid_t id; uuid_unparse(uu, uu_str);
uuid_generate(id); string stringGUID = uu_str;
char *guid_string = new char[100];
uuid_unparse(id, guid_string);
string stringGUID = guid_string;
return stringGUID; return stringGUID;
#endif
} }
/** The name of the client's host computer*/ /** The name of the client's host computer*/
string getClientHostName() { string getClientHostName() {
string stringHostName; string stringHostName = "";
char hostname[255]; const char * hostname;
if (gethostname(hostname, 255) != 0) { esp_netif_get_hostname(esp_netif_get_default_netif(), &hostname);
stringHostName = ""; if (hostname != nullptr) {
}
else {
stringHostName = hostname; stringHostName = hostname;
} }
return stringHostName;; return stringHostName;;
+1
View File
@@ -0,0 +1 @@
https://github.com/typester/esp32-uuid/tree/master
+7
View File
@@ -0,0 +1,7 @@
Copyright 2019 Daisuke Murase (typester)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+84
View File
@@ -0,0 +1,84 @@
#include "uuid.h"
#include <string.h>
#include "esp_system.h"
#include "esp_random.h"
void uuid_generate(uuid_t out)
{
esp_fill_random(out, sizeof(uuid_t));
/* uuid version */
out[6] = 0x40 | (out[6] & 0xF);
/* uuid variant */
out[8] = (0x80 | out[8]) & ~0x40;
}
static uint8_t unhex_char(unsigned char s)
{
if (0x30 <= s && s <= 0x39) { /* 0-9 */
return s - 0x30;
} else if (0x41 <= s && s <= 0x46) { /* A-F */
return s - 0x41 + 0xa;
} else if (0x61 <= s && s <= 0x69) { /* a-f */
return s - 0x61 + 0xa;
} else {
/* invalid string */
return 0xff;
}
}
static int unhex(unsigned char *s, size_t s_len, unsigned char *r)
{
int i;
for (i = 0; i < s_len; i += 2) {
uint8_t h = unhex_char(s[i]);
uint8_t l = unhex_char(s[i + 1]);
if (0xff == h || 0xff == l) {
return -1;
}
r[i / 2] = (h << 4) | (l & 0xf);
}
return 0;
}
int uuid_parse(const char *in, uuid_t uu)
{
const char *p = in;
uint8_t *op = (uint8_t *)uu;
if (0 != unhex((unsigned char *)p, 8, op)) {
return -1;
}
p += 8;
op += 4;
for (int i = 0; i < 3; i++) {
if ('-' != *p++ || 0 != unhex((unsigned char *)p, 4, op)) {
return -1;
}
p += 4;
op += 2;
}
if ('-' != *p++ || 0 != unhex((unsigned char *)p, 12, op)) {
return -1;
}
p += 12;
op += 6;
return 0;
}
void uuid_unparse(const uuid_t uu, char *out)
{
snprintf(out, UUID_STR_LEN,
"%02x%02x%02x%02x-%02x%02x-%02x%02x-"
"%02x%02x-%02x%02x%02x%02x%02x%02x",
uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7], uu[8], uu[9], uu[10], uu[11],
uu[12], uu[13], uu[14], uu[15]);
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include <stdint.h>
typedef uint8_t uuid_t[16];
#define UUID_STR_LEN 37
#ifdef __cplusplus
extern "C" {
#endif
void uuid_generate(uuid_t out);
int uuid_parse(const char *in, uuid_t uu);
void uuid_unparse(const uuid_t uu, char *out);
#ifdef __cplusplus
}
#endif