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(
SRC_DIRS "src"
SRC_DIRS "src" "src/esp"
INCLUDE_DIRS "include"
REQUIRES esp_system esp_netif freeRtosApi
)
+4 -9
View File
@@ -20,9 +20,6 @@
using namespace std;
int main();
class MyApp : SPIT_ClientInterface {
public:
MyApp();
@@ -30,10 +27,6 @@ public:
//Client's infos is set by the client
static string s_ClientName;
static string s_ClientProjectID;
static string s_ClientProjectName;
static int s_ClientDefaultFramesPerSecond;
void loadClientProject();
private:
@@ -53,6 +46,8 @@ private:
string m_ServerProjectID;
string m_ServerProjectName;
int m_ServerFramesPerSecond; //set when the server reports his project, see eventProjectReport
//liveSHOWsoftware will use 44100 frames per second as time resolution
//All times are given in frames,
//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
@@ -63,8 +58,8 @@ private:
public:
//---------- SPIT_ClientInterface -------------
string getClientProjectID(); //should return the client's project id, maybe the same as project name
string getClientProjectName(); //should return the client's project name
string getClientProjectName();
//----- ServerAutoDetection -----
void startServerAutoDetect(); //starts the autodetection of SPITServers in the local network area (see eventServerDetected)
void stopServerAutoDetect(); //stopps the autodetection
-8
View File
@@ -15,12 +15,7 @@
#define SPIT_CLIENT_H
#include "_SPITMACROS.h"
#if defined OS_WINDOWS
#include "WindowsSocket.h"
#endif
#if defined OS_MAC || defined OS_LINUX
#include "UnixSocket.h"
#endif
#include "SPITSocket.h"
#include "SAD_Client.h"
@@ -35,9 +30,6 @@
#include "SPITPlayer.h"
#include <chrono>
//#include <thread>
using namespace std;
//static char nullChar[] = "\0";
-4
View File
@@ -15,9 +15,6 @@
#define UNIXSOCKET_H
#include "_SPITMACROS.h"
#if defined(OS_MAC) || defined(OS_LINUX)
#include <ifaddrs.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
@@ -50,7 +47,6 @@ public:
int sendMessageTo(int p_InetFamily, string p_ServerIP, string p_ServerPort, const char* p_MessageBytes, int p_MessageLength);
int receiveMessage(int p_InetFamily, char* p_Buffer, int p_BufferLength, string* p_ServerIP);
};
#endif
#endif /* UNIXSOCKET_H */
-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 */
+6 -45
View File
@@ -1,57 +1,18 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
#pragma once
/*
* File: _SPITMACROS.h
* Author: Hagi
*
* Created on 13. April 2019, 13:37
*/
#include <unistd.h>
// #include <uuid/uuid.h>
#ifndef _SPITMACROS_H
#define _SPITMACROS_H
//To compile for a specific operating system, you must change the precompiler comments.
//In windows Ws2_32.lib Iphlpapi.lib (in gcc: -liphlpapi -lole32) should be added to the linker options
#ifndef OS_WINDOWS
// #define OS_WINDOWS
// #include <WinSock2.h> //include this here, because it must be included before string.h .. is included
#endif
#ifndef OS_MAC
// #define OS_MAC
// #include <unistd.h>
// #include<uuid/uuid.h>
#endif
#ifndef OS_LINUX
#define OS_LINUX
#include <unistd.h>
#include<uuid/uuid.h>
#endif
//To output debug information (printf calls in the code)
//you must set or comment out this precompiler definition
// To output debug information (printf calls in the code)
// you must set or comment out this precompiler definition
#ifndef DEBUGOUTPUT
#define DEBUGOUTPUT
#define DEBUGOUTPUT
#endif
#include <string>
using namespace std;
//--------- OS specific functions ---------
/** Returns an guid */
string createGUID();
/** Returns the name of the client's host computer*/
string getClientHostName();
#endif /* _SPITMACROS_H */
+89 -284
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 "Task.hpp"
#include "esp_log.h"
string MyApp::s_ClientName = "MySPITApp_Client"; //Name of this Client
string MyApp::s_ClientProjectName = "MySPITAppProject"; //Name of the client'loaded project
string MyApp::s_ClientProjectID = s_ClientProjectName; //ID of the client's project - maybe the same as the name or a specific id
const char * TAG = "SPIT";
#if defined(OS_WINDOWS)
//Win32 Main Function - application entry
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();
void SpitClientApp() {
auto ptrMyApp = std::make_unique<MyApp>();
//load a client project
//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
ptrMyApp->startServerAutoDetect();
//This application is multthreaded, in the background all is done by several threads
//all events are delegated to SPIT_Handler
//-> 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
this_thread::sleep_for(chrono::milliseconds(30000));
//perhaps you should save the client project
//close MyApp instance
delete ptrMyApp;
return 0;
while (true) {
fos::Task::delayMs(10000);
ptrMyApp->testLiveShowRemote(); //This is an excample how to remote control the liveSHOWsoftware
}
}
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);
//You need to give your application a descriptive name
m_SPIT_Client->setName(s_ClientName);
//The following members are set in loadClientProject function.
m_ClientProjectName = "";
m_ClientProjectID = ""; //id can be the same as the project name
m_ClientProjectID = "";
//The following members are set in the eventConnectionStatus
m_ServerID = "";
@@ -107,18 +47,11 @@ MyApp::MyApp() {
m_ServerProjectID = "";
m_ServerProjectName = "";
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
//see eventServerDetected and eventConnectionStatus
m_FlagReconnect = false;
}
MyApp::~MyApp() {
//To close the connection and all other stuff delete the SPIT_Client instance
if (m_SPIT_Client != NULL) {
@@ -128,71 +61,40 @@ MyApp::~MyApp() {
//Following functions fullfill the SPIT_ClientInterface
//They are needed when the server sends his project, see eventProjectReport
//and they should be set in loadClientProject
string MyApp::getClientProjectID() {
return m_ClientProjectID;
}
//Following functions fullfill the SPIT_ClientInterface
//They are needed when the server sends his project, see eventProjectReport
string MyApp::getClientProjectName() {
return m_ClientProjectName;
}
void MyApp::loadClientProject() {
//----- close the actual client project -----
//inform the SPIT_Client that the actual project will close
//If there is actual no connection to the server nothing happens
//----- close current client project -----
if (m_SPIT_Client != NULL) {
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) {
//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 a SPITTypes according to the following patterns
//Excample "Action1"
SPITType* ptrSPITType1Fix;
ptrSPITType1Fix = m_SPIT_Client->createSPITTypeFixed("MySPITAPP_Action1ID", "MyActionGroupName", "FixedAction1", 0, 0);
//When an action exist which shpuld be done whenever a SPITObject with this SPITType is played, <br>
ptrSPITType1Fix = m_SPIT_Client->createSPITTypeFixed("MySPITAPP_Action1ID", "ActionGroupName", "Action1Name", 0, 0);
SPITType* ptrSPITType2Fix;
ptrSPITType2Fix = m_SPIT_Client->createSPITTypeFixed("MySPITAPP_Action2ID", "ActionGroupName", "Action2Name", 0, 0);
//When an action exist which should be done whenever a SPITObject with this SPITType is played, <br>
//then you should 'setAssignedActionType' to 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);
//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) {
m_SPIT_Client->clientProjectLoaded();
}
}
//-----------------------------------------
@@ -223,33 +125,24 @@ void MyApp::stopServerAutoDetect() {
*/
void MyApp::eventServerDetected(const SAD_DetectedServer& p_DetectedServer) {
//fetch the infoemations from the p_DetectedServer
#if defined(DEBUGOUTPUT)
printf("mySPITApp\n");
printf("-----> SERVER DETECTED\n");
printf(" Name: %s\n", p_DetectedServer.getName().data());
printf(" ID: %s\n", p_DetectedServer.getID().data());
printf(" Computer: %s\n", p_DetectedServer.getComputerName().data());
printf(" IP: %s\n", p_DetectedServer.getIP().data());
printf(" Port: %s\n", p_DetectedServer.getPort().data());
printf(" Addition: %s\n", p_DetectedServer.getAdditions().data());
printf(" ClientIP: %s\n", p_DetectedServer.getClientIP().data());
printf("\n");
#endif
ESP_LOGD(TAG, "SERVER DETECTED");
ESP_LOGD(TAG, " Name: %s", p_DetectedServer.getName().data());
ESP_LOGD(TAG, " ID: %s", p_DetectedServer.getID().data());
ESP_LOGD(TAG, " Computer: %s", p_DetectedServer.getComputerName().data());
ESP_LOGD(TAG, " IP: %s", p_DetectedServer.getIP().data());
ESP_LOGD(TAG, " Port: %s", p_DetectedServer.getPort().data());
ESP_LOGD(TAG, " Addition: %s", p_DetectedServer.getAdditions().data());
ESP_LOGD(TAG, " ClientIP: %s", p_DetectedServer.getClientIP().data());
bool boolSuccess;
bool boolSuccess = false;
//---------- RECONNECTION ----------
//If a connection has been established and the connection is lost -> reconnect
boolSuccess = false;
if (m_FlagReconnect == true) {
//check if the server is the same as prior connected
if (m_ServerID == p_DetectedServer.getID()) {
//reconnect
if (m_SPIT_Client != NULL) {
stopServerAutoDetect();
#if defined(DEBUGOUTPUT)
printf("MySPITApp: reconnect to %s ", p_DetectedServer.getIP().data());
#endif
ESP_LOGI(TAG,"reconnect to %s", p_DetectedServer.getIP().data());
boolSuccess = m_SPIT_Client->connect(p_DetectedServer.getIP(), p_DetectedServer.getPort(), p_DetectedServer.getClientIP(), "0"); //ClientPort = "0" meeans use any port
if (boolSuccess == true) {
return;
@@ -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
//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 != NULL) {
#if defined(DEBUGOUTPUT)
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
}
if (boolSuccess == false) {
//connection message could not be sent
//perhaps restart AutoDetection
startServerAutoDetect();
}
// } //Excample
if (p_DetectedServer.getIpIsLoopback() == true) { //omit the if condition if you want to use the first server found
return;
}
boolSuccess = false;
//Stop auto detection because a suitable server was found
stopServerAutoDetect();
if (m_SPIT_Client != NULL) {
ESP_LOGI(TAG,"connect to %s", p_DetectedServer.getIP().data());
boolSuccess = m_SPIT_Client->connect(p_DetectedServer.getIP(), p_DetectedServer.getPort(), p_DetectedServer.getClientIP(), "0"); //ClientPort = "0" meeans use any port
}
if (boolSuccess == false) {
//connection message could not be sent -> better to restart AutoDetection
startServerAutoDetect();
}
}
@@ -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>
*/
void MyApp::eventServerLost(const SAD_DetectedServer& p_DetectedServer) {
#if defined(DEBUGOUTPUT)
printf("\n");
printf("-----> SERVER LOST\n");
printf("Name: %s IP: %s\n", p_DetectedServer.getName().data(), p_DetectedServer.getIP().data());
printf("\n");
#endif
ESP_LOGW(TAG, "Server lost Name: %s IP: %s", p_DetectedServer.getName().data(), p_DetectedServer.getIP().data());
}
@@ -313,19 +189,13 @@ void MyApp::eventServerLost(const SAD_DetectedServer& p_DetectedServer) {
//---------- Connecting event ----------
void MyApp::eventConnectionStatus(string p_ServerID, string p_ServerComputerName, string p_ServerName, int p_ServerStepTime, int p_ConnectionStatus, int p_OldConnectionStatus) {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventConnectionStatus %d ", p_ConnectionStatus);
#endif
ESP_LOGD(TAG, "eventConnectionStatus %d ", p_ConnectionStatus);
switch(p_ConnectionStatus) {
case SPIT_Client::CONNECTION_NONE:
#if defined(DEBUGOUTPUT)
printf(" not connected\n");
#endif
ESP_LOGD(TAG, "not connected");
break;
case SPIT_Client::CONNECTION_NONESERVER:
#if defined(DEBUGOUTPUT)
printf(" connection terminated by server\n");
#endif
ESP_LOGD(TAG, "connection terminated by server");
//call eventProjectClosed because this may not be sended by the server,
//when the connstion is closed
eventProjectClosed(m_ServerProjectID);
@@ -335,9 +205,7 @@ void MyApp::eventConnectionStatus(string p_ServerID, string p_ServerComputerName
startServerAutoDetect();
break;
case SPIT_Client::CONNECTION_OK:
#if defined(DEBUGOUTPUT)
printf(" connection established\n");
#endif
ESP_LOGD(TAG, "connection established");
stopServerAutoDetect(); //normally you should stop the autodetection before you try a connection
//This is redundand
m_ServerID = p_ServerID;
@@ -350,9 +218,7 @@ void MyApp::eventConnectionStatus(string p_ServerID, string p_ServerComputerName
m_FlagReconnect = false;
break;
case SPIT_Client::CONNECTION_LOST:
#if defined(DEBUGOUTPUT)
printf(" connection lost\n");
#endif
ESP_LOGD(TAG, "connection lost");
//Maybe you want to reconnect, see eventServerDetected(...)
//We have lost the connection -> set the flag to true and start the autodetection to reconnect at eventServerDetected(...)
m_FlagReconnect = true;
@@ -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....
*/
void MyApp::eventProjectReport(string p_ProjectID, string p_ProjectName, int p_FramesPerSeoond) {
#if defined(DEBUGOUTPUT)
printf("\n");
printf("MySPITApp: eventProjectReport ID: %s Name: %s FramesPerSecond: %d\n", p_ProjectID.data(), p_ProjectName.data(), p_FramesPerSeoond);
#endif
ESP_LOGD(TAG, "eventProjectReport ID: %s Name: %s FramesPerSecond: %d", p_ProjectID.data(), p_ProjectName.data(), p_FramesPerSeoond);
m_ServerProjectID = p_ProjectID;
m_ServerProjectName = p_ProjectName;
m_ServerFramesPerSecond = p_FramesPerSeoond;
@@ -388,18 +251,15 @@ void MyApp::eventProjectReport(string p_ProjectID, string p_ProjectName, int p_F
m_ServerFramesPerSecond = p_FramesPerSeoond;
//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>
* @param p_ProjectID the id of the project<br>
* The server loads only one project at time-> the ID is not actually necessary
*/
void MyApp::eventProjectClosed(string p_ProjectID) {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventProjectClosed ID: %s\n", p_ProjectID.data());
printf("\n");
#endif
ESP_LOGD(TAG, "eventProjectClosed ID: %s", p_ProjectID.data());
//If we don't save SPITServer's project specific information
//perhaps close all SPITObjects and RemoteSPITObjects to avoid conflicts, when the SPITServer loads a new project
//SPITObject::clearSPITObjects();
@@ -413,23 +273,17 @@ void MyApp::eventProjectClosed(string p_ProjectID) {
* At the end eventEndProjectTransfer is called.
*/
void MyApp::eventStartProjectTransfer() {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventStartProjectTransfer\n");
#endif
ESP_LOGD(TAG, "eventStartProjectTransfer");
}
/**
* 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.
*/
void MyApp::eventEndProjectTransfer() {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventEndProjectTransfer\n");
#endif
ESP_LOGD(TAG, "eventEndProjectTransfer");
}
//----------------------------------------------------
//--------- SPITType events ----------
@@ -475,19 +329,13 @@ void MyApp::eventSPITType(bool p_New, const SPITType& p_SPITType) {
//fetch information of the SPITType
if (p_New) {
//a new SPITType is created
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITType NEW");
#endif
ESP_LOGD(TAG, "eventSPITType NEW");
}
else {
//an existing SPITType is changed
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITType CHANGED");
#endif
ESP_LOGD(TAG, "eventSPITType CHANGED");
}
#if defined(DEBUGOUTPUT)
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
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());
//Check your actions
//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) {
if (p_New) {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITTypeRemote NEW");
#endif
ESP_LOGD(TAG, "eventSPITTypeRemote NEW");
}
else {
//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);
}
}
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITTypeRemote CHANGED");
#endif
ESP_LOGD(TAG, "eventSPITTypeRemote CHANGED");
}
#if defined(DEBUGOUTPUT)
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
ESP_LOGD(TAG, "ID: %s GroupName: %s Name: %s confirmed: %d",
p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data(), p_SPITType.getConfirmed());
//this is a remote SPITType, if you want you can list this for later remote use.
}
@@ -552,10 +395,8 @@ void MyApp::eventSPITTypeRemote(bool p_New, const SPITType& p_SPITType) {
* The reference is deleted after this function call!!
*/
void MyApp::eventSPITTypeRemoved(const SPITType& p_SPITType) {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITType Removed");
printf(" ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data());
#endif
ESP_LOGD(TAG, "eventSPITType Removed");
ESP_LOGD(TAG, " ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data());
//Check your actions
//take the removal of the SPITType over in your code
@@ -573,10 +414,8 @@ void MyApp::eventSPITTypeRemoved(const SPITType& p_SPITType) {
* The reference is deleted after this function call!!
*/
void MyApp::eventSPITTypeRemoteRemoved(const SPITType& p_SPITType) {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITTypeRemote Removed");
printf(" ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data());
#endif
ESP_LOGD(TAG, "eventSPITTypeRemote Removed");
ESP_LOGD(TAG, " ID: %s GroupName: %s Name: %s\n", p_SPITType.getID().data(), p_SPITType.getGroupName().data(), p_SPITType.getName().data());
//This is a remote SPITType
//If you have listet this prior you should remove it from the list
@@ -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) {
if (p_New) {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITObject NEW");
#endif
ESP_LOGD(TAG, "eventSPITObject NEW");
}
else {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITObject CHANGED");
#endif
ESP_LOGD(TAG, "eventSPITObject CHANGED");
}
#if defined(DEBUGOUTPUT)
printf(" ID: %s Name: %s -> SPITType: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data());
#endif
ESP_LOGD(TAG, " ID: %s Name: %s -> SPITType: %s", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data());
//check your actions
//Whenever you provide an action for this SPITObject take this over in your code.
@@ -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) {
if (p_New) {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITObjectRemote NEW");
#endif
ESP_LOGD(TAG, "eventSPITObjectRemote NEW");
}
else {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITObjectRemote CHANGED");
#endif
ESP_LOGD(TAG, "eventSPITObjectRemote CHANGED");
}
#if defined(DEBUGOUTPUT)
printf(" ID: %s Name: %s -> SPITType: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data());
#endif
ESP_LOGD(TAG, " ID: %s Name: %s -> SPITType: %s", p_SPITObject.getID().data(), p_SPITObject.getName().data(), p_SPITType.getName().data());
//This is a remote SPITObject which can be used to remote control the server.
//If you want you can list this for later use
@@ -689,11 +516,9 @@ void MyApp::eventSPITObjectRemote(bool p_New, const SPITType& p_SPITType, const
* The reference is deleted after this function call!!
*/
void MyApp::eventSPITObjectRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject) {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITObject Removed");
printf(" ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data());
#endif
ESP_LOGD(TAG, "eventSPITObject Removed");
ESP_LOGD(TAG, " ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data());
//Check your actions
//take the removal of the SPITObject over in your code
@@ -712,11 +537,9 @@ void MyApp::eventSPITObjectRemoved(const SPITType& p_SPITType, const SPITObject&
* The reference is deleted after this function call!!
*/
void MyApp::eventSPITObjectRemoteRemoved(const SPITType& p_SPITType, const SPITObject& p_SPITObject) {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventSPITObjectRemote Removed");
printf(" ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data());
#endif
ESP_LOGD(TAG, "eventSPITObjectRemote Removed");
ESP_LOGD(TAG, " ID: %s Name: %s\n", p_SPITObject.getID().data(), p_SPITObject.getName().data());
//This is a remote SPITObject
//If you have listet this prior you should remove it from the list
}
@@ -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.
void MyApp::eventPlay(string p_PlayerID, string p_PlayerName, char p_PlayerType, bool p_PlayerIsRunning, long long p_TimeFrames) {
#if defined(DEBUGOUTPUT)
printf("MySPITApp: eventPlay Player: %s Runs: %d Time: %lld\n", p_PlayerName.data(), p_PlayerIsRunning, p_TimeFrames);
#endif
ESP_LOGD(TAG, "eventPlay Player: %s Runs: %d Time: %lld", p_PlayerName.data(), p_PlayerIsRunning, p_TimeFrames);
switch(p_PlayerType) {
case SPIT_Client::PLAYERTYPE_MAIN:
@@ -786,11 +607,9 @@ 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
//We can get the second (pre played) position: p_PlayObject.getFrameInsidePrePosition();
#if defined(DEBUGOUTPUT)
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);
printf(" SPITType: %s SPITObject: %s Position: %lld Value: %f\n", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_PlayObject.getFrameInside(), doubleValue);
#endif
ESP_LOGD(TAG, "eventPlayObject Player: %s is running: %d Object Started: %d Stopped: %d", p_PlayObject.getPlayerName().data(), p_PlayObject.getPlayerIsRunning(), p_Started, p_Ended);
ESP_LOGD(TAG, " SPITType: %s SPITObject: %s Position: %lld Value: %f\n", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_PlayObject.getFrameInside(), doubleValue);
//check for your actions to do
//In our little excample decribed in loadClientProject:
@@ -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
//we can get some information about the play status
if (p_Started == true) {
#if defined(DEBUGOUTPUT)
printf("MyApp AKTION 1 started Value: %f and running: %d\n", doubleValue, boolPLayerIsRunning);
#endif
ESP_LOGD(TAG, "MyApp AKTION 1 started Value: %f and running: %d", doubleValue, boolPLayerIsRunning);
}
else if (p_Ended == true) {
#if defined(DEBUGOUTPUT)
printf("MyApp AKTION 1 ended\n"); //p_PlayObject.getFrameInside() is -1
#endif
ESP_LOGD(TAG, "MyApp AKTION 1 ended"); //p_PlayObject.getFrameInside() is -1
}
else {
#if defined(DEBUGOUTPUT)
printf("MyApp AKTION 1 is played Value: %f and running: %d\n", doubleValue, boolPLayerIsRunning);
#endif
ESP_LOGD(TAG, "MyApp AKTION 1 is played Value: %f and running: %d", doubleValue, boolPLayerIsRunning);
}
}
else if (p_SPITType.getID() == "MySPITAPP_Action2ID") { //do Action 2
if (p_Started == true) {
#if defined(DEBUGOUTPUT)
printf("MyApp AKTION 2 started Value: %f and running: %d\n", doubleValue, boolPLayerIsRunning);
#endif
ESP_LOGD(TAG, "AKTION 2 started Value: %f and running: %d", doubleValue, boolPLayerIsRunning);
}
else if (p_Ended == true) {
#if defined(DEBUGOUTPUT)
printf("MyApp AKTION 2 ended\n"); //p_PlayObject.getFrameInside() is -1
#endif
ESP_LOGD(TAG, "AKTION 2 ended"); //p_PlayObject.getFrameInside() is -1
}
else {
#if defined(DEBUGOUTPUT)
printf("MyApp AKTION 2 is played Value: %f and running: %d\n", doubleValue, boolPLayerIsRunning);
#endif
ESP_LOGD(TAG, "AKTION 2 is played Value: %f and running: %d", doubleValue, boolPLayerIsRunning);
}
}
}
@@ -851,9 +658,7 @@ void MyApp::eventPlayObject(string p_PlayerID, bool p_Started, bool p_Ended, con
* @param p_Value the new value
*/
void MyApp::eventPlayRemoteObjectStatus(const SPITType& p_SPITType, const SPITObject& p_SPITObject, long long p_FrameInsideObject, int p_Value) {
#if defined(DEBUGOUTPUT)
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
ESP_LOGD(TAG, "eventPlayRemoteObjectStatus RemoteSPITType: %s RemoteSPITObject: %s Position: %lld Value: %d", p_SPITType.getName().data(), p_SPITObject.getName().data(), p_FrameInsideObject, p_Value);
}
/**
+7 -4
View File
@@ -1636,13 +1636,16 @@ const char* SPIT_Message::getMessageBytes() {
//---------------------------- static helper functions -----------------------
bool SPIT_Message::isSystemLittleEndian() {
// todo replace with #include <bit> then if constexpr (std::endian::native == std::endian::big)
int intOne = 1;
char* firstByte;
firstByte = (char*)&intOne;
// firstByte = intOne & 0xff000000;
if (firstByte > 0) return false;
else return true;
}
if (*firstByte > 0) {
return false;
}
return true;
}
int SPIT_Message::getInt(char* p_Bytes, int p_ByteCount, int p_Offset) {
if (p_Offset < 0) throw "ParseError_received";
if (p_Bytes == NULL || p_ByteCount < p_Offset + 4) throw "ParseError_received";
+22 -74
View File
@@ -16,10 +16,12 @@
#include "_SPITMACROS.h"
#if defined(OS_MAC) || defined(OS_LINUX)
#include "UnixSocket.h"
// #include <ifaddrs.h>
#include <thread>
#include "esp_netif.h"
#include "esp_log.h"
UnixSocket::UnixSocket() : SPITSocket(){
SPITSocket::FAMILY_IP4 = AF_INET;
@@ -63,7 +65,7 @@ int UnixSocket::cleanUp() {
*/
bool UnixSocket::createSocket_UDP() {
bool boolSuccess = true;
int intResult;
int intResult = -1;
int intOptionValue4 = 1;
int intOptionValue6 = 1;
u_char charOptionValue = 0x01;
@@ -145,12 +147,7 @@ int UnixSocket::bindSocket(string p_ClientIP, string p_ClientPort) {
memset(&o_IP4SocketAddress, 0, intSocklen);
o_IP4SocketAddress.sin_addr = ptrIP4SocketAddress->sin_addr;
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;
#endif
//o_IP4SocketAddress.sin_zero = ptrIP4SocketAddress->sin_zero;
o_IP4SocketAddress.sin_port = ptrIP4SocketAddress->sin_port;
intResult = bind(m_UDPSocketIP4, (const sockaddr*)(ptrIP4SocketAddress),(socklen_t)intSocklen);
if (intResult < 0) {
@@ -360,71 +357,22 @@ string UnixSocket::getBroadcastIP4(SPITSocket::IPAddress* p_IPAddress) {
}
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();
if (getifaddrs(&ifaddr) == -1) {
printf("UnixSocket::getAdaptersInfo getifaddrs < 0\n");
return;
// iterate over active interfaces, and print out IPs
esp_netif_t *netif = NULL;
while ((netif = esp_netif_next_unsafe(netif)) != NULL) {
ESP_LOGI("SPIT", "Connected to %s", esp_netif_get_desc(netif));
esp_netif_ip_info_t ip;
ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip));
ESP_LOGI("SPIT", "- IPv4 address: " IPSTR ",", IP2STR(&ip.ip));
ESP_LOGI("SPIT", "- IPv4 netmask: " IPSTR ",", IP2STR(&ip.netmask));
char buffer[64];
sprintf(buffer, IPSTR, IP2STR(&ip.ip));
string stringIP4 = buffer;
sprintf(buffer, IPSTR, IP2STR(&ip.netmask));
string stringSubnet = buffer;
addIPAddress(stringIP4, stringSubnet);
}
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);
}
//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();
}
#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
+18 -28
View File
@@ -5,41 +5,31 @@
*/
#include "_SPITMACROS.h"
#include "esp/uuid.h"
#include "esp_netif.h"
string createGUID() {
#if defined(OS_WINDOWS)
GUID o_GUID;
CoCreateGuid(&o_GUID);
char guid_string[37]; // 32 hex chars + 4 hyphens + null terminator
snprintf(
guid_string, sizeof(guid_string) / sizeof(guid_string[0]),
"%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 id;
// uuid_generate(id);
// char *guid_string = new char[100];
// uuid_unparse(id, guid_string);
// string stringGUID = guid_string;
// return stringGUID;
uuid_t uu;
char uu_str[UUID_STR_LEN];
#if defined(OS_MAC) || defined(OS_LINUX)
uuid_t id;
uuid_generate(id);
char *guid_string = new char[100];
uuid_unparse(id, guid_string);
string stringGUID = guid_string;
return stringGUID;
#endif
uuid_generate(uu);
uuid_unparse(uu, uu_str);
string stringGUID = uu_str;
return stringGUID;
}
/** The name of the client's host computer*/
string getClientHostName() {
string stringHostName;
char hostname[255];
if (gethostname(hostname, 255) != 0) {
stringHostName = "";
}
else {
string stringHostName = "";
const char * hostname;
esp_netif_get_hostname(esp_netif_get_default_netif(), &hostname);
if (hostname != nullptr) {
stringHostName = hostname;
}
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