mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 05:52:38 +02:00
get rid of arpa/inet.h and netdb.h
This commit is contained in:
parent
9bc4a3df41
commit
5725a92cfe
6 changed files with 227 additions and 225 deletions
|
@ -6,7 +6,7 @@
|
|||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <arpa/inet.h>
|
||||
//#include <arpa/inet.h> // not available on windows, apparently not needed on mac
|
||||
#include <signal.h>
|
||||
|
||||
#include <QtCore/QJsonDocument>
|
||||
|
@ -41,86 +41,86 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
|||
_hasCompletedRestartHold(false)
|
||||
{
|
||||
DomainServer::setDomainServerInstance(this);
|
||||
|
||||
|
||||
signal(SIGINT, signalhandler);
|
||||
|
||||
|
||||
const char CUSTOM_PORT_OPTION[] = "-p";
|
||||
const char* customPortString = getCmdOption(argc, (const char**) argv, CUSTOM_PORT_OPTION);
|
||||
unsigned short domainServerPort = customPortString ? atoi(customPortString) : DEFAULT_DOMAIN_SERVER_PORT;
|
||||
|
||||
|
||||
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_DOMAIN, domainServerPort);
|
||||
|
||||
|
||||
const char VOXEL_CONFIG_OPTION[] = "--voxelServerConfig";
|
||||
_voxelServerConfig = getCmdOption(argc, (const char**) argv, VOXEL_CONFIG_OPTION);
|
||||
|
||||
const char PARTICLE_CONFIG_OPTION[] = "--particleServerConfig";
|
||||
_particleServerConfig = getCmdOption(argc, (const char**) argv, PARTICLE_CONFIG_OPTION);
|
||||
|
||||
|
||||
const char METAVOXEL_CONFIG_OPTION[] = "--metavoxelServerConfig";
|
||||
_metavoxelServerConfig = getCmdOption(argc, (const char**)argv, METAVOXEL_CONFIG_OPTION);
|
||||
|
||||
|
||||
// setup the mongoose web server
|
||||
struct mg_callbacks callbacks = {};
|
||||
|
||||
|
||||
QString documentRootString = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath());
|
||||
|
||||
|
||||
char documentRoot[documentRootString.size() + 1];
|
||||
strcpy(documentRoot, documentRootString.toLocal8Bit().constData());
|
||||
|
||||
|
||||
// list of options. Last element must be NULL.
|
||||
const char* options[] = {"listening_ports", "8080",
|
||||
"document_root", documentRoot, NULL};
|
||||
|
||||
|
||||
callbacks.begin_request = civetwebRequestHandler;
|
||||
callbacks.upload = civetwebUploadHandler;
|
||||
|
||||
|
||||
// Start the web server.
|
||||
mg_start(&callbacks, NULL, options);
|
||||
|
||||
|
||||
nodeList->addHook(this);
|
||||
|
||||
|
||||
if (!_staticAssignmentFile.exists() || _voxelServerConfig) {
|
||||
|
||||
|
||||
if (_voxelServerConfig) {
|
||||
// we have a new VS config, clear the existing file to start fresh
|
||||
_staticAssignmentFile.remove();
|
||||
}
|
||||
|
||||
|
||||
prepopulateStaticAssignmentFile();
|
||||
}
|
||||
|
||||
|
||||
_staticAssignmentFile.open(QIODevice::ReadWrite);
|
||||
|
||||
|
||||
_staticAssignmentFileData = _staticAssignmentFile.map(0, _staticAssignmentFile.size());
|
||||
|
||||
|
||||
_staticAssignments = (Assignment*) _staticAssignmentFileData;
|
||||
|
||||
|
||||
QTimer* silentNodeTimer = new QTimer(this);
|
||||
connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes()));
|
||||
silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000);
|
||||
|
||||
|
||||
connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), SLOT(readAvailableDatagrams()));
|
||||
|
||||
|
||||
// fire a single shot timer to add static assignments back into the queue after a restart
|
||||
QTimer::singleShot(RESTART_HOLD_TIME_MSECS, this, SLOT(addStaticAssignmentsBackToQueueAfterRestart()));
|
||||
|
||||
|
||||
connect(this, SIGNAL(aboutToQuit()), SLOT(cleanup()));
|
||||
}
|
||||
|
||||
void DomainServer::readAvailableDatagrams() {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
|
||||
HifiSockAddr senderSockAddr, nodePublicAddress, nodeLocalAddress;
|
||||
|
||||
|
||||
static unsigned char packetData[MAX_PACKET_SIZE];
|
||||
|
||||
|
||||
static unsigned char broadcastPacket[MAX_PACKET_SIZE];
|
||||
|
||||
|
||||
static unsigned char* currentBufferPos;
|
||||
static unsigned char* startPointer;
|
||||
|
||||
|
||||
int receivedBytes = 0;
|
||||
|
||||
|
||||
while (nodeList->getNodeSocket().hasPendingDatagrams()) {
|
||||
if ((receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
|
||||
senderSockAddr.getAddressPointer(),
|
||||
|
@ -128,22 +128,22 @@ void DomainServer::readAvailableDatagrams() {
|
|||
&& packetVersionMatch((unsigned char*) packetData)) {
|
||||
if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) {
|
||||
// this is an RFD or domain list request packet, and there is a version match
|
||||
|
||||
|
||||
int numBytesSenderHeader = numBytesForPacketHeader((unsigned char*) packetData);
|
||||
|
||||
|
||||
NODE_TYPE nodeType = *(packetData + numBytesSenderHeader);
|
||||
|
||||
|
||||
int packetIndex = numBytesSenderHeader + sizeof(NODE_TYPE);
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray(((char*) packetData + packetIndex), NUM_BYTES_RFC4122_UUID));
|
||||
packetIndex += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
|
||||
int numBytesPrivateSocket = HifiSockAddr::unpackSockAddr(packetData + packetIndex, nodePublicAddress);
|
||||
packetIndex += numBytesPrivateSocket;
|
||||
|
||||
|
||||
if (nodePublicAddress.getAddress().isNull()) {
|
||||
// this node wants to use us its STUN server
|
||||
// so set the node public address to whatever we perceive the public address to be
|
||||
|
||||
|
||||
// if the sender is on our box then leave its public address to 0 so that
|
||||
// other users attempt to reach it on the same address they have for the domain-server
|
||||
if (senderSockAddr.getAddress().isLoopback()) {
|
||||
|
@ -152,19 +152,19 @@ void DomainServer::readAvailableDatagrams() {
|
|||
nodePublicAddress.setAddress(senderSockAddr.getAddress());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int numBytesPublicSocket = HifiSockAddr::unpackSockAddr(packetData + packetIndex, nodeLocalAddress);
|
||||
packetIndex += numBytesPublicSocket;
|
||||
|
||||
|
||||
const char STATICALLY_ASSIGNED_NODES[] = {
|
||||
NODE_TYPE_AUDIO_MIXER,
|
||||
NODE_TYPE_AVATAR_MIXER,
|
||||
NODE_TYPE_VOXEL_SERVER,
|
||||
NODE_TYPE_METAVOXEL_SERVER
|
||||
};
|
||||
|
||||
|
||||
Assignment* matchingStaticAssignment = NULL;
|
||||
|
||||
|
||||
if (memchr(STATICALLY_ASSIGNED_NODES, nodeType, sizeof(STATICALLY_ASSIGNED_NODES)) == NULL
|
||||
|| ((matchingStaticAssignment = matchingStaticAssignmentForCheckIn(nodeUUID, nodeType))
|
||||
|| checkInWithUUIDMatchesExistingNode(nodePublicAddress,
|
||||
|
@ -175,79 +175,79 @@ void DomainServer::readAvailableDatagrams() {
|
|||
nodeType,
|
||||
nodePublicAddress,
|
||||
nodeLocalAddress);
|
||||
|
||||
|
||||
if (matchingStaticAssignment) {
|
||||
// this was a newly added node with a matching static assignment
|
||||
|
||||
|
||||
if (_hasCompletedRestartHold) {
|
||||
// remove the matching assignment from the assignment queue so we don't take the next check in
|
||||
removeAssignmentFromQueue(matchingStaticAssignment);
|
||||
}
|
||||
|
||||
|
||||
// set the linked data for this node to a copy of the matching assignment
|
||||
// so we can re-queue it should the node die
|
||||
Assignment* nodeCopyOfMatchingAssignment = new Assignment(*matchingStaticAssignment);
|
||||
|
||||
|
||||
checkInNode->setLinkedData(nodeCopyOfMatchingAssignment);
|
||||
}
|
||||
|
||||
|
||||
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN);
|
||||
|
||||
|
||||
currentBufferPos = broadcastPacket + numHeaderBytes;
|
||||
startPointer = currentBufferPos;
|
||||
|
||||
|
||||
unsigned char* nodeTypesOfInterest = packetData + packetIndex + sizeof(unsigned char);
|
||||
int numInterestTypes = *(nodeTypesOfInterest - 1);
|
||||
|
||||
|
||||
if (numInterestTypes > 0) {
|
||||
// if the node has sent no types of interest, assume they want nothing but their own ID back
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getUUID() != nodeUUID &&
|
||||
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
|
||||
|
||||
|
||||
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
||||
if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
|
||||
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, &(*node));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update last receive to now
|
||||
uint64_t timeNow = usecTimestampNow();
|
||||
checkInNode->setLastHeardMicrostamp(timeNow);
|
||||
|
||||
|
||||
// send the constructed list back to this node
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket,
|
||||
(currentBufferPos - startPointer) + numHeaderBytes,
|
||||
senderSockAddr.getAddress(), senderSockAddr.getPort());
|
||||
}
|
||||
} else if (packetData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
||||
|
||||
|
||||
if (_assignmentQueue.size() > 0) {
|
||||
// construct the requested assignment from the packet data
|
||||
Assignment requestAssignment(packetData, receivedBytes);
|
||||
|
||||
|
||||
qDebug("Received a request for assignment type %i from %s.\n", requestAssignment.getType(), qPrintable(senderSockAddr.getAddress().toString()));
|
||||
|
||||
|
||||
Assignment* assignmentToDeploy = deployableAssignmentForRequest(requestAssignment);
|
||||
|
||||
|
||||
if (assignmentToDeploy) {
|
||||
|
||||
|
||||
// give this assignment out, either the type matches or the requestor said they will take any
|
||||
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_CREATE_ASSIGNMENT);
|
||||
int numAssignmentBytes = assignmentToDeploy->packToBuffer(broadcastPacket + numHeaderBytes);
|
||||
|
||||
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, numHeaderBytes + numAssignmentBytes,
|
||||
senderSockAddr.getAddress(), senderSockAddr.getPort());
|
||||
|
||||
|
||||
if (assignmentToDeploy->getNumberOfInstances() == 0) {
|
||||
// there are no more instances of this script to send out, delete it
|
||||
delete assignmentToDeploy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
qDebug("Received an invalid assignment request from %s.\n", qPrintable(senderSockAddr.getAddress().toString()));
|
||||
}
|
||||
|
@ -262,10 +262,10 @@ void DomainServer::setDomainServerInstance(DomainServer* domainServer) {
|
|||
|
||||
QJsonObject jsonForSocket(const HifiSockAddr& socket) {
|
||||
QJsonObject socketJSON;
|
||||
|
||||
|
||||
socketJSON["ip"] = socket.getAddress().toString();
|
||||
socketJSON["port"] = ntohs(socket.getPort());
|
||||
|
||||
|
||||
return socketJSON;
|
||||
}
|
||||
|
||||
|
@ -281,14 +281,14 @@ QJsonObject jsonObjectForNode(Node* node) {
|
|||
QString nodeTypeName(node->getTypeName());
|
||||
nodeTypeName = nodeTypeName.toLower();
|
||||
nodeTypeName.replace(' ', '-');
|
||||
|
||||
|
||||
// add the node type
|
||||
nodeJson[JSON_KEY_TYPE] = nodeTypeName;
|
||||
|
||||
|
||||
// add the node socket information
|
||||
nodeJson[JSON_KEY_PUBLIC_SOCKET] = jsonForSocket(node->getPublicSocket());
|
||||
nodeJson[JSON_KEY_LOCAL_SOCKET] = jsonForSocket(node->getLocalSocket());
|
||||
|
||||
|
||||
// if the node has pool information, add it
|
||||
if (node->getLinkedData() && ((Assignment*) node->getLinkedData())->hasPool()) {
|
||||
nodeJson[JSON_KEY_POOL] = QString(((Assignment*) node->getLinkedData())->getPool());
|
||||
|
@ -299,27 +299,27 @@ QJsonObject jsonObjectForNode(Node* node) {
|
|||
|
||||
int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
||||
const struct mg_request_info* ri = mg_get_request_info(connection);
|
||||
|
||||
|
||||
const char RESPONSE_200[] = "HTTP/1.0 200 OK\r\n\r\n";
|
||||
const char RESPONSE_400[] = "HTTP/1.0 400 Bad Request\r\n\r\n";
|
||||
|
||||
|
||||
const char URI_ASSIGNMENT[] = "/assignment";
|
||||
const char URI_NODE[] = "/node";
|
||||
|
||||
|
||||
if (strcmp(ri->request_method, "GET") == 0) {
|
||||
if (strcmp(ri->uri, "/assignments.json") == 0) {
|
||||
// user is asking for json list of assignments
|
||||
|
||||
|
||||
// start with a 200 response
|
||||
mg_printf(connection, "%s", RESPONSE_200);
|
||||
|
||||
|
||||
// setup the JSON
|
||||
QJsonObject assignmentJSON;
|
||||
QJsonObject assignedNodesJSON;
|
||||
|
||||
|
||||
// enumerate the NodeList to find the assigned nodes
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getLinkedData()) {
|
||||
// add the node using the UUID as the key
|
||||
|
@ -327,67 +327,67 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
|||
assignedNodesJSON[uuidString] = jsonObjectForNode(&(*node));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
assignmentJSON["fulfilled"] = assignedNodesJSON;
|
||||
|
||||
|
||||
QJsonObject queuedAssignmentsJSON;
|
||||
|
||||
|
||||
// add the queued but unfilled assignments to the json
|
||||
std::deque<Assignment*>::iterator assignment = domainServerInstance->_assignmentQueue.begin();
|
||||
|
||||
|
||||
while (assignment != domainServerInstance->_assignmentQueue.end()) {
|
||||
QJsonObject queuedAssignmentJSON;
|
||||
|
||||
|
||||
QString uuidString = uuidStringWithoutCurlyBraces((*assignment)->getUUID());
|
||||
queuedAssignmentJSON[JSON_KEY_TYPE] = QString((*assignment)->getTypeName());
|
||||
|
||||
|
||||
// if the assignment has a pool, add it
|
||||
if ((*assignment)->hasPool()) {
|
||||
queuedAssignmentJSON[JSON_KEY_POOL] = QString((*assignment)->getPool());
|
||||
}
|
||||
|
||||
|
||||
// add this queued assignment to the JSON
|
||||
queuedAssignmentsJSON[uuidString] = queuedAssignmentJSON;
|
||||
|
||||
|
||||
// push forward the iterator to check the next assignment
|
||||
assignment++;
|
||||
}
|
||||
|
||||
|
||||
assignmentJSON["queued"] = queuedAssignmentsJSON;
|
||||
|
||||
|
||||
// print out the created JSON
|
||||
QJsonDocument assignmentDocument(assignmentJSON);
|
||||
mg_printf(connection, "%s", assignmentDocument.toJson().constData());
|
||||
|
||||
|
||||
// we've processed this request
|
||||
return 1;
|
||||
} else if (strcmp(ri->uri, "/nodes.json") == 0) {
|
||||
// start with a 200 response
|
||||
mg_printf(connection, "%s", RESPONSE_200);
|
||||
|
||||
|
||||
// setup the JSON
|
||||
QJsonObject rootJSON;
|
||||
QJsonObject nodesJSON;
|
||||
|
||||
|
||||
// enumerate the NodeList to find the assigned nodes
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
// add the node using the UUID as the key
|
||||
QString uuidString = uuidStringWithoutCurlyBraces(node->getUUID());
|
||||
nodesJSON[uuidString] = jsonObjectForNode(&(*node));
|
||||
}
|
||||
|
||||
|
||||
rootJSON["nodes"] = nodesJSON;
|
||||
|
||||
|
||||
// print out the created JSON
|
||||
QJsonDocument nodesDocument(rootJSON);
|
||||
mg_printf(connection, "%s", nodesDocument.toJson().constData());
|
||||
|
||||
|
||||
// we've processed this request
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// not processed, pass to document root
|
||||
return 0;
|
||||
} else if (strcmp(ri->request_method, "POST") == 0) {
|
||||
|
@ -396,38 +396,38 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
|||
mg_printf(connection, "%s", RESPONSE_200);
|
||||
// upload the file
|
||||
mg_upload(connection, "/tmp");
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
} else if (strcmp(ri->request_method, "DELETE") == 0) {
|
||||
// this is a DELETE request
|
||||
|
||||
|
||||
// check if it is for an assignment
|
||||
if (memcmp(ri->uri, URI_NODE, strlen(URI_NODE)) == 0) {
|
||||
// pull the UUID from the url
|
||||
QUuid deleteUUID = QUuid(QString(ri->uri + strlen(URI_NODE) + sizeof('/')));
|
||||
|
||||
|
||||
if (!deleteUUID.isNull()) {
|
||||
Node *nodeToKill = NodeList::getInstance()->nodeWithUUID(deleteUUID);
|
||||
|
||||
|
||||
if (nodeToKill) {
|
||||
// start with a 200 response
|
||||
mg_printf(connection, "%s", RESPONSE_200);
|
||||
|
||||
|
||||
// we have a valid UUID and node - kill the node that has this assignment
|
||||
NodeList::getInstance()->killNode(nodeToKill);
|
||||
|
||||
|
||||
// successfully processed request
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// request not processed - bad request
|
||||
mg_printf(connection, "%s", RESPONSE_400);
|
||||
|
||||
|
||||
// this was processed by civetweb
|
||||
return 1;
|
||||
} else {
|
||||
|
@ -439,33 +439,33 @@ int DomainServer::civetwebRequestHandler(struct mg_connection *connection) {
|
|||
const char ASSIGNMENT_SCRIPT_HOST_LOCATION[] = "resources/web/assignment";
|
||||
|
||||
void DomainServer::civetwebUploadHandler(struct mg_connection *connection, const char *path) {
|
||||
|
||||
|
||||
// create an assignment for this saved script, for now make it local only
|
||||
Assignment* scriptAssignment = new Assignment(Assignment::CreateCommand,
|
||||
Assignment::AgentType,
|
||||
NULL,
|
||||
Assignment::LocalLocation);
|
||||
|
||||
|
||||
// check how many instances of this assignment the user wants by checking the ASSIGNMENT-INSTANCES header
|
||||
const char ASSIGNMENT_INSTANCES_HTTP_HEADER[] = "ASSIGNMENT-INSTANCES";
|
||||
const char* requestInstancesHeader = mg_get_header(connection, ASSIGNMENT_INSTANCES_HTTP_HEADER);
|
||||
|
||||
|
||||
if (requestInstancesHeader) {
|
||||
// the user has requested a number of instances greater than 1
|
||||
// so set that on the created assignment
|
||||
scriptAssignment->setNumberOfInstances(atoi(requestInstancesHeader));
|
||||
}
|
||||
|
||||
|
||||
QString newPath(ASSIGNMENT_SCRIPT_HOST_LOCATION);
|
||||
newPath += "/";
|
||||
// append the UUID for this script as the new filename, remove the curly braces
|
||||
newPath += uuidStringWithoutCurlyBraces(scriptAssignment->getUUID());
|
||||
|
||||
|
||||
// rename the saved script to the GUID of the assignment and move it to the script host locaiton
|
||||
rename(path, newPath.toLocal8Bit().constData());
|
||||
|
||||
|
||||
qDebug("Saved a script for assignment at %s\n", newPath.toLocal8Bit().constData());
|
||||
|
||||
|
||||
// add the script assigment to the assignment queue
|
||||
// lock the assignment queue mutex since we're operating on a different thread than DS main
|
||||
domainServerInstance->_assignmentQueueMutex.lock();
|
||||
|
@ -475,18 +475,18 @@ void DomainServer::civetwebUploadHandler(struct mg_connection *connection, const
|
|||
|
||||
void DomainServer::addReleasedAssignmentBackToQueue(Assignment* releasedAssignment) {
|
||||
qDebug() << "Adding assignment" << *releasedAssignment << " back to queue.\n";
|
||||
|
||||
|
||||
// find this assignment in the static file
|
||||
for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) {
|
||||
if (_staticAssignments[i].getUUID() == releasedAssignment->getUUID()) {
|
||||
// reset the UUID on the static assignment
|
||||
_staticAssignments[i].resetUUID();
|
||||
|
||||
|
||||
// put this assignment back in the queue so it goes out
|
||||
_assignmentQueueMutex.lock();
|
||||
_assignmentQueue.push_back(&_staticAssignments[i]);
|
||||
_assignmentQueueMutex.unlock();
|
||||
|
||||
|
||||
} else if (_staticAssignments[i].getUUID().isNull()) {
|
||||
// we are at the blank part of the static assignments - break out
|
||||
break;
|
||||
|
@ -495,79 +495,79 @@ void DomainServer::addReleasedAssignmentBackToQueue(Assignment* releasedAssignme
|
|||
}
|
||||
|
||||
void DomainServer::nodeAdded(Node* node) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void DomainServer::nodeKilled(Node* node) {
|
||||
// if this node has linked data it was from an assignment
|
||||
if (node->getLinkedData()) {
|
||||
Assignment* nodeAssignment = (Assignment*) node->getLinkedData();
|
||||
|
||||
|
||||
addReleasedAssignmentBackToQueue(nodeAssignment);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char* DomainServer::addNodeToBroadcastPacket(unsigned char* currentPosition, Node* nodeToAdd) {
|
||||
*currentPosition++ = nodeToAdd->getType();
|
||||
|
||||
|
||||
|
||||
|
||||
QByteArray rfcUUID = nodeToAdd->getUUID().toRfc4122();
|
||||
memcpy(currentPosition, rfcUUID.constData(), rfcUUID.size());
|
||||
currentPosition += rfcUUID.size();
|
||||
|
||||
|
||||
currentPosition += HifiSockAddr::packSockAddr(currentPosition, nodeToAdd->getPublicSocket());
|
||||
currentPosition += HifiSockAddr::packSockAddr(currentPosition, nodeToAdd->getLocalSocket());
|
||||
|
||||
|
||||
// return the new unsigned char * for broadcast packet
|
||||
return currentPosition;
|
||||
}
|
||||
|
||||
void DomainServer::prepopulateStaticAssignmentFile() {
|
||||
int numFreshStaticAssignments = 0;
|
||||
|
||||
|
||||
// write a fresh static assignment array to file
|
||||
|
||||
|
||||
Assignment freshStaticAssignments[MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS];
|
||||
|
||||
|
||||
// pre-populate the first static assignment list with assignments for root AuM, AvM, VS
|
||||
freshStaticAssignments[numFreshStaticAssignments++] = Assignment(Assignment::CreateCommand, Assignment::AudioMixerType);
|
||||
freshStaticAssignments[numFreshStaticAssignments++] = Assignment(Assignment::CreateCommand, Assignment::AvatarMixerType);
|
||||
|
||||
|
||||
// Handle Domain/Voxel Server configuration command line arguments
|
||||
if (_voxelServerConfig) {
|
||||
qDebug("Reading Voxel Server Configuration.\n");
|
||||
qDebug() << "config: " << _voxelServerConfig << "\n";
|
||||
|
||||
|
||||
QString multiConfig((const char*) _voxelServerConfig);
|
||||
QStringList multiConfigList = multiConfig.split(";");
|
||||
|
||||
|
||||
// read each config to a payload for a VS assignment
|
||||
for (int i = 0; i < multiConfigList.size(); i++) {
|
||||
QString config = multiConfigList.at(i);
|
||||
|
||||
|
||||
qDebug("config[%d]=%s\n", i, config.toLocal8Bit().constData());
|
||||
|
||||
|
||||
// Now, parse the config to check for a pool
|
||||
const char ASSIGNMENT_CONFIG_POOL_OPTION[] = "--pool";
|
||||
QString assignmentPool;
|
||||
|
||||
|
||||
int poolIndex = config.indexOf(ASSIGNMENT_CONFIG_POOL_OPTION);
|
||||
|
||||
|
||||
if (poolIndex >= 0) {
|
||||
int spaceBeforePoolIndex = config.indexOf(' ', poolIndex);
|
||||
int spaceAfterPoolIndex = config.indexOf(' ', spaceBeforePoolIndex);
|
||||
|
||||
|
||||
assignmentPool = config.mid(spaceBeforePoolIndex + 1, spaceAfterPoolIndex);
|
||||
qDebug() << "The pool for this voxel-assignment is" << assignmentPool << "\n";
|
||||
}
|
||||
|
||||
|
||||
Assignment voxelServerAssignment(Assignment::CreateCommand,
|
||||
Assignment::VoxelServerType,
|
||||
(assignmentPool.isEmpty() ? NULL : assignmentPool.toLocal8Bit().constData()));
|
||||
|
||||
|
||||
int payloadLength = config.length() + sizeof(char);
|
||||
voxelServerAssignment.setPayload((uchar*)config.toLocal8Bit().constData(), payloadLength);
|
||||
|
||||
|
||||
freshStaticAssignments[numFreshStaticAssignments++] = voxelServerAssignment;
|
||||
}
|
||||
} else {
|
||||
|
@ -579,53 +579,53 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
|||
if (_particleServerConfig) {
|
||||
qDebug("Reading Particle Server Configuration.\n");
|
||||
qDebug() << "config: " << _particleServerConfig << "\n";
|
||||
|
||||
|
||||
QString multiConfig((const char*) _particleServerConfig);
|
||||
QStringList multiConfigList = multiConfig.split(";");
|
||||
|
||||
|
||||
// read each config to a payload for a VS assignment
|
||||
for (int i = 0; i < multiConfigList.size(); i++) {
|
||||
QString config = multiConfigList.at(i);
|
||||
|
||||
|
||||
qDebug("config[%d]=%s\n", i, config.toLocal8Bit().constData());
|
||||
|
||||
|
||||
// Now, parse the config to check for a pool
|
||||
const char ASSIGNMENT_CONFIG_POOL_OPTION[] = "--pool";
|
||||
QString assignmentPool;
|
||||
|
||||
|
||||
int poolIndex = config.indexOf(ASSIGNMENT_CONFIG_POOL_OPTION);
|
||||
|
||||
|
||||
if (poolIndex >= 0) {
|
||||
int spaceBeforePoolIndex = config.indexOf(' ', poolIndex);
|
||||
int spaceAfterPoolIndex = config.indexOf(' ', spaceBeforePoolIndex);
|
||||
|
||||
|
||||
assignmentPool = config.mid(spaceBeforePoolIndex + 1, spaceAfterPoolIndex);
|
||||
qDebug() << "The pool for this particle-assignment is" << assignmentPool << "\n";
|
||||
}
|
||||
|
||||
|
||||
Assignment particleServerAssignment(Assignment::CreateCommand,
|
||||
Assignment::ParticleServerType,
|
||||
(assignmentPool.isEmpty() ? NULL : assignmentPool.toLocal8Bit().constData()));
|
||||
|
||||
|
||||
int payloadLength = config.length() + sizeof(char);
|
||||
particleServerAssignment.setPayload((uchar*)config.toLocal8Bit().constData(), payloadLength);
|
||||
|
||||
|
||||
freshStaticAssignments[numFreshStaticAssignments++] = particleServerAssignment;
|
||||
}
|
||||
} else {
|
||||
Assignment rootParticleServerAssignment(Assignment::CreateCommand, Assignment::ParticleServerType);
|
||||
freshStaticAssignments[numFreshStaticAssignments++] = rootParticleServerAssignment;
|
||||
}
|
||||
|
||||
|
||||
// handle metavoxel configuration command line argument
|
||||
Assignment& metavoxelAssignment = (freshStaticAssignments[numFreshStaticAssignments++] =
|
||||
Assignment(Assignment::CreateCommand, Assignment::MetavoxelServerType));
|
||||
if (_metavoxelServerConfig) {
|
||||
metavoxelAssignment.setPayload((const unsigned char*)_metavoxelServerConfig, strlen(_metavoxelServerConfig));
|
||||
}
|
||||
|
||||
|
||||
qDebug() << "Adding" << numFreshStaticAssignments << "static assignments to fresh file.\n";
|
||||
|
||||
|
||||
_staticAssignmentFile.open(QIODevice::WriteOnly);
|
||||
_staticAssignmentFile.write((char*) &freshStaticAssignments, sizeof(freshStaticAssignments));
|
||||
_staticAssignmentFile.resize(MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS * sizeof(Assignment));
|
||||
|
@ -634,10 +634,10 @@ void DomainServer::prepopulateStaticAssignmentFile() {
|
|||
|
||||
Assignment* DomainServer::matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NODE_TYPE nodeType) {
|
||||
// pull the UUID passed with the check in
|
||||
|
||||
|
||||
if (_hasCompletedRestartHold) {
|
||||
_assignmentQueueMutex.lock();
|
||||
|
||||
|
||||
// iterate the assignment queue to check for a match
|
||||
std::deque<Assignment*>::iterator assignment = _assignmentQueue.begin();
|
||||
while (assignment != _assignmentQueue.end()) {
|
||||
|
@ -650,7 +650,7 @@ Assignment* DomainServer::matchingStaticAssignmentForCheckIn(const QUuid& checkI
|
|||
assignment++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_assignmentQueueMutex.unlock();
|
||||
} else {
|
||||
for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) {
|
||||
|
@ -663,17 +663,17 @@ Assignment* DomainServer::matchingStaticAssignmentForCheckIn(const QUuid& checkI
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Assignment* DomainServer::deployableAssignmentForRequest(Assignment& requestAssignment) {
|
||||
_assignmentQueueMutex.lock();
|
||||
|
||||
|
||||
// this is an unassigned client talking to us directly for an assignment
|
||||
// go through our queue and see if there are any assignments to give out
|
||||
std::deque<Assignment*>::iterator assignment = _assignmentQueue.begin();
|
||||
|
||||
|
||||
while (assignment != _assignmentQueue.end()) {
|
||||
bool requestIsAllTypes = requestAssignment.getType() == Assignment::AllTypes;
|
||||
bool assignmentTypesMatch = (*assignment)->getType() == requestAssignment.getType();
|
||||
|
@ -681,29 +681,29 @@ Assignment* DomainServer::deployableAssignmentForRequest(Assignment& requestAssi
|
|||
bool assignmentPoolsMatch = memcmp((*assignment)->getPool(),
|
||||
requestAssignment.getPool(),
|
||||
MAX_ASSIGNMENT_POOL_BYTES) == 0;
|
||||
|
||||
|
||||
if ((requestIsAllTypes || assignmentTypesMatch) && (nietherHasPool || assignmentPoolsMatch)) {
|
||||
|
||||
|
||||
Assignment* deployableAssignment = *assignment;
|
||||
|
||||
|
||||
if ((*assignment)->getType() == Assignment::AgentType) {
|
||||
// if there is more than one instance to send out, simply decrease the number of instances
|
||||
|
||||
|
||||
if ((*assignment)->getNumberOfInstances() == 1) {
|
||||
_assignmentQueue.erase(assignment);
|
||||
}
|
||||
|
||||
|
||||
deployableAssignment->decrementNumberOfInstances();
|
||||
|
||||
|
||||
} else {
|
||||
// remove the assignment from the queue
|
||||
_assignmentQueue.erase(assignment);
|
||||
|
||||
|
||||
// until we get a check-in from that GUID
|
||||
// put assignment back in queue but stick it at the back so the others have a chance to go out
|
||||
_assignmentQueue.push_back(deployableAssignment);
|
||||
}
|
||||
|
||||
|
||||
// stop looping, we've handed out an assignment
|
||||
_assignmentQueueMutex.unlock();
|
||||
return deployableAssignment;
|
||||
|
@ -712,17 +712,17 @@ Assignment* DomainServer::deployableAssignmentForRequest(Assignment& requestAssi
|
|||
assignment++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_assignmentQueueMutex.unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DomainServer::removeAssignmentFromQueue(Assignment* removableAssignment) {
|
||||
|
||||
|
||||
_assignmentQueueMutex.lock();
|
||||
|
||||
|
||||
std::deque<Assignment*>::iterator assignment = _assignmentQueue.begin();
|
||||
|
||||
|
||||
while (assignment != _assignmentQueue.end()) {
|
||||
if ((*assignment)->getUUID() == removableAssignment->getUUID()) {
|
||||
_assignmentQueue.erase(assignment);
|
||||
|
@ -732,7 +732,7 @@ void DomainServer::removeAssignmentFromQueue(Assignment* removableAssignment) {
|
|||
assignment++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_assignmentQueueMutex.unlock();
|
||||
}
|
||||
|
||||
|
@ -740,7 +740,7 @@ bool DomainServer::checkInWithUUIDMatchesExistingNode(const HifiSockAddr& nodePu
|
|||
const HifiSockAddr& nodeLocalSocket,
|
||||
const QUuid& checkInUUID) {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getLinkedData()
|
||||
&& nodePublicSocket == node->getPublicSocket()
|
||||
|
@ -750,28 +750,28 @@ bool DomainServer::checkInWithUUIDMatchesExistingNode(const HifiSockAddr& nodePu
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DomainServer::addStaticAssignmentsBackToQueueAfterRestart() {
|
||||
_hasCompletedRestartHold = true;
|
||||
|
||||
|
||||
// if the domain-server has just restarted,
|
||||
// check if there are static assignments in the file that we need to
|
||||
// throw into the assignment queue
|
||||
|
||||
|
||||
// pull anything in the static assignment file that isn't spoken for and add to the assignment queue
|
||||
for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) {
|
||||
if (_staticAssignments[i].getUUID().isNull()) {
|
||||
// reached the end of static assignments, bail
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
bool foundMatchingAssignment = false;
|
||||
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
|
||||
// enumerate the nodes and check if there is one with an attached assignment with matching UUID
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getLinkedData()) {
|
||||
|
@ -782,13 +782,13 @@ void DomainServer::addStaticAssignmentsBackToQueueAfterRestart() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!foundMatchingAssignment) {
|
||||
// this assignment has not been fulfilled - reset the UUID and add it to the assignment queue
|
||||
_staticAssignments[i].resetUUID();
|
||||
|
||||
|
||||
qDebug() << "Adding static assignment to queue -" << _staticAssignments[i] << "\n";
|
||||
|
||||
|
||||
_assignmentQueueMutex.lock();
|
||||
_assignmentQueue.push_back(&_staticAssignments[i]);
|
||||
_assignmentQueueMutex.unlock();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <arpa/inet.h>
|
||||
//#include <arpa/inet.h> // not available on windows, apparently not needed on mac
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -22,23 +22,23 @@ const int PAIRING_SERVER_PORT = 7247;
|
|||
|
||||
PairingHandler* PairingHandler::getInstance() {
|
||||
static PairingHandler* instance = NULL;
|
||||
|
||||
|
||||
if (!instance) {
|
||||
instance = new PairingHandler();
|
||||
}
|
||||
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
void PairingHandler::sendPairRequest() {
|
||||
|
||||
|
||||
// prepare the pairing request packet
|
||||
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
|
||||
// use the getLocalAddress helper to get this client's listening address
|
||||
quint32 localAddress = htonl(getHostOrderLocalAddress());
|
||||
|
||||
|
||||
char pairPacket[24] = {};
|
||||
sprintf(pairPacket, "Find %d.%d.%d.%d:%hu",
|
||||
localAddress & 0xFF,
|
||||
|
@ -46,11 +46,11 @@ void PairingHandler::sendPairRequest() {
|
|||
(localAddress >> 16) & 0xFF,
|
||||
(localAddress >> 24) & 0xFF,
|
||||
NodeList::getInstance()->getNodeSocket().localPort());
|
||||
|
||||
|
||||
qDebug("Sending pair packet: %s\n", pairPacket);
|
||||
|
||||
|
||||
HifiSockAddr pairingServerSocket(PAIRING_SERVER_HOSTNAME, PAIRING_SERVER_PORT);
|
||||
|
||||
|
||||
// send the pair request to the pairing server
|
||||
nodeList->getNodeSocket().writeDatagram((char*) pairPacket, strlen(pairPacket),
|
||||
pairingServerSocket.getAddress(), pairingServerSocket.getPort());
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <netdb.h>
|
||||
//#include <netdb.h> // not available on windows, apparently not needed on mac
|
||||
|
||||
#include <QtNetwork/QHostInfo>
|
||||
|
||||
|
@ -23,12 +23,12 @@ HifiSockAddr Logging::logstashSocket = HifiSockAddr();
|
|||
char* Logging::targetName = NULL;
|
||||
|
||||
const HifiSockAddr& Logging::socket() {
|
||||
|
||||
|
||||
if (logstashSocket.getAddress().isNull()) {
|
||||
// we need to construct the socket object
|
||||
// use the constant port
|
||||
logstashSocket.setPort(htons(LOGSTASH_UDP_PORT));
|
||||
|
||||
|
||||
// lookup the IP address for the constant hostname
|
||||
QHostInfo hostInfo = QHostInfo::fromName(LOGSTASH_HOSTNAME);
|
||||
if (!hostInfo.addresses().isEmpty()) {
|
||||
|
@ -38,7 +38,7 @@ const HifiSockAddr& Logging::socket() {
|
|||
printf("Failed to lookup logstash IP - will try again on next log attempt.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return logstashSocket;
|
||||
}
|
||||
|
||||
|
@ -49,13 +49,13 @@ bool Logging::shouldSendStats() {
|
|||
|
||||
void Logging::stashValue(char statType, const char* key, float value) {
|
||||
static char logstashPacket[MAX_PACKET_SIZE];
|
||||
|
||||
|
||||
// load up the logstash packet with the key and the passed float value
|
||||
// send it to 4 decimal places
|
||||
int numPacketBytes = sprintf(logstashPacket, "%c %s %.4f", statType, key, value);
|
||||
|
||||
|
||||
NodeList *nodeList = NodeList::getInstance();
|
||||
|
||||
|
||||
if (nodeList) {
|
||||
nodeList->getNodeSocket().writeDatagram(logstashPacket, numPacketBytes,
|
||||
logstashSocket.getAddress(), logstashSocket.getPort());
|
||||
|
@ -65,7 +65,7 @@ void Logging::stashValue(char statType, const char* key, float value) {
|
|||
void Logging::setTargetName(const char* targetName) {
|
||||
// remove the old target name, if it exists
|
||||
delete Logging::targetName;
|
||||
|
||||
|
||||
// copy over the new target name
|
||||
Logging::targetName = new char[strlen(targetName)];
|
||||
strcpy(Logging::targetName, targetName);
|
||||
|
@ -92,30 +92,30 @@ const char DATE_STRING_FORMAT[] = "%F %H:%M:%S %z";
|
|||
void Logging::verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) {
|
||||
// log prefix is in the following format
|
||||
// [DEBUG] [TIMESTAMP] [PID:PARENT_PID] [TARGET] logged string
|
||||
|
||||
|
||||
QString prefixString = QString("[%1]").arg(stringForLogType(type));
|
||||
|
||||
|
||||
time_t rawTime;
|
||||
time(&rawTime);
|
||||
struct tm* localTime = localtime(&rawTime);
|
||||
|
||||
|
||||
char dateString[100];
|
||||
strftime(dateString, sizeof(dateString), DATE_STRING_FORMAT, localTime);
|
||||
|
||||
|
||||
prefixString.append(QString(" [%1]").arg(dateString));
|
||||
|
||||
|
||||
prefixString.append(QString(" [%1").arg(getpid()));
|
||||
|
||||
|
||||
pid_t parentProcessID = getppid();
|
||||
if (parentProcessID != 0) {
|
||||
prefixString.append(QString(":%1]").arg(parentProcessID));
|
||||
} else {
|
||||
prefixString.append("]");
|
||||
}
|
||||
|
||||
|
||||
if (Logging::targetName) {
|
||||
prefixString.append(QString(" [%1]").arg(Logging::targetName));
|
||||
}
|
||||
|
||||
|
||||
fprintf(stdout, "%s %s", prefixString.toLocal8Bit().constData(), message.toLocal8Bit().constData());
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
#define __shared_NetworkPacket__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <arpa/inet.h>
|
||||
//#include <arpa/inet.h> // not available on windows, apparently not needed on mac
|
||||
#include <ifaddrs.h>
|
||||
|
||||
#include "HifiSockAddr.h"
|
||||
|
@ -43,7 +43,7 @@ public:
|
|||
|
||||
private:
|
||||
void copyContents(const HifiSockAddr& sockAddr, const unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
|
||||
HifiSockAddr _sockAddr;
|
||||
ssize_t _packetLength;
|
||||
unsigned char _packetData[MAX_PACKET_SIZE];
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#ifdef _WIN32
|
||||
#include "Syssocket.h"
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
//#include <arpa/inet.h> // not available on windows, apparently not needed on mac
|
||||
#endif
|
||||
|
||||
#include "Node.h"
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
//#include <arpa/inet.h> // not available on windows, apparently not needed on mac
|
||||
|
||||
const int INET_ADDR_STRLEN = 16;
|
||||
|
||||
#include <QtNetwork/QUdpSocket>
|
||||
|
||||
|
@ -28,7 +30,7 @@ struct PairableDevice {
|
|||
};
|
||||
|
||||
struct RequestingClient {
|
||||
char address[INET_ADDRSTRLEN];
|
||||
char address[INET_ADDR_STRLEN];
|
||||
int port;
|
||||
};
|
||||
|
||||
|
@ -38,67 +40,67 @@ RequestingClient* lastClient = NULL;
|
|||
|
||||
int indexOfFirstOccurenceOfCharacter(char* haystack, char needle) {
|
||||
int currentIndex = 0;
|
||||
|
||||
|
||||
while (haystack[currentIndex] != '\0' && haystack[currentIndex] != needle) {
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
void sendLastClientToLastDevice() {
|
||||
char pairData[INET_ADDRSTRLEN + 6] = {};
|
||||
char pairData[INET_ADDR_STRLEN + 6] = {};
|
||||
int bytesWritten = sprintf(pairData, "%s:%d", ::lastClient->address, ::lastClient->port);
|
||||
|
||||
|
||||
::serverSocket.writeDatagram(pairData, bytesWritten,
|
||||
::lastDevice->sendingSocket.getAddress(), ::lastDevice->sendingSocket.getPort());
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
|
||||
|
||||
serverSocket.bind(QHostAddress::LocalHost, PAIRING_SERVER_LISTEN_PORT);
|
||||
|
||||
|
||||
HifiSockAddr senderSockAddr;
|
||||
char senderData[MAX_PACKET_SIZE_BYTES] = {};
|
||||
|
||||
|
||||
while (true) {
|
||||
if (::serverSocket.hasPendingDatagrams()
|
||||
&& ::serverSocket.readDatagram(senderData, MAX_PACKET_SIZE_BYTES,
|
||||
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer())) {
|
||||
if (senderData[0] == 'A') {
|
||||
// this is a device reporting itself as available
|
||||
|
||||
|
||||
PairableDevice tempDevice = {};
|
||||
|
||||
char deviceAddress[INET_ADDRSTRLEN] = {};
|
||||
|
||||
char deviceAddress[INET_ADDR_STRLEN] = {};
|
||||
int socketPort = 0;
|
||||
|
||||
|
||||
int numMatches = sscanf(senderData, "Available %s %[^:]:%d %s",
|
||||
tempDevice.identifier,
|
||||
deviceAddress,
|
||||
&socketPort,
|
||||
tempDevice.name);
|
||||
|
||||
|
||||
if (numMatches >= 3) {
|
||||
// if we have fewer than 3 matches the packet wasn't properly formatted
|
||||
|
||||
|
||||
// setup the localSocket for the pairing device
|
||||
tempDevice.localSocket.setAddress(QHostAddress(deviceAddress));
|
||||
tempDevice.localSocket.setPort(socketPort);
|
||||
|
||||
|
||||
// store this device's sending socket so we can talk back to it
|
||||
tempDevice.sendingSocket = senderSockAddr;
|
||||
|
||||
|
||||
// push this new device into the vector
|
||||
printf("New last device is %s (%s) at %s:%d\n",
|
||||
tempDevice.identifier,
|
||||
tempDevice.name,
|
||||
deviceAddress,
|
||||
socketPort);
|
||||
|
||||
// copy the tempDevice to the persisting lastDevice
|
||||
|
||||
// copy the tempDevice to the persisting lastDevice
|
||||
::lastDevice = new PairableDevice(tempDevice);
|
||||
|
||||
|
||||
if (::lastClient) {
|
||||
sendLastClientToLastDevice();
|
||||
}
|
||||
|
@ -106,21 +108,21 @@ int main(int argc, const char* argv[]) {
|
|||
} else if (senderData[0] == 'F') {
|
||||
// this is a client looking to pair with a device
|
||||
// send the most recent device this address so it can attempt to pair
|
||||
|
||||
|
||||
RequestingClient tempClient = {};
|
||||
|
||||
|
||||
int requestorMatches = sscanf(senderData, "Find %[^:]:%d",
|
||||
tempClient.address,
|
||||
&tempClient.port);
|
||||
|
||||
|
||||
if (requestorMatches == 2) {
|
||||
// good data, copy the tempClient to the persisting lastInterfaceClient
|
||||
// good data, copy the tempClient to the persisting lastInterfaceClient
|
||||
::lastClient = new RequestingClient(tempClient);
|
||||
|
||||
|
||||
printf("New last client is at %s:%d\n",
|
||||
::lastClient->address,
|
||||
::lastClient->port);
|
||||
|
||||
|
||||
if (::lastDevice) {
|
||||
sendLastClientToLastDevice();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue