feature: Add SPIT-Source as is

This commit is contained in:
2024-08-19 03:29:37 +02:00
parent a5805aceb2
commit 500641a6e2
31 changed files with 10176 additions and 0 deletions
+328
View File
@@ -0,0 +1,328 @@
/*
* 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.
*/
/*
* SAD_Client is used for ServerAutoDetection (SAD).
*
* File: ServerAutoDetetc_Client.cpp
* Author: Hagi
*
* Created on 16. April 2019, 08:57
*/
#include "SAD_Client.h"
//----- initialze static members -----
bool SAD_Client::s_StopSAD = true;
mutex SAD_Client::s_MutexSAD;
condition_variable SAD_Client::s_ConditionStopSAD;
thread* SAD_Client::s_ThreadSend = NULL;
thread* SAD_Client::s_ThreadReceiveIP4 = NULL;
thread* SAD_Client::s_ThreadReceiveIP6 = NULL;
recursive_mutex SAD_Client::s_MutexClientInterface;
SAD_ClientInterface* SAD_Client::s_SADClientInterface = NULL;
recursive_mutex SAD_Client::s_MutexSocket;
SPITSocket* SAD_Client::s_SPITSocket = NULL;
void SAD_Client::startAutoDetectServer(SAD_ClientInterface* p_SADClientInterface, SPITSocket* p_SpitSocket) {
if (p_SADClientInterface == NULL) return;
if (p_SpitSocket == NULL) return;
{
unique_lock<recursive_mutex> o_LockClient(s_MutexClientInterface);
s_SADClientInterface = p_SADClientInterface;
}
{
unique_lock<mutex> o_UniqueLock(s_MutexSAD);
if (s_StopSAD == false) return;
s_StopSAD = false;
SAD_DetectedServer::clearDetectedServers();
}
s_SPITSocket = p_SpitSocket;
s_ThreadSend = new thread(&SAD_Client::sendAutoDetectServer);
s_ThreadReceiveIP4 = new thread(&SAD_Client::receiveAutoDetectServer_IP4);
s_ThreadReceiveIP6 = new thread(&SAD_Client::receiveAutoDetectServer_IP6);
}
void SAD_Client::stopAutoDetectServer(SAD_ClientInterface* p_SADClientInterface) {
bool boolStopDetection = false;
{
unique_lock<recursive_mutex> o_LockClient(s_MutexClientInterface);
if (s_SADClientInterface != p_SADClientInterface) {
return;
}
}
{
unique_lock<mutex> o_UniqueLock(s_MutexSAD);
if (s_StopSAD == true) return;
s_StopSAD = true;
}
s_ConditionStopSAD.notify_one();
if (s_ThreadSend != NULL) {
if (this_thread::get_id() != s_ThreadSend->get_id()) {
if (s_ThreadSend->joinable()) {
s_ThreadSend->join();
}
}
s_ThreadSend = NULL;
}
//wait for receiving threads
if (s_ThreadReceiveIP4 != NULL) {
if (this_thread::get_id() != s_ThreadReceiveIP4->get_id()) {
if (s_ThreadReceiveIP4->joinable()) {
s_ThreadReceiveIP4->join();
}
}
s_ThreadReceiveIP4 = NULL;
}
if (s_ThreadReceiveIP6 != NULL) {
if (this_thread::get_id() != s_ThreadReceiveIP6->get_id()) {
if (s_ThreadReceiveIP6->joinable()) {
s_ThreadReceiveIP6->join();
}
}
s_ThreadReceiveIP6 = NULL;
}
{
unique_lock<recursive_mutex> o_LockSocket(s_MutexSocket);
if (s_SPITSocket != NULL) {
delete s_SPITSocket;
s_SPITSocket = NULL;
}
}
{
unique_lock<mutex> o_UniqueLock(s_MutexSAD);
SAD_DetectedServer::clearDetectedServers();
}
}
void SAD_Client::sendAutoDetectServer() {
SPITSocket::IPAddress* o_IPAddress;
string stringBroadcastIP4;
string stringBroadcastIP6;
string stringBroadcastIP6_loopback;
string stringDatagram;
int intDatagramLength;
bool boolDone;
stringDatagram = SERVERAUTODETECT_PRECODE;
stringDatagram.append(SERVERAUTODETECT_SEPERATOR);
stringDatagram.append(SERVERAUTODETECT_TASKID);
intDatagramLength = stringDatagram.length();
stringBroadcastIP6 = "ff02::1";
stringBroadcastIP6_loopback = "::1";
while(s_StopSAD == false) {
//---- IP4 ---
cycleStart();
{
unique_lock<recursive_mutex> o_LockSocket(s_MutexSocket);
if (s_SPITSocket == NULL) {
return;
}
s_SPITSocket->getAdaptersInfo();
for (int i = 0; i < SPITSocket::getIPAddressCount(); i++) {
o_IPAddress = SPITSocket::getIPAddress(i);
if (o_IPAddress == NULL) break;
stringBroadcastIP4 = s_SPITSocket->getBroadcastIP4(o_IPAddress);
if (s_SPITSocket->sendMessageTo(SPITSocket::FAMILY_IP4, stringBroadcastIP4, SERVERAUTODETECT_PORT, stringDatagram.data(), intDatagramLength) < 0) {
}
else {
}
}
//---- IP6 --- send to "ff02::1" and to the loopback address "::1" because MAC OSX seems to to need the loopback over IP6
//"ff02::1"
if (s_SPITSocket->sendMessageTo(SPITSocket::FAMILY_IP6, stringBroadcastIP6, SERVERAUTODETECT_PORT, stringDatagram.data(), stringDatagram.length()) < 0) {
}
else {
}
//"::1" loopback
if (s_SPITSocket->sendMessageTo(SPITSocket::FAMILY_IP6, stringBroadcastIP6_loopback, SERVERAUTODETECT_PORT, stringDatagram.data(), stringDatagram.length()) < 0) {
}
else {
}
}
{
if (s_StopSAD == true) {
return;
}
//wait for 3000 milliseconds or
//s_StopAutoDetectServer == true see stopAutoDetectServer
unique_lock<mutex> o_LockWait(s_MutexSAD);
boolDone = s_ConditionStopSAD.wait_for(o_LockWait, chrono::milliseconds(3000),[]{return s_StopSAD;});
if (s_StopSAD == true) {
return;
}
}
cycleEnd();
}
int intTest = 0;
}
void SAD_Client::receiveAutoDetectServer_IP4() {
char buffer[512+1];
int intReceivedByteCount;
string stringMessage;
string stringServerIP;
int intIndex = 0;
int intPos = 0;
int intOldPos = 0;
string stringPart;
string stringParts[9];
//sendAutoDetectServer will bind the socket to a port
//wait a while to be sendAutoDetectServer first
this_thread::sleep_for(chrono::milliseconds(500));
while (s_StopSAD == false) {
{
unique_lock<recursive_mutex> o_LockIP4(s_MutexSocket);
if (s_SPITSocket == NULL) {
return;
}
}
intReceivedByteCount = s_SPITSocket->receiveMessage(SPITSocket::FAMILY_IP4, buffer, 512, &stringServerIP);
if (intReceivedByteCount <= 0) {
if (s_StopSAD == false) {
//To reduce the processor load if a socket error occurs, we let the thread sleep a bit.
this_thread::sleep_for(chrono::milliseconds(100));
}
continue;
}
if (s_StopSAD == true) {
return;
}
//add null chararcter
if (intReceivedByteCount < 512) {
buffer[intReceivedByteCount] = '\0';
}
else {
buffer[512] = '\0';
}
stringMessage = buffer;
//Check if precode is ok
if (stringMessage.find(SERVERAUTODETECT_PRECODE.data(),0) != 0) {
return;
}
intIndex = 0;
intPos = 0;
intOldPos = 0;
while(intIndex < 8) {
intPos = stringMessage.find(SERVERAUTODETECT_SEPERATOR.data(),intOldPos);
if (intPos == string::npos) {
stringPart = "";
}
else {
stringPart = stringMessage.substr(intOldPos, intPos-intOldPos);
intOldPos = intPos + SERVERAUTODETECT_SEPERATOR.length();
}
stringParts[intIndex] = stringPart;
intIndex++;
}
stringParts[8] = stringServerIP;
SAD_DetectedServer::addDetectedServer(true, stringParts[SAD_DetectedServer::PARAMINDEX_ID], stringParts);
}
int inTest = 0;
}
void SAD_Client::receiveAutoDetectServer_IP6() {
char buffer[512+1];
int intReceivedByteCount;
string stringMessage;
string stringServerIP;
int intIndex = 0;
int intPos = 0;
int intOldPos = 0;
string stringPart;
string stringParts[9];
//sendto will bind the socket to a port
//wait a while to be sendto first
this_thread::sleep_for(chrono::milliseconds(500));
while (s_StopSAD == false) {
{
unique_lock<recursive_mutex> o_LockIP6(s_MutexSocket);
if (s_SPITSocket == NULL) {
return;
}
}
intReceivedByteCount = s_SPITSocket->receiveMessage(SPITSocket::FAMILY_IP6, buffer, 512, &stringServerIP);
if (intReceivedByteCount <= 0) {
if (s_StopSAD == false) {
//To reduce the processor load if a socket error occurs, we let the thread sleep a bit.
this_thread::sleep_for(chrono::milliseconds(100));
}
continue;
}
if (s_StopSAD == true) {
return;
}
//add null chararcter
if (intReceivedByteCount < 512) {
buffer[intReceivedByteCount] = '\0';
}
else {
buffer[512] = '\0';
}
stringMessage = buffer;
//Check if precode is ok
if (stringMessage.find(SERVERAUTODETECT_PRECODE.data(),0) != 0) {
return;
}
intIndex = 0;
intPos = 0;
intOldPos = 0;
while(intIndex < 8) {
intPos = stringMessage.find(SERVERAUTODETECT_SEPERATOR.data(),intOldPos);
if (intPos == string::npos) {
stringPart = "";
}
else {
stringPart = stringMessage.substr(intOldPos, intPos-intOldPos);
intOldPos = intPos + SERVERAUTODETECT_SEPERATOR.length();
}
stringParts[intIndex] = stringPart;
intIndex++;
}
stringParts[8] = stringServerIP;
SAD_DetectedServer::addDetectedServer(false, stringParts[SAD_DetectedServer::PARAMINDEX_ID], stringParts);
}
int inTest = 0;
}
void SAD_Client::cycleStart() {
{
unique_lock<mutex> o_UniqueLock(s_MutexSAD);
if (s_StopSAD == true) return;
}
// printf("SAD CYCLE START\n");
SAD_DetectedServer::cycleStart();
}
void SAD_Client::cycleEnd() {
{
unique_lock<mutex> o_UniqueLock(s_MutexSAD);
if (s_StopSAD == true) return;
}
SAD_DetectedServer::cycleEnd(s_SADClientInterface);
// printf("SAD CYCLE END\n");
}