feature: Add SPIT-Source as is
This commit is contained in:
@@ -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");
|
||||
}
|
||||
Reference in New Issue
Block a user