mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 17:54:20 +02:00
replace UDPSocket with QUDPSocket
This commit is contained in:
parent
d21583d9c5
commit
141394a664
61 changed files with 521 additions and 1386 deletions
|
@ -17,5 +17,4 @@ add_subdirectory(assignment-client)
|
|||
add_subdirectory(domain-server)
|
||||
add_subdirectory(interface)
|
||||
add_subdirectory(pairing-server)
|
||||
add_subdirectory(space-server)
|
||||
add_subdirectory(voxel-edit)
|
|
@ -841,7 +841,7 @@ int main(int argc, const char * argv[])
|
|||
pthread_t animateVoxelThread;
|
||||
pthread_create(&animateVoxelThread, NULL, animateVoxels, NULL);
|
||||
|
||||
sockaddr nodePublicAddress;
|
||||
HifiSockAddr nodeSockAddr;
|
||||
|
||||
unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE];
|
||||
ssize_t receivedBytes;
|
||||
|
@ -858,15 +858,17 @@ int main(int argc, const char * argv[])
|
|||
}
|
||||
|
||||
// Nodes sending messages to us...
|
||||
if (nodeList->getNodeSocket()->receive(&nodePublicAddress, packetData, &receivedBytes) &&
|
||||
if ((receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
|
||||
nodeSockAddr.getAddressPointer(),
|
||||
nodeSockAddr.getPortPointer())) &&
|
||||
packetVersionMatch(packetData)) {
|
||||
|
||||
if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) {
|
||||
if (::jurisdictionListener) {
|
||||
::jurisdictionListener->queueReceivedPacket(nodePublicAddress, packetData, receivedBytes);
|
||||
::jurisdictionListener->queueReceivedPacket(nodeSockAddr, packetData, receivedBytes);
|
||||
}
|
||||
}
|
||||
NodeList::getInstance()->processNodeData(&nodePublicAddress, packetData, receivedBytes);
|
||||
NodeList::getInstance()->processNodeData(nodeSockAddr, packetData, receivedBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,8 +51,6 @@ void Agent::run() {
|
|||
const char AGENT_NODE_TYPES_OF_INTEREST[1] = { NODE_TYPE_VOXEL_SERVER };
|
||||
|
||||
nodeList->setNodeTypesOfInterest(AGENT_NODE_TYPES_OF_INTEREST, sizeof(AGENT_NODE_TYPES_OF_INTEREST));
|
||||
|
||||
nodeList->getNodeSocket()->setBlocking(false);
|
||||
|
||||
// figure out the URL for the script for this agent assignment
|
||||
QString scriptURLString("http://%1:8080/assignment/%2");
|
||||
|
@ -90,11 +88,6 @@ void Agent::run() {
|
|||
// let the VoxelPacketSender know how frequently we plan to call it
|
||||
voxelScripter.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS);
|
||||
|
||||
// hook in a constructor for audio injectorss
|
||||
AudioInjector scriptedAudioInjector(BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||
QScriptValue audioInjectorValue = engine.newQObject(&scriptedAudioInjector);
|
||||
engine.globalObject().setProperty("AudioInjector", audioInjectorValue);
|
||||
|
||||
qDebug() << "Downloaded script:" << scriptContents << "\n";
|
||||
QScriptValue result = engine.evaluate(scriptContents);
|
||||
qDebug() << "Evaluated script.\n";
|
||||
|
@ -109,7 +102,8 @@ void Agent::run() {
|
|||
|
||||
timeval lastDomainServerCheckIn = {};
|
||||
|
||||
sockaddr_in senderAddress;
|
||||
|
||||
HifiSockAddr senderSockAddr;
|
||||
unsigned char receivedData[MAX_PACKET_SIZE];
|
||||
ssize_t receivedBytes;
|
||||
|
||||
|
@ -153,14 +147,17 @@ void Agent::run() {
|
|||
qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n";
|
||||
}
|
||||
|
||||
while (NodeList::getInstance()->getNodeSocket()->receive((sockaddr*) &senderAddress, receivedData, &receivedBytes)
|
||||
&& packetVersionMatch(receivedData)) {
|
||||
while ((receivedBytes = NodeList::getInstance()->getNodeSocket().readDatagram((char*) receivedBytes,
|
||||
MAX_PACKET_SIZE,
|
||||
senderSockAddr.getAddressPointer(),
|
||||
senderSockAddr.getPortPointer()))
|
||||
&& packetVersionMatch(receivedData)) {
|
||||
if (receivedData[0] == PACKET_TYPE_VOXEL_JURISDICTION) {
|
||||
voxelScripter.getJurisdictionListener()->queueReceivedPacket((sockaddr&) senderAddress,
|
||||
voxelScripter.getJurisdictionListener()->queueReceivedPacket(senderSockAddr,
|
||||
receivedData,
|
||||
receivedBytes);
|
||||
} else {
|
||||
NodeList::getInstance()->processNodeData((sockaddr*) &senderAddress, receivedData, receivedBytes);
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, receivedData, receivedBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
#include <AudioInjector.h>
|
||||
#include <Assignment.h>
|
||||
|
||||
class Agent : public Assignment {
|
||||
|
@ -33,7 +32,6 @@ private:
|
|||
static QScriptValue AudioInjectorConstructor(QScriptContext *context, QScriptEngine *engine);
|
||||
|
||||
bool volatile _shouldStop;
|
||||
std::vector<AudioInjector*> _audioInjectors;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__Agent__) */
|
||||
|
|
|
@ -23,7 +23,7 @@ const long long ASSIGNMENT_REQUEST_INTERVAL_MSECS = 1 * 1000;
|
|||
|
||||
AssignmentClient::AssignmentClient(int &argc, char **argv,
|
||||
Assignment::Type requestAssignmentType,
|
||||
const sockaddr_in& customAssignmentServerSocket,
|
||||
const HifiSockAddr& customAssignmentServerSocket,
|
||||
const char* requestAssignmentPool) :
|
||||
QCoreApplication(argc, argv),
|
||||
_requestAssignment(Assignment::RequestCommand, requestAssignmentType, requestAssignmentPool)
|
||||
|
@ -35,8 +35,8 @@ AssignmentClient::AssignmentClient(int &argc, char **argv,
|
|||
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_UNASSIGNED);
|
||||
|
||||
// set the custom assignment socket if we have it
|
||||
if (customAssignmentServerSocket.sin_addr.s_addr != 0) {
|
||||
nodeList->setAssignmentServerSocket((sockaddr*) &customAssignmentServerSocket);
|
||||
if (!customAssignmentServerSocket.isNull()) {
|
||||
nodeList->setAssignmentServerSocket(customAssignmentServerSocket);
|
||||
}
|
||||
|
||||
// call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required
|
||||
|
|
|
@ -16,7 +16,7 @@ class AssignmentClient : public QCoreApplication {
|
|||
public:
|
||||
AssignmentClient(int &argc, char **argv,
|
||||
Assignment::Type requestAssignmentType = Assignment::AllTypes,
|
||||
const sockaddr_in& customAssignmentServerSocket = sockaddr_in(),
|
||||
const HifiSockAddr& customAssignmentServerSocket = HifiSockAddr(),
|
||||
const char* requestAssignmentPool = NULL);
|
||||
private slots:
|
||||
void sendAssignmentRequest();
|
||||
|
|
|
@ -235,10 +235,7 @@ void AudioMixer::run() {
|
|||
|
||||
unsigned char packetData[MAX_PACKET_SIZE] = {};
|
||||
|
||||
sockaddr* nodeAddress = new sockaddr;
|
||||
|
||||
// make sure our node socket is non-blocking
|
||||
nodeList->getNodeSocket()->setBlocking(false);
|
||||
HifiSockAddr nodeSockAddr;
|
||||
|
||||
int nextFrame = 0;
|
||||
timeval startTime;
|
||||
|
@ -301,7 +298,9 @@ void AudioMixer::run() {
|
|||
prepareMixForListeningNode(&(*node));
|
||||
|
||||
memcpy(clientPacket + numBytesPacketHeader, _clientSamples, sizeof(_clientSamples));
|
||||
nodeList->getNodeSocket()->send(node->getActiveSocket(), clientPacket, sizeof(clientPacket));
|
||||
nodeList->getNodeSocket().writeDatagram((char*) clientPacket, sizeof(clientPacket),
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,7 +312,8 @@ void AudioMixer::run() {
|
|||
}
|
||||
|
||||
// pull any new audio data from nodes off of the network stack
|
||||
while (nodeList->getNodeSocket()->receive(nodeAddress, packetData, &receivedBytes) &&
|
||||
while ((receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
|
||||
nodeSockAddr.getAddressPointer(), nodeSockAddr.getPortPointer())) &&
|
||||
packetVersionMatch(packetData)) {
|
||||
if (packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO
|
||||
|| packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO
|
||||
|
@ -325,7 +325,7 @@ void AudioMixer::run() {
|
|||
Node* matchingNode = nodeList->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (matchingNode) {
|
||||
nodeList->updateNodeWithData(matchingNode, nodeAddress, packetData, receivedBytes);
|
||||
nodeList->updateNodeWithData(matchingNode, nodeSockAddr, packetData, receivedBytes);
|
||||
|
||||
if (!matchingNode->getActiveSocket()) {
|
||||
// we don't have an active socket for this node, but they're talking to us
|
||||
|
@ -335,7 +335,7 @@ void AudioMixer::run() {
|
|||
}
|
||||
} else {
|
||||
// let processNodeData handle it.
|
||||
nodeList->processNodeData(nodeAddress, packetData, receivedBytes);
|
||||
nodeList->processNodeData(nodeSockAddr, packetData, receivedBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ void attachAvatarDataToNode(Node* newNode) {
|
|||
// 3) if we need to rate limit the amount of data we send, we can use a distance weighted "semi-random" function to
|
||||
// determine which avatars are included in the packet stream
|
||||
// 4) we should optimize the avatar data format to be more compact (100 bytes is pretty wasteful).
|
||||
void broadcastAvatarData(NodeList* nodeList, const QUuid& receiverUUID, sockaddr* receiverAddress) {
|
||||
void broadcastAvatarData(NodeList* nodeList, const QUuid& receiverUUID, const HifiSockAddr& receiverSockAddr) {
|
||||
static unsigned char broadcastPacketBuffer[MAX_PACKET_SIZE];
|
||||
static unsigned char avatarDataBuffer[MAX_PACKET_SIZE];
|
||||
unsigned char* broadcastPacket = (unsigned char*)&broadcastPacketBuffer[0];
|
||||
|
@ -68,7 +68,8 @@ void broadcastAvatarData(NodeList* nodeList, const QUuid& receiverUUID, sockaddr
|
|||
} else {
|
||||
packetsSent++;
|
||||
//printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength);
|
||||
nodeList->getNodeSocket()->send(receiverAddress, broadcastPacket, currentBufferPosition - broadcastPacket);
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, currentBufferPosition - broadcastPacket,
|
||||
receiverSockAddr.getAddress(), receiverSockAddr.getPort());
|
||||
|
||||
// reset the packet
|
||||
currentBufferPosition = broadcastPacket + numHeaderBytes;
|
||||
|
@ -83,7 +84,8 @@ void broadcastAvatarData(NodeList* nodeList, const QUuid& receiverUUID, sockaddr
|
|||
}
|
||||
packetsSent++;
|
||||
//printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength);
|
||||
nodeList->getNodeSocket()->send(receiverAddress, broadcastPacket, currentBufferPosition - broadcastPacket);
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, currentBufferPosition - broadcastPacket,
|
||||
receiverSockAddr.getAddress(), receiverSockAddr.getPort());
|
||||
}
|
||||
|
||||
AvatarMixer::AvatarMixer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) {
|
||||
|
@ -103,7 +105,7 @@ void AvatarMixer::run() {
|
|||
|
||||
nodeList->startSilentNodeRemovalThread();
|
||||
|
||||
sockaddr nodeAddress = {};
|
||||
HifiSockAddr nodeSockAddr;
|
||||
ssize_t receivedBytes = 0;
|
||||
|
||||
unsigned char packetData[MAX_PACKET_SIZE];
|
||||
|
@ -127,7 +129,8 @@ void AvatarMixer::run() {
|
|||
|
||||
nodeList->possiblyPingInactiveNodes();
|
||||
|
||||
if (nodeList->getNodeSocket()->receive(&nodeAddress, packetData, &receivedBytes) &&
|
||||
if (nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
|
||||
nodeSockAddr.getAddressPointer(), nodeSockAddr.getPortPointer()) &&
|
||||
packetVersionMatch(packetData)) {
|
||||
switch (packetData[0]) {
|
||||
case PACKET_TYPE_HEAD_DATA:
|
||||
|
@ -139,12 +142,12 @@ void AvatarMixer::run() {
|
|||
|
||||
if (avatarNode) {
|
||||
// parse positional data from an node
|
||||
nodeList->updateNodeWithData(avatarNode, &nodeAddress, packetData, receivedBytes);
|
||||
nodeList->updateNodeWithData(avatarNode, nodeSockAddr, packetData, receivedBytes);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_INJECT_AUDIO:
|
||||
broadcastAvatarData(nodeList, nodeUUID, &nodeAddress);
|
||||
broadcastAvatarData(nodeList, nodeUUID, nodeSockAddr);
|
||||
break;
|
||||
case PACKET_TYPE_KILL_NODE:
|
||||
case PACKET_TYPE_AVATAR_URLS:
|
||||
|
@ -154,14 +157,16 @@ void AvatarMixer::run() {
|
|||
// let everyone else know about the update
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getActiveSocket() && node->getUUID() != nodeUUID) {
|
||||
nodeList->getNodeSocket()->send(node->getActiveSocket(), packetData, receivedBytes);
|
||||
nodeList->getNodeSocket().writeDatagram((char*) packetData, receivedBytes,
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
}
|
||||
}
|
||||
// let node kills fall through to default behavior
|
||||
|
||||
default:
|
||||
// hand this off to the NodeList
|
||||
nodeList->processNodeData(&nodeAddress, packetData, receivedBytes);
|
||||
nodeList->processNodeData(nodeSockAddr, packetData, receivedBytes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
const char PARENT_TARGET_NAME[] = "assignment-client-monitor";
|
||||
|
||||
pid_t* childForks = NULL;
|
||||
sockaddr_in customAssignmentSocket = {};
|
||||
HifiSockAddr customAssignmentSocket;
|
||||
int numForks = 0;
|
||||
Assignment::Type overiddenAssignmentType = Assignment::AllTypes;
|
||||
const char* assignmentPool = NULL;
|
||||
|
@ -130,7 +130,7 @@ int main(int argc, char* argv[]) {
|
|||
customAssignmentServerHostname = LOCAL_ASSIGNMENT_SERVER_HOSTNAME;
|
||||
}
|
||||
|
||||
::customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServerHostname, assignmentServerPort);
|
||||
::customAssignmentSocket = HifiSockAddr(customAssignmentServerHostname, assignmentServerPort);
|
||||
}
|
||||
|
||||
const char ASSIGNMENT_TYPE_OVVERIDE_OPTION[] = "-t";
|
||||
|
|
|
@ -27,11 +27,13 @@ void VoxelScriptingInterface::queueVoxelAdd(float x, float y, float z, float sca
|
|||
|
||||
void VoxelScriptingInterface::queueDestructiveVoxelAdd(float x, float y, float z, float scale,
|
||||
uchar red, uchar green, uchar blue) {
|
||||
// setup a VoxelDetail struct with the data
|
||||
VoxelDetail addVoxelDetail = {x, y, z, scale, red, green, blue};
|
||||
// // setup a VoxelDetail struct with the data
|
||||
// VoxelDetail addVoxelDetail = {x, y, z, scale, red, green, blue};
|
||||
//
|
||||
// // queue the destructive add
|
||||
// queueVoxelAdd(PACKET_TYPE_SET_VOXEL_DESTRUCTIVE, addVoxelDetail);
|
||||
|
||||
// queue the destructive add
|
||||
queueVoxelAdd(PACKET_TYPE_SET_VOXEL_DESTRUCTIVE, addVoxelDetail);
|
||||
_voxelTree.createVoxel(x, y, z, scale, red, green, blue);
|
||||
}
|
||||
|
||||
void VoxelScriptingInterface::queueVoxelDelete(float x, float y, float z, float scale) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <JurisdictionListener.h>
|
||||
#include <VoxelEditPacketSender.h>
|
||||
#include <VoxelTree.h>
|
||||
|
||||
/// handles scripting of voxel commands from JS passed to assigned clients
|
||||
class VoxelScriptingInterface : public QObject {
|
||||
|
@ -22,6 +23,7 @@ public:
|
|||
|
||||
VoxelEditPacketSender* getVoxelPacketSender() { return &_voxelPacketSender; }
|
||||
JurisdictionListener* getJurisdictionListener() { return &_jurisdictionListener; }
|
||||
VoxelTree* getVoxelTree() { return &_voxelTree; }
|
||||
public slots:
|
||||
/// queues the creation of a voxel which will be sent by calling process on the PacketSender
|
||||
/// \param x the x-coordinate of the voxel (in VS space)
|
||||
|
@ -105,6 +107,7 @@ private:
|
|||
/// attached VoxelEditPacketSender that handles queuing and sending of packets to VS
|
||||
VoxelEditPacketSender _voxelPacketSender;
|
||||
JurisdictionListener _jurisdictionListener;
|
||||
VoxelTree _voxelTree;
|
||||
|
||||
void queueVoxelAdd(PACKET_TYPE addPacketType, VoxelDetail& addVoxelDetails);
|
||||
};
|
||||
|
|
|
@ -30,14 +30,11 @@ void DomainServer::setDomainServerInstance(DomainServer* domainServer) {
|
|||
domainServerInstance = domainServer;
|
||||
}
|
||||
|
||||
QJsonObject jsonForSocket(sockaddr* socket) {
|
||||
QJsonObject jsonForSocket(const HifiSockAddr& socket) {
|
||||
QJsonObject socketJSON;
|
||||
|
||||
if (socket->sa_family == AF_INET) {
|
||||
sockaddr_in* socketIPv4 = (sockaddr_in*) socket;
|
||||
socketJSON["ip"] = QString(inet_ntoa(socketIPv4->sin_addr));
|
||||
socketJSON["port"] = (int) ntohs(socketIPv4->sin_port);
|
||||
}
|
||||
socketJSON["ip"] = socket.getAddress().toString();
|
||||
socketJSON["port"] = ntohs(socket.getPort());
|
||||
|
||||
return socketJSON;
|
||||
}
|
||||
|
@ -288,8 +285,8 @@ unsigned char* DomainServer::addNodeToBroadcastPacket(unsigned char* currentPosi
|
|||
memcpy(currentPosition, rfcUUID.constData(), rfcUUID.size());
|
||||
currentPosition += rfcUUID.size();
|
||||
|
||||
currentPosition += packSocket(currentPosition, nodeToAdd->getPublicSocket());
|
||||
currentPosition += packSocket(currentPosition, nodeToAdd->getLocalSocket());
|
||||
currentPosition += HifiSockAddr::packSockAddr(currentPosition, nodeToAdd->getPublicSocket());
|
||||
currentPosition += HifiSockAddr::packSockAddr(currentPosition, nodeToAdd->getLocalSocket());
|
||||
|
||||
// return the new unsigned char * for broadcast packet
|
||||
return currentPosition;
|
||||
|
@ -506,15 +503,15 @@ void DomainServer::removeAssignmentFromQueue(Assignment* removableAssignment) {
|
|||
_assignmentQueueMutex.unlock();
|
||||
}
|
||||
|
||||
bool DomainServer::checkInWithUUIDMatchesExistingNode(sockaddr* nodePublicSocket,
|
||||
sockaddr* nodeLocalSocket,
|
||||
bool DomainServer::checkInWithUUIDMatchesExistingNode(const HifiSockAddr& nodePublicSocket,
|
||||
const HifiSockAddr& nodeLocalSocket,
|
||||
const QUuid& checkInUUID) {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getLinkedData()
|
||||
&& socketMatch(node->getPublicSocket(), nodePublicSocket)
|
||||
&& socketMatch(node->getLocalSocket(), nodeLocalSocket)
|
||||
&& nodePublicSocket == node->getPublicSocket()
|
||||
&& nodeLocalSocket == node->getLocalSocket()
|
||||
&& node->getUUID() == checkInUUID) {
|
||||
// this is a matching existing node if the public socket, local socket, and UUID match
|
||||
return true;
|
||||
|
@ -588,9 +585,11 @@ int DomainServer::run() {
|
|||
unsigned char* currentBufferPos;
|
||||
unsigned char* startPointer;
|
||||
|
||||
sockaddr_in senderAddress, nodePublicAddress, nodeLocalAddress;
|
||||
nodePublicAddress.sin_family = AF_INET;
|
||||
nodeLocalAddress.sin_family = AF_INET;
|
||||
QHostAddress senderAddress;
|
||||
quint16 senderPort;
|
||||
HifiSockAddr nodePublicAddress, nodeLocalAddress;
|
||||
|
||||
|
||||
|
||||
nodeList->startSilentNodeRemovalThread();
|
||||
|
||||
|
@ -614,7 +613,7 @@ int DomainServer::run() {
|
|||
gettimeofday(&startTime, NULL);
|
||||
|
||||
while (true) {
|
||||
while (nodeList->getNodeSocket()->receive((sockaddr *)&senderAddress, packetData, &receivedBytes) &&
|
||||
while (nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE, &senderAddress, &senderPort) &&
|
||||
packetVersionMatch(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
|
||||
|
@ -627,23 +626,23 @@ int DomainServer::run() {
|
|||
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray(((char*) packetData + packetIndex), NUM_BYTES_RFC4122_UUID));
|
||||
packetIndex += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
int numBytesPrivateSocket = unpackSocket(packetData + packetIndex, (sockaddr*) &nodePublicAddress);
|
||||
int numBytesPrivateSocket = HifiSockAddr::unpackSockAddr(packetData + packetIndex, nodePublicAddress);
|
||||
packetIndex += numBytesPrivateSocket;
|
||||
|
||||
if (nodePublicAddress.sin_addr.s_addr == 0) {
|
||||
if (nodePublicAddress.getAddress().isNull() == 0) {
|
||||
// this node wants to use us its STUN server
|
||||
// so set the node public address to whatever we perceive the public address to be
|
||||
|
||||
nodePublicAddress = senderAddress;
|
||||
nodePublicAddress.setAddress(senderAddress);
|
||||
|
||||
// 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 (senderAddress.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
|
||||
nodePublicAddress.sin_addr.s_addr = 0;
|
||||
if (senderAddress.isLoopback()) {
|
||||
nodePublicAddress.setAddress(QHostAddress());
|
||||
}
|
||||
}
|
||||
|
||||
int numBytesPublicSocket = unpackSocket(packetData + packetIndex, (sockaddr*) &nodeLocalAddress);
|
||||
int numBytesPublicSocket = HifiSockAddr::unpackSockAddr(packetData + packetIndex, nodeLocalAddress);
|
||||
packetIndex += numBytesPublicSocket;
|
||||
|
||||
const char STATICALLY_ASSIGNED_NODES[3] = {
|
||||
|
@ -656,14 +655,14 @@ int DomainServer::run() {
|
|||
|
||||
if (memchr(STATICALLY_ASSIGNED_NODES, nodeType, sizeof(STATICALLY_ASSIGNED_NODES)) == NULL
|
||||
|| ((matchingStaticAssignment = matchingStaticAssignmentForCheckIn(nodeUUID, nodeType))
|
||||
|| checkInWithUUIDMatchesExistingNode((sockaddr*) &nodePublicAddress,
|
||||
(sockaddr*) &nodeLocalAddress,
|
||||
|| checkInWithUUIDMatchesExistingNode(nodePublicAddress,
|
||||
nodeLocalAddress,
|
||||
nodeUUID)))
|
||||
{
|
||||
Node* checkInNode = nodeList->addOrUpdateNode(nodeUUID,
|
||||
nodeType,
|
||||
(sockaddr*) &nodePublicAddress,
|
||||
(sockaddr*) &nodeLocalAddress);
|
||||
nodePublicAddress,
|
||||
nodeLocalAddress);
|
||||
|
||||
if (matchingStaticAssignment) {
|
||||
// this was a newly added node with a matching static assignment
|
||||
|
@ -691,7 +690,7 @@ int DomainServer::run() {
|
|||
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->matches((sockaddr*) &nodePublicAddress, (sockaddr*) &nodeLocalAddress, nodeType) &&
|
||||
if (node->getUUID() != nodeUUID &&
|
||||
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
|
||||
|
||||
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
||||
|
@ -708,9 +707,9 @@ int DomainServer::run() {
|
|||
checkInNode->setLastHeardMicrostamp(timeNow);
|
||||
|
||||
// send the constructed list back to this node
|
||||
nodeList->getNodeSocket()->send((sockaddr*)&senderAddress,
|
||||
broadcastPacket,
|
||||
(currentBufferPos - startPointer) + numHeaderBytes);
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket,
|
||||
(currentBufferPos - startPointer) + numHeaderBytes,
|
||||
senderAddress, senderPort);
|
||||
}
|
||||
} else if (packetData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
||||
|
||||
|
@ -732,9 +731,8 @@ int DomainServer::run() {
|
|||
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_CREATE_ASSIGNMENT);
|
||||
int numAssignmentBytes = assignmentToDeploy->packToBuffer(broadcastPacket + numHeaderBytes);
|
||||
|
||||
nodeList->getNodeSocket()->send((sockaddr*) &senderAddress,
|
||||
broadcastPacket,
|
||||
numHeaderBytes + numAssignmentBytes);
|
||||
nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, numHeaderBytes + numAssignmentBytes,
|
||||
senderAddress, senderPort);
|
||||
|
||||
if (assignmentToDeploy->getNumberOfInstances() == 0) {
|
||||
// there are no more instances of this script to send out, delete it
|
||||
|
@ -743,43 +741,6 @@ int DomainServer::run() {
|
|||
}
|
||||
|
||||
}
|
||||
} else if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
|
||||
// this is a create assignment likely recieved from a server needed more clients to help with load
|
||||
|
||||
// unpack it
|
||||
Assignment* createAssignment = new Assignment(packetData, receivedBytes);
|
||||
|
||||
qDebug() << "Received a create assignment -" << *createAssignment << "\n";
|
||||
|
||||
// make sure we have a matching node with the UUID packed with the assignment
|
||||
// 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->getLinkedData()
|
||||
&& socketMatch((sockaddr*) &senderAddress, node->getPublicSocket())
|
||||
&& ((Assignment*) node->getLinkedData())->getUUID() == createAssignment->getUUID()) {
|
||||
|
||||
// give the create assignment a new UUID
|
||||
createAssignment->resetUUID();
|
||||
|
||||
// add the assignment at the back of the queue
|
||||
_assignmentQueueMutex.lock();
|
||||
_assignmentQueue.push_back(createAssignment);
|
||||
_assignmentQueueMutex.unlock();
|
||||
|
||||
// find the first available spot in the static assignments and put this assignment there
|
||||
for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) {
|
||||
if (_staticAssignments[i].getUUID().isNull()) {
|
||||
_staticAssignments[i] = *createAssignment;
|
||||
|
||||
// we've stuck the assignment in, break out
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// we found the matching node that asked for create assignment, break out
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,9 @@ private:
|
|||
Assignment* matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NODE_TYPE nodeType);
|
||||
Assignment* deployableAssignmentForRequest(Assignment& requestAssignment);
|
||||
void removeAssignmentFromQueue(Assignment* removableAssignment);
|
||||
bool checkInWithUUIDMatchesExistingNode(sockaddr* nodePublicSocket, sockaddr* nodeLocalSocket, const QUuid& checkInUUI);
|
||||
bool checkInWithUUIDMatchesExistingNode(const HifiSockAddr& nodePublicSocket,
|
||||
const HifiSockAddr& nodeLocalSocket,
|
||||
const QUuid& checkInUUI);
|
||||
void possiblyAddStaticAssignmentsBackToQueueAfterRestart(timeval* startTime);
|
||||
void addReleasedAssignmentBackToQueue(Assignment* releasedAssignment);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#include <glm/gtx/component_wise.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
|
||||
|
@ -47,8 +48,6 @@
|
|||
#include <QDesktopServices>
|
||||
|
||||
#include <NodeTypes.h>
|
||||
#include <AudioInjectionManager.h>
|
||||
#include <AudioInjector.h>
|
||||
#include <Logging.h>
|
||||
#include <OctalCode.h>
|
||||
#include <PacketHeaders.h>
|
||||
|
@ -172,9 +171,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
|
||||
// network receive thread and voxel parsing thread are both controlled by the --nonblocking command line
|
||||
_enableProcessVoxelsThread = _enableNetworkThread = !cmdOptionExists(argc, constArgv, "--nonblocking");
|
||||
if (!_enableNetworkThread) {
|
||||
NodeList::getInstance()->getNodeSocket()->setBlocking(false);
|
||||
}
|
||||
|
||||
// setup QSettings
|
||||
#ifdef Q_OS_MAC
|
||||
|
@ -1463,8 +1459,9 @@ void Application::checkBandwidthMeterClick() {
|
|||
// ... to be called upon button release
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth) &&
|
||||
glm::compMax(glm::abs(glm::ivec2(_mouseX - _mouseDragStartedX, _mouseY - _mouseDragStartedY))) <= BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH &&
|
||||
_bandwidthMeter.isWithinArea(_mouseX, _mouseY, _glWidget->width(), _glWidget->height())) {
|
||||
glm::compMax(glm::abs(glm::ivec2(_mouseX - _mouseDragStartedX, _mouseY - _mouseDragStartedY)))
|
||||
<= BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH
|
||||
&& _bandwidthMeter.isWithinArea(_mouseX, _mouseY, _glWidget->width(), _glWidget->height())) {
|
||||
|
||||
// The bandwidth meter is visible, the click didn't get dragged too far and
|
||||
// we actually hit the bandwidth meter
|
||||
|
@ -2661,7 +2658,6 @@ void Application::queryVoxels() {
|
|||
qDebug("perServerPPS: %d perUnknownServer: %d\n", perServerPPS, perUnknownServer);
|
||||
}
|
||||
|
||||
UDPSocket* nodeSocket = NodeList::getInstance()->getNodeSocket();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
// only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER
|
||||
if (node->getActiveSocket() != NULL && node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
|
@ -2747,7 +2743,8 @@ void Application::queryVoxels() {
|
|||
|
||||
int packetLength = endOfVoxelQueryPacket - voxelQueryPacket;
|
||||
|
||||
nodeSocket->send(node->getActiveSocket(), voxelQueryPacket, packetLength);
|
||||
nodeList->getNodeSocket().writeDatagram((char*) voxelQueryPacket, packetLength,
|
||||
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
|
||||
|
||||
// Feed number of bytes to corresponding channel of the bandwidth meter
|
||||
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength);
|
||||
|
@ -4034,62 +4031,6 @@ void Application::renderViewFrustum(ViewFrustum& viewFrustum) {
|
|||
}
|
||||
}
|
||||
|
||||
void Application::injectVoxelAddedSoundEffect() {
|
||||
AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(11025);
|
||||
|
||||
if (voxelInjector) {
|
||||
voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z));
|
||||
//voxelInjector->setBearing(-1 * _myAvatar.getAbsoluteHeadYaw());
|
||||
voxelInjector->setVolume (16 * pow (_mouseVoxel.s, 2) / .0000001); //255 is max, and also default value
|
||||
|
||||
/* for (int i = 0; i
|
||||
< 22050; i++) {
|
||||
if (i % 4 == 0) {
|
||||
voxelInjector->addSample(4000);
|
||||
} else if (i % 4 == 1) {
|
||||
voxelInjector->addSample(0);
|
||||
} else if (i % 4 == 2) {
|
||||
voxelInjector->addSample(-4000);
|
||||
} else {
|
||||
voxelInjector->addSample(0);
|
||||
}
|
||||
*/
|
||||
|
||||
const float BIG_VOXEL_MIN_SIZE = .01f;
|
||||
|
||||
for (int i = 0; i < 11025; i++) {
|
||||
|
||||
/*
|
||||
A440 square wave
|
||||
if (sin(i * 2 * PIE / 50)>=0) {
|
||||
voxelInjector->addSample(4000);
|
||||
} else {
|
||||
voxelInjector->addSample(-4000);
|
||||
}
|
||||
*/
|
||||
|
||||
if (_mouseVoxel.s > BIG_VOXEL_MIN_SIZE) {
|
||||
voxelInjector->addSample(20000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 200))));
|
||||
} else {
|
||||
voxelInjector->addSample(16000 * sin(i / (1.5 * log (_mouseVoxel.s / .0001) * ((i + 11025) / 5512.5)))); //808
|
||||
}
|
||||
}
|
||||
|
||||
//voxelInjector->addSample(32500 * sin(i/(2 * 1 * ((i+5000)/5512.5)))); //80
|
||||
//voxelInjector->addSample(20000 * sin(i/(6 * (_mouseVoxel.s/.001) *((i+5512.5)/5512.5)))); //808
|
||||
//voxelInjector->addSample(20000 * sin(i/(6 * ((i+5512.5)/5512.5)))); //808
|
||||
//voxelInjector->addSample(4000 * sin(i * 2 * PIE /50)); //A440 sine wave
|
||||
//voxelInjector->addSample(4000 * sin(i * 2 * PIE /50) * sin (i/500)); //A440 sine wave with amplitude modulation
|
||||
|
||||
//FM library
|
||||
//voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(500*sin((i+1)/200)))); //FM 1 dubstep
|
||||
//voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(300*sin((i+1)/5.0)))); //FM 2 flange sweep
|
||||
//voxelInjector->addSample(10000 * sin((i * 2 * PIE) /(500*sin((i+1)/500.0)))); //FM 3 resonant pulse
|
||||
|
||||
AudioInjectionManager::threadInjector(voxelInjector);
|
||||
}
|
||||
}
|
||||
|
||||
bool Application::maybeEditVoxelUnderCursor() {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode)
|
||||
|| Menu::getInstance()->isOptionChecked(MenuOption::VoxelColorMode)) {
|
||||
|
@ -4114,9 +4055,6 @@ bool Application::maybeEditVoxelUnderCursor() {
|
|||
fade.voxelDetails.s = _mouseVoxel.s + slightlyBigger + slightlyBigger;
|
||||
_voxelFades.push_back(fade);
|
||||
|
||||
// inject a sound effect
|
||||
injectVoxelAddedSoundEffect();
|
||||
|
||||
// remember the position for drag detection
|
||||
_justEditedVoxel = true;
|
||||
|
||||
|
@ -4149,21 +4087,6 @@ void Application::deleteVoxelUnderCursor() {
|
|||
// delete it locally to see the effect immediately (and in case no voxel server is present)
|
||||
_voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
||||
|
||||
AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(5000);
|
||||
|
||||
if (voxelInjector) {
|
||||
voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z));
|
||||
//voxelInjector->setBearing(0); //straight down the z axis
|
||||
voxelInjector->setVolume (255); //255 is max, and also default value
|
||||
|
||||
|
||||
for (int i = 0; i < 5000; i++) {
|
||||
voxelInjector->addSample(10000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 500.0)))); //FM 3 resonant pulse
|
||||
//voxelInjector->addSample(20000 * sin((i) /((4 / _mouseVoxel.s) * sin((i)/(20 * _mouseVoxel.s / .001))))); //FM 2 comb filter
|
||||
}
|
||||
|
||||
AudioInjectionManager::threadInjector(voxelInjector);
|
||||
}
|
||||
}
|
||||
// remember the position for drag detection
|
||||
_justEditedVoxel = true;
|
||||
|
@ -4321,10 +4244,10 @@ void Application::nodeKilled(Node* node) {
|
|||
}
|
||||
}
|
||||
|
||||
int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress) {
|
||||
int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderSockAddr) {
|
||||
|
||||
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
|
||||
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
|
||||
// parse the incoming stats datas stick it in a temporary object for now, while we
|
||||
// determine which server it belongs to
|
||||
|
@ -4377,12 +4300,15 @@ void* Application::networkReceive(void* args) {
|
|||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"Application::networkReceive()");
|
||||
|
||||
sockaddr senderAddress;
|
||||
HifiSockAddr senderSockAddr;
|
||||
ssize_t bytesReceived;
|
||||
|
||||
Application* app = Application::getInstance();
|
||||
while (!app->_stopNetworkReceiveThread) {
|
||||
if (NodeList::getInstance()->getNodeSocket()->receive(&senderAddress, app->_incomingPacket, &bytesReceived)) {
|
||||
if ((bytesReceived = NodeList::getInstance()->getNodeSocket().readDatagram((char*) app->_incomingPacket,
|
||||
MAX_PACKET_SIZE,
|
||||
senderSockAddr.getAddressPointer(),
|
||||
senderSockAddr.getPortPointer()))) {
|
||||
|
||||
app->_packetCount++;
|
||||
app->_bytesCount += bytesReceived;
|
||||
|
@ -4408,11 +4334,11 @@ void* Application::networkReceive(void* args) {
|
|||
"Application::networkReceive()... _voxelProcessor.queueReceivedPacket()");
|
||||
|
||||
// add this packet to our list of voxel packets and process them on the voxel processing
|
||||
app->_voxelProcessor.queueReceivedPacket(senderAddress, app->_incomingPacket, bytesReceived);
|
||||
app->_voxelProcessor.queueReceivedPacket(senderSockAddr, app->_incomingPacket, bytesReceived);
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_BULK_AVATAR_DATA:
|
||||
NodeList::getInstance()->processBulkNodeData(&senderAddress,
|
||||
NodeList::getInstance()->processBulkNodeData(senderSockAddr,
|
||||
app->_incomingPacket,
|
||||
bytesReceived);
|
||||
getInstance()->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
|
||||
|
@ -4430,7 +4356,7 @@ void* Application::networkReceive(void* args) {
|
|||
DataServerClient::processMessageFromDataServer(app->_incomingPacket, bytesReceived);
|
||||
break;
|
||||
default:
|
||||
NodeList::getInstance()->processNodeData(&senderAddress, app->_incomingPacket, bytesReceived);
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, app->_incomingPacket, bytesReceived);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -284,7 +284,6 @@ private:
|
|||
bool maybeEditVoxelUnderCursor();
|
||||
void deleteVoxelUnderCursor();
|
||||
void eyedropperVoxelUnderCursor();
|
||||
void injectVoxelAddedSoundEffect();
|
||||
|
||||
void setMenuShortcutsEnabled(bool enabled);
|
||||
|
||||
|
@ -464,7 +463,7 @@ private:
|
|||
|
||||
PieMenu _pieMenu;
|
||||
|
||||
int parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress);
|
||||
int parseVoxelStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderAddress);
|
||||
|
||||
NodeToJurisdictionMap _voxelServerJurisdictions;
|
||||
NodeToVoxelSceneStats _voxelServerSceneStats;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <StdDev.h>
|
||||
#include <UDPSocket.h>
|
||||
#include <QSvgRenderer>
|
||||
|
||||
#include "Application.h"
|
||||
|
@ -143,9 +142,9 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o
|
|||
// copy the audio data to the last BUFFER_LENGTH_BYTES bytes of the data packet
|
||||
memcpy(currentPacketPtr, inputLeft, BUFFER_LENGTH_BYTES_PER_CHANNEL);
|
||||
|
||||
nodeList->getNodeSocket()->send(audioMixer->getActiveSocket(),
|
||||
dataPacket,
|
||||
BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes);
|
||||
nodeList->getNodeSocket().writeDatagram((char*) dataPacket, BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes,
|
||||
audioMixer->getActiveSocket()->getAddress(),
|
||||
audioMixer->getActiveSocket()->getPort());
|
||||
|
||||
interface->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO).updateValue(BUFFER_LENGTH_BYTES_PER_CHANNEL
|
||||
+ leadingBytes);
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
//
|
||||
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtNetwork/QUdpSocket>
|
||||
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <UDPSocket.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
@ -24,7 +24,7 @@ const char MULTI_KEY_VALUE_SEPARATOR = '|';
|
|||
|
||||
const char DATA_SERVER_HOSTNAME[] = "data.highfidelity.io";
|
||||
const unsigned short DATA_SERVER_PORT = 3282;
|
||||
const sockaddr_in DATA_SERVER_SOCKET = socketForHostnameAndHostOrderPort(DATA_SERVER_HOSTNAME, DATA_SERVER_PORT);
|
||||
const HifiSockAddr DATA_SERVER_SOCKET = HifiSockAddr(DATA_SERVER_HOSTNAME, DATA_SERVER_PORT);
|
||||
|
||||
void DataServerClient::putValueForKey(const QString& key, const char* value) {
|
||||
QString clientString = Application::getInstance()->getProfile()->getUserString();
|
||||
|
@ -57,7 +57,8 @@ void DataServerClient::putValueForKey(const QString& key, const char* value) {
|
|||
// _unmatchedPackets.insert(std::pair<unsigned char*, int>(putPacket, numPacketBytes));
|
||||
|
||||
// send this put request to the data server
|
||||
NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, putPacket, numPacketBytes);
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) putPacket, numPacketBytes,
|
||||
DATA_SERVER_SOCKET.getAddress(), DATA_SERVER_SOCKET.getPort());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,7 +97,8 @@ void DataServerClient::getValuesForKeysAndUserString(const QStringList& keys, co
|
|||
// _unmatchedPackets.insert(std::pair<unsigned char*, int>(getPacket, numPacketBytes));
|
||||
|
||||
// send the get to the data server
|
||||
NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, getPacket, numPacketBytes);
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) getPacket, numPacketBytes,
|
||||
DATA_SERVER_SOCKET.getAddress(), DATA_SERVER_SOCKET.getPort());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,8 +238,7 @@ void DataServerClient::resendUnmatchedPackets() {
|
|||
mapIterator != _unmatchedPackets.end();
|
||||
++mapIterator) {
|
||||
// send the unmatched packet to the data server
|
||||
NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET,
|
||||
mapIterator->first,
|
||||
mapIterator->second);
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) mapIterator->first, mapIterator->second,
|
||||
DATA_SERVER_SOCKET.getAddress(), DATA_SERVER_SOCKET.getPort());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,24 +18,13 @@
|
|||
#include "renderer/ProgramObject.h"
|
||||
#include "world.h"
|
||||
|
||||
uint qHash(const sockaddr& address) {
|
||||
const sockaddr_in* inetAddress = reinterpret_cast<const sockaddr_in*>(&address);
|
||||
if (inetAddress->sin_family != AF_INET) {
|
||||
uint qHash(const HifiSockAddr& sockAddr) {
|
||||
if (sockAddr.getAddress().isNull()) {
|
||||
return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash
|
||||
}
|
||||
return inetAddress->sin_port + qHash(QByteArray::fromRawData(
|
||||
reinterpret_cast<const char*>(&inetAddress->sin_addr), sizeof(in_addr)));
|
||||
}
|
||||
|
||||
bool operator== (const sockaddr& addr1, const sockaddr& addr2) {
|
||||
return socketMatch(&addr1, &addr2);
|
||||
}
|
||||
|
||||
static sockaddr getZeroAddress() {
|
||||
sockaddr addr;
|
||||
memset(&addr, 0, sizeof(sockaddr));
|
||||
addr.sa_family = AF_INET;
|
||||
return addr;
|
||||
quint32 address = sockAddr.getAddress().toIPv4Address();
|
||||
return sockAddr.getPort() + qHash(QByteArray::fromRawData((char*) &address,
|
||||
sizeof(address)));
|
||||
}
|
||||
|
||||
Environment::Environment()
|
||||
|
@ -60,14 +49,14 @@ void Environment::init() {
|
|||
_skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations);
|
||||
|
||||
// start off with a default-constructed environment data
|
||||
_data[getZeroAddress()][0];
|
||||
_data[HifiSockAddr()][0];
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void Environment::resetToDefault() {
|
||||
_data.clear();
|
||||
_data[getZeroAddress()][0];
|
||||
_data[HifiSockAddr()][0];
|
||||
}
|
||||
|
||||
void Environment::renderAtmospheres(Camera& camera) {
|
||||
|
@ -159,7 +148,7 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3
|
|||
return found;
|
||||
}
|
||||
|
||||
int Environment::parseData(sockaddr *senderAddress, unsigned char* sourceBuffer, int numBytes) {
|
||||
int Environment::parseData(const HifiSockAddr& senderAddress, unsigned char* sourceBuffer, int numBytes) {
|
||||
// push past the packet header
|
||||
unsigned char* start = sourceBuffer;
|
||||
|
||||
|
@ -175,14 +164,14 @@ int Environment::parseData(sockaddr *senderAddress, unsigned char* sourceBuffer,
|
|||
int dataLength = newData.parseData(sourceBuffer, numBytes);
|
||||
|
||||
// update the mapping by address/ID
|
||||
_data[*senderAddress][newData.getID()] = newData;
|
||||
_data[senderAddress][newData.getID()] = newData;
|
||||
|
||||
sourceBuffer += dataLength;
|
||||
numBytes -= dataLength;
|
||||
}
|
||||
|
||||
// remove the default mapping, if any
|
||||
_data.remove(getZeroAddress());
|
||||
_data.remove(HifiSockAddr());
|
||||
|
||||
return sourceBuffer - start;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <QHash>
|
||||
#include <QMutex>
|
||||
|
||||
#include <UDPSocket.h>
|
||||
#include <HifiSockAddr.h>
|
||||
|
||||
#include "EnvironmentData.h"
|
||||
#include "InterfaceConfig.h"
|
||||
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration);
|
||||
|
||||
int parseData(sockaddr *senderAddress, unsigned char* sourceBuffer, int numBytes);
|
||||
int parseData(const HifiSockAddr& senderSockAddr, unsigned char* sourceBuffer, int numBytes);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -71,7 +71,7 @@ private:
|
|||
|
||||
typedef QHash<int, EnvironmentData> ServerData;
|
||||
|
||||
QHash<sockaddr, ServerData> _data;
|
||||
QHash<HifiSockAddr, ServerData> _data;
|
||||
|
||||
QMutex _mutex;
|
||||
};
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <QtNetwork/QHostInfo>
|
||||
|
||||
#include <HifiSockAddr.h>
|
||||
#include <NodeList.h>
|
||||
|
||||
#include "PairingHandler.h"
|
||||
|
@ -27,14 +30,14 @@ PairingHandler* PairingHandler::getInstance() {
|
|||
return instance;
|
||||
}
|
||||
|
||||
void PairingHandler::sendPairRequest() {
|
||||
// grab the node socket from the NodeList singleton
|
||||
UDPSocket *nodeSocket = NodeList::getInstance()->getNodeSocket();
|
||||
void PairingHandler::sendPairRequest() {
|
||||
|
||||
// prepare the pairing request packet
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
// use the getLocalAddress helper to get this client's listening address
|
||||
int localAddress = getLocalAddress();
|
||||
quint32 localAddress = getLocalAddress();
|
||||
|
||||
char pairPacket[24] = {};
|
||||
sprintf(pairPacket, "Find %d.%d.%d.%d:%hu",
|
||||
|
@ -42,19 +45,13 @@ void PairingHandler::sendPairRequest() {
|
|||
(localAddress >> 8) & 0xFF,
|
||||
(localAddress >> 16) & 0xFF,
|
||||
(localAddress >> 24) & 0xFF,
|
||||
NodeList::getInstance()->getSocketListenPort());
|
||||
NodeList::getInstance()->getNodeSocket().localPort());
|
||||
|
||||
qDebug("Sending pair packet: %s\n", pairPacket);
|
||||
|
||||
sockaddr_in pairingServerSocket;
|
||||
|
||||
pairingServerSocket.sin_family = AF_INET;
|
||||
|
||||
// lookup the pairing server IP by the hostname
|
||||
struct hostent* hostInfo = gethostbyname(PAIRING_SERVER_HOSTNAME);
|
||||
memcpy(&pairingServerSocket.sin_addr, hostInfo->h_addr_list[0], hostInfo->h_length);
|
||||
pairingServerSocket.sin_port = htons(PAIRING_SERVER_PORT);
|
||||
HifiSockAddr pairingServerSocket(PAIRING_SERVER_HOSTNAME, PAIRING_SERVER_PORT);
|
||||
|
||||
// send the pair request to the pairing server
|
||||
nodeSocket->send((sockaddr*) &pairingServerSocket, pairPacket, strlen(pairPacket));
|
||||
nodeList->getNodeSocket().writeDatagram((char*) pairPacket, strlen(pairPacket),
|
||||
pairingServerSocket.getAddress(), pairingServerSocket.getPort());
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "Menu.h"
|
||||
#include "VoxelPacketProcessor.h"
|
||||
|
||||
void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
|
||||
"VoxelPacketProcessor::processPacket()");
|
||||
|
||||
|
@ -50,10 +50,10 @@ void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char*
|
|||
} // fall through to piggyback message
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) {
|
||||
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||
if (voxelServer && socketMatch(voxelServer->getActiveSocket(), &senderAddress)) {
|
||||
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||
if (voxelServer && *voxelServer->getActiveSocket() == senderAddress) {
|
||||
if (packetData[0] == PACKET_TYPE_ENVIRONMENT_DATA) {
|
||||
app->_environment.parseData(&senderAddress, packetData, messageLength);
|
||||
app->_environment.parseData(senderAddress, packetData, messageLength);
|
||||
} else {
|
||||
app->_voxels.setDataSourceUUID(voxelServer->getUUID());
|
||||
app->_voxels.parseData(packetData, messageLength);
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
/// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket()
|
||||
class VoxelPacketProcessor : public ReceivedPacketProcessor {
|
||||
protected:
|
||||
virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
};
|
||||
#endif // __shared__VoxelPacketProcessor__
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <glm/glm.hpp>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
#include <UDPSocket.h>
|
||||
|
||||
#include <CoverageMapV2.h>
|
||||
#include <NodeData.h>
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
//
|
||||
// AudioInjectionManager.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 5/16/13.
|
||||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "SharedUtil.h"
|
||||
#include "NodeList.h"
|
||||
#include "NodeTypes.h"
|
||||
#include "Node.h"
|
||||
#include "PacketHeaders.h"
|
||||
|
||||
#include "AudioInjectionManager.h"
|
||||
|
||||
UDPSocket* AudioInjectionManager::_injectorSocket = NULL;
|
||||
sockaddr AudioInjectionManager::_destinationSocket;
|
||||
bool AudioInjectionManager::_isDestinationSocketExplicit = false;
|
||||
AudioInjector* AudioInjectionManager::_injectors[50] = {};
|
||||
|
||||
AudioInjector* AudioInjectionManager::injectorWithCapacity(int capacity) {
|
||||
for (int i = 0; i < MAX_CONCURRENT_INJECTORS; i++) {
|
||||
if (!_injectors[i]) {
|
||||
_injectors[i] = new AudioInjector(capacity);
|
||||
return _injectors[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AudioInjectionManager::setDestinationSocket(sockaddr& destinationSocket) {
|
||||
_destinationSocket = destinationSocket;
|
||||
_isDestinationSocketExplicit = true;
|
||||
}
|
||||
|
||||
void* AudioInjectionManager::injectAudioViaThread(void* args) {
|
||||
AudioInjector* injector = (AudioInjector*) args;
|
||||
|
||||
// if we don't have an injectorSocket then grab the one from the node list
|
||||
if (!_injectorSocket) {
|
||||
_injectorSocket = NodeList::getInstance()->getNodeSocket();
|
||||
}
|
||||
|
||||
// if we don't have an explicit destination socket then pull active socket for current audio mixer from node list
|
||||
if (!_isDestinationSocketExplicit) {
|
||||
Node* audioMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AUDIO_MIXER);
|
||||
if (audioMixer && audioMixer->getActiveSocket()) {
|
||||
_destinationSocket = *audioMixer->getActiveSocket();
|
||||
} else {
|
||||
pthread_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
injector->injectAudio(_injectorSocket, &_destinationSocket);
|
||||
|
||||
// if this an injector inside the injection manager's array we're responsible for deletion
|
||||
for (int i = 0; i < MAX_CONCURRENT_INJECTORS; i++) {
|
||||
if (_injectors[i] == injector) {
|
||||
// pointer matched - delete this injector
|
||||
delete injector;
|
||||
|
||||
// set the pointer to NULL so we can reuse this spot
|
||||
_injectors[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_exit(0);
|
||||
}
|
||||
|
||||
void AudioInjectionManager::threadInjector(AudioInjector* injector) {
|
||||
pthread_t audioInjectThread;
|
||||
pthread_create(&audioInjectThread, NULL, injectAudioViaThread, (void*) injector);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
//
|
||||
// AudioInjectionManager.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 5/16/13.
|
||||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__AudioInjectionManager__
|
||||
#define __hifi__AudioInjectionManager__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "UDPSocket.h"
|
||||
#include "AudioInjector.h"
|
||||
|
||||
const int MAX_CONCURRENT_INJECTORS = 50;
|
||||
|
||||
class AudioInjectionManager {
|
||||
public:
|
||||
static AudioInjector* injectorWithCapacity(int capacity);
|
||||
|
||||
static void threadInjector(AudioInjector* injector);
|
||||
|
||||
static void setInjectorSocket(UDPSocket* injectorSocket) { _injectorSocket = injectorSocket;}
|
||||
static void setDestinationSocket(sockaddr& destinationSocket);
|
||||
private:
|
||||
static void* injectAudioViaThread(void* args);
|
||||
|
||||
static UDPSocket* _injectorSocket;
|
||||
static sockaddr _destinationSocket;
|
||||
static bool _isDestinationSocketExplicit;
|
||||
static AudioInjector* _injectors[MAX_CONCURRENT_INJECTORS];
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AudioInjectionManager__) */
|
|
@ -1,137 +0,0 @@
|
|||
//
|
||||
// AudioInjector.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 4/23/13.
|
||||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "AudioInjector.h"
|
||||
|
||||
AudioInjector::AudioInjector(int maxNumSamples) :
|
||||
_streamIdentifier(QUuid::createUuid()),
|
||||
_numTotalSamples(maxNumSamples),
|
||||
_position(0.0f, 0.0f, 0.0f),
|
||||
_orientation(),
|
||||
_radius(0.0f),
|
||||
_volume(MAX_INJECTOR_VOLUME),
|
||||
_indexOfNextSlot(0),
|
||||
_isInjectingAudio(false)
|
||||
{
|
||||
_audioSampleArray = new int16_t[maxNumSamples];
|
||||
memset(_audioSampleArray, 0, _numTotalSamples * sizeof(int16_t));
|
||||
}
|
||||
|
||||
AudioInjector::~AudioInjector() {
|
||||
delete[] _audioSampleArray;
|
||||
}
|
||||
|
||||
void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destinationSocket) {
|
||||
if (_audioSampleArray && _indexOfNextSlot > 0) {
|
||||
_isInjectingAudio = true;
|
||||
|
||||
timeval startTime;
|
||||
|
||||
// calculate the number of bytes required for additional data
|
||||
int leadingBytes = numBytesForPacketHeader((unsigned char*) &PACKET_TYPE_INJECT_AUDIO)
|
||||
+ NUM_BYTES_RFC4122_UUID
|
||||
+ NUM_BYTES_RFC4122_UUID
|
||||
+ sizeof(_position)
|
||||
+ sizeof(_orientation)
|
||||
+ sizeof(_radius)
|
||||
+ sizeof(_volume);
|
||||
|
||||
unsigned char dataPacket[(BUFFER_LENGTH_SAMPLES_PER_CHANNEL * sizeof(int16_t)) + leadingBytes];
|
||||
|
||||
unsigned char* currentPacketPtr = dataPacket + populateTypeAndVersion(dataPacket, PACKET_TYPE_INJECT_AUDIO);
|
||||
|
||||
// copy the UUID for the owning node
|
||||
QByteArray rfcUUID = NodeList::getInstance()->getOwnerUUID().toRfc4122();
|
||||
memcpy(currentPacketPtr, rfcUUID.constData(), rfcUUID.size());
|
||||
currentPacketPtr += rfcUUID.size();
|
||||
|
||||
// copy the stream identifier
|
||||
QByteArray rfcStreamIdentifier = _streamIdentifier.toRfc4122();
|
||||
memcpy(currentPacketPtr, rfcStreamIdentifier.constData(), rfcStreamIdentifier.size());
|
||||
currentPacketPtr += rfcStreamIdentifier.size();
|
||||
|
||||
memcpy(currentPacketPtr, &_position, sizeof(_position));
|
||||
currentPacketPtr += sizeof(_position);
|
||||
|
||||
memcpy(currentPacketPtr, &_orientation, sizeof(_orientation));
|
||||
currentPacketPtr += sizeof(_orientation);
|
||||
|
||||
memcpy(currentPacketPtr, &_radius, sizeof(_radius));
|
||||
currentPacketPtr += sizeof(_radius);
|
||||
|
||||
*currentPacketPtr = _volume;
|
||||
currentPacketPtr++;
|
||||
|
||||
gettimeofday(&startTime, NULL);
|
||||
int nextFrame = 0;
|
||||
|
||||
for (int i = 0; i < _numTotalSamples; i += BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
||||
int usecToSleep = usecTimestamp(&startTime) + (nextFrame++ * INJECT_INTERVAL_USECS) - usecTimestampNow();
|
||||
if (usecToSleep > 0) {
|
||||
usleep(usecToSleep);
|
||||
}
|
||||
|
||||
int numSamplesToCopy = BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||
|
||||
if (_numTotalSamples - i < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
||||
numSamplesToCopy = _numTotalSamples - i;
|
||||
memset(currentPacketPtr + numSamplesToCopy,
|
||||
0,
|
||||
BUFFER_LENGTH_BYTES_PER_CHANNEL - (numSamplesToCopy * sizeof(int16_t)));
|
||||
}
|
||||
|
||||
memcpy(currentPacketPtr, _audioSampleArray + i, numSamplesToCopy * sizeof(int16_t));
|
||||
|
||||
injectorSocket->send(destinationSocket, dataPacket, sizeof(dataPacket));
|
||||
}
|
||||
|
||||
_isInjectingAudio = false;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioInjector::addSample(const int16_t sample) {
|
||||
if (_indexOfNextSlot != _numTotalSamples) {
|
||||
// only add this sample if we actually have space for it
|
||||
_audioSampleArray[_indexOfNextSlot++] = sample;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioInjector::addSamples(int16_t* sampleBuffer, int numSamples) {
|
||||
if (_audioSampleArray + _indexOfNextSlot + numSamples <= _audioSampleArray + _numTotalSamples) {
|
||||
// only copy the audio from the sample buffer if there's space
|
||||
memcpy(_audioSampleArray + _indexOfNextSlot, sampleBuffer, numSamples * sizeof(int16_t));
|
||||
_indexOfNextSlot += numSamples;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioInjector::clear() {
|
||||
_indexOfNextSlot = 0;
|
||||
memset(_audioSampleArray, 0, _numTotalSamples * sizeof(int16_t));
|
||||
}
|
||||
|
||||
int16_t& AudioInjector::sampleAt(const int index) {
|
||||
assert(index >= 0 && index < _numTotalSamples);
|
||||
|
||||
return _audioSampleArray[index];
|
||||
}
|
||||
|
||||
void AudioInjector::insertSample(const int index, int sample) {
|
||||
assert (index >= 0 && index < _numTotalSamples);
|
||||
|
||||
_audioSampleArray[index] = (int16_t) sample;
|
||||
_indexOfNextSlot = index + 1;
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
//
|
||||
// AudioInjector.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 4/23/13.
|
||||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__AudioInjector__
|
||||
#define __hifi__AudioInjector__
|
||||
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/gtx/component_wise.hpp>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include <RegisteredMetaTypes.h>
|
||||
#include <UDPSocket.h>
|
||||
|
||||
#include "AudioRingBuffer.h"
|
||||
|
||||
const int MAX_INJECTOR_VOLUME = 0xFF;
|
||||
|
||||
const int INJECT_INTERVAL_USECS = floorf((BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SAMPLE_RATE) * 1000000);
|
||||
|
||||
class AudioInjector : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition)
|
||||
Q_PROPERTY(uchar volume READ getVolume WRITE setVolume);
|
||||
public:
|
||||
AudioInjector(int maxNumSamples);
|
||||
~AudioInjector();
|
||||
|
||||
void injectAudio(UDPSocket* injectorSocket, sockaddr* destinationSocket);
|
||||
|
||||
bool isInjectingAudio() const { return _isInjectingAudio; }
|
||||
|
||||
unsigned char getVolume() const { return _volume; }
|
||||
void setVolume(unsigned char volume) { _volume = volume; }
|
||||
|
||||
const glm::vec3& getPosition() const { return _position; }
|
||||
void setPosition(const glm::vec3& position) { _position = position; }
|
||||
|
||||
const glm::quat& getOrientation() const { return _orientation; }
|
||||
void setOrientation(const glm::quat& orientation) { _orientation = orientation; }
|
||||
|
||||
float getRadius() const { return _radius; }
|
||||
void setRadius(float radius) { _radius = radius; }
|
||||
|
||||
bool hasSamplesToInject() const { return _indexOfNextSlot > 0; }
|
||||
|
||||
void addSample(const int16_t sample);
|
||||
void addSamples(int16_t* sampleBuffer, int numSamples);
|
||||
|
||||
void clear();
|
||||
public slots:
|
||||
int16_t& sampleAt(const int index);
|
||||
void insertSample(const int index, int sample);
|
||||
private:
|
||||
QUuid _streamIdentifier;
|
||||
int16_t* _audioSampleArray;
|
||||
int _numTotalSamples;
|
||||
glm::vec3 _position;
|
||||
glm::quat _orientation;
|
||||
float _radius;
|
||||
unsigned char _volume;
|
||||
int _indexOfNextSlot;
|
||||
bool _isInjectingAudio;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AudioInjector__) */
|
|
@ -24,6 +24,8 @@ InjectedAudioRingBuffer::InjectedAudioRingBuffer(const QUuid& streamIdentifier)
|
|||
|
||||
}
|
||||
|
||||
const uchar MAX_INJECTOR_VOLUME = 255;
|
||||
|
||||
int InjectedAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||
unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer);
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include "AudioInjector.h"
|
||||
|
||||
#include "PositionalAudioRingBuffer.h"
|
||||
|
||||
class InjectedAudioRingBuffer : public PositionalAudioRingBuffer {
|
||||
|
|
110
libraries/shared/src/HifiSockAddr.cpp
Normal file
110
libraries/shared/src/HifiSockAddr.cpp
Normal file
|
@ -0,0 +1,110 @@
|
|||
//
|
||||
// HifiSockAddr.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 11/26/2013.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "HifiSockAddr.h"
|
||||
|
||||
#include <QtNetwork/QHostInfo>
|
||||
#include <QtNetwork/QNetworkInterface>
|
||||
|
||||
HifiSockAddr::HifiSockAddr() :
|
||||
_address(QHostAddress::Null),
|
||||
_port(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HifiSockAddr::HifiSockAddr(const QHostAddress& address, quint16 port) :
|
||||
_address(address),
|
||||
_port(port)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HifiSockAddr::HifiSockAddr(const HifiSockAddr& otherSockAddr) {
|
||||
_address = otherSockAddr._address;
|
||||
_port = otherSockAddr._port;
|
||||
}
|
||||
|
||||
HifiSockAddr::HifiSockAddr(const QString& hostname, quint16 hostOrderPort) {
|
||||
// lookup the IP by the hostname
|
||||
QHostInfo hostInfo = QHostInfo::fromName(hostname);
|
||||
if (!hostInfo.addresses().isEmpty()) {
|
||||
// use the first IP address
|
||||
_address = hostInfo.addresses().first();
|
||||
_port = hostOrderPort; }
|
||||
}
|
||||
|
||||
HifiSockAddr& HifiSockAddr::operator=(const HifiSockAddr& rhsSockAddr) {
|
||||
HifiSockAddr temp(rhsSockAddr);
|
||||
swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void HifiSockAddr::swap(HifiSockAddr& otherSockAddr) {
|
||||
using std::swap;
|
||||
|
||||
swap(_address, otherSockAddr._address);
|
||||
swap(_port, otherSockAddr._port);
|
||||
}
|
||||
|
||||
int HifiSockAddr::packSockAddr(unsigned char* packetData, const HifiSockAddr& packSockAddr) {
|
||||
unsigned int addressToPack = packSockAddr._address.toIPv4Address();
|
||||
memcpy(packetData, &addressToPack, sizeof(packSockAddr._address.toIPv4Address()));
|
||||
memcpy(packetData, &packSockAddr._port, sizeof(packSockAddr._port));
|
||||
|
||||
return sizeof(addressToPack) + sizeof(packSockAddr._port);
|
||||
}
|
||||
|
||||
int HifiSockAddr::unpackSockAddr(const unsigned char* packetData, HifiSockAddr& unpackDestSockAddr) {
|
||||
unpackDestSockAddr._address = QHostAddress(*((quint32*) packetData));
|
||||
unpackDestSockAddr._port = *((quint16*) (packetData + sizeof(quint32)));
|
||||
|
||||
return sizeof(quint32) + sizeof(quint16);
|
||||
}
|
||||
|
||||
bool HifiSockAddr::operator==(const HifiSockAddr &rhsSockAddr) const {
|
||||
return _address == rhsSockAddr._address && _port == rhsSockAddr._port;
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const HifiSockAddr &hifiSockAddr) {
|
||||
debug.nospace() << hifiSockAddr._address.toString() << ":" << hifiSockAddr._port;
|
||||
return debug;
|
||||
}
|
||||
|
||||
quint32 getLocalAddress() {
|
||||
|
||||
static int localAddress = 0;
|
||||
|
||||
if (localAddress == 0) {
|
||||
foreach(const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
|
||||
if (interface.flags() & QNetworkInterface::IsUp
|
||||
&& interface.flags() & QNetworkInterface::IsRunning
|
||||
&& interface.flags() & ~QNetworkInterface::IsLoopBack) {
|
||||
// we've decided that this is the active NIC
|
||||
// enumerate it's addresses to grab the IPv4 address
|
||||
foreach(const QNetworkAddressEntry &entry, interface.addressEntries()) {
|
||||
// make sure it's an IPv4 address that isn't the loopback
|
||||
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isLoopback()) {
|
||||
qDebug("Node's local address is %s\n", entry.ip().toString().toLocal8Bit().constData());
|
||||
|
||||
// set our localAddress and break out
|
||||
localAddress = htonl(entry.ip().toIPv4Address());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (localAddress != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return the looked up local address
|
||||
return localAddress;
|
||||
}
|
48
libraries/shared/src/HifiSockAddr.h
Normal file
48
libraries/shared/src/HifiSockAddr.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
//
|
||||
// HifiSockAddr.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 11/26/2013.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__HifiSockAddr__
|
||||
#define __hifi__HifiSockAddr__
|
||||
|
||||
#include <QtNetwork/QHostAddress>
|
||||
|
||||
class HifiSockAddr {
|
||||
public:
|
||||
HifiSockAddr();
|
||||
HifiSockAddr(const QHostAddress& address, quint16 port);
|
||||
HifiSockAddr(const HifiSockAddr& otherSockAddr);
|
||||
HifiSockAddr(const QString& hostname, quint16 hostOrderPort);
|
||||
|
||||
bool isNull() const { return _address.isNull() && _port == 0; }
|
||||
|
||||
HifiSockAddr& operator=(const HifiSockAddr& rhsSockAddr);
|
||||
void swap(HifiSockAddr& otherSockAddr);
|
||||
|
||||
bool operator==(const HifiSockAddr& rhsSockAddr) const;
|
||||
bool operator!=(const HifiSockAddr& rhsSockAddr) const { return !(*this == rhsSockAddr); }
|
||||
|
||||
const QHostAddress& getAddress() const { return _address; }
|
||||
QHostAddress* getAddressPointer() { return &_address; }
|
||||
void setAddress(const QHostAddress& address) { _address = address; }
|
||||
|
||||
quint16 getPort() const { return _port; }
|
||||
quint16* getPortPointer() { return &_port; }
|
||||
void setPort(quint16 port) { _port = port; }
|
||||
|
||||
static int packSockAddr(unsigned char* packetData, const HifiSockAddr& packSockAddr);
|
||||
static int unpackSockAddr(const unsigned char* packetData, HifiSockAddr& unpackDestSockAddr);
|
||||
|
||||
friend QDebug operator<<(QDebug debug, const HifiSockAddr &hifiSockAddr);
|
||||
private:
|
||||
QHostAddress _address;
|
||||
quint16 _port;
|
||||
};
|
||||
|
||||
quint32 getLocalAddress();
|
||||
|
||||
#endif /* defined(__hifi__HifiSockAddr__) */
|
|
@ -11,35 +11,35 @@
|
|||
#include <iostream>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <QtNetwork/QHostInfo>
|
||||
|
||||
#include "HifiSockAddr.h"
|
||||
#include "SharedUtil.h"
|
||||
#include "NodeList.h"
|
||||
|
||||
#include "Logging.h"
|
||||
|
||||
sockaddr_in Logging::logstashSocket = {};
|
||||
HifiSockAddr Logging::logstashSocket = HifiSockAddr();
|
||||
char* Logging::targetName = NULL;
|
||||
|
||||
sockaddr* Logging::socket() {
|
||||
const HifiSockAddr& Logging::socket() {
|
||||
|
||||
if (logstashSocket.sin_addr.s_addr == 0) {
|
||||
if (logstashSocket.getAddress().isNull()) {
|
||||
// we need to construct the socket object
|
||||
|
||||
// assume IPv4
|
||||
logstashSocket.sin_family = AF_INET;
|
||||
|
||||
// use the constant port
|
||||
logstashSocket.sin_port = htons(LOGSTASH_UDP_PORT);
|
||||
logstashSocket.setPort(htons(LOGSTASH_UDP_PORT));
|
||||
|
||||
// lookup the IP address for the constant hostname
|
||||
struct hostent* logstashHostInfo;
|
||||
if ((logstashHostInfo = gethostbyname(LOGSTASH_HOSTNAME))) {
|
||||
memcpy(&logstashSocket.sin_addr, logstashHostInfo->h_addr_list[0], logstashHostInfo->h_length);
|
||||
QHostInfo hostInfo = QHostInfo::fromName(LOGSTASH_HOSTNAME);
|
||||
if (!hostInfo.addresses().isEmpty()) {
|
||||
// use the first IP address
|
||||
logstashSocket.setAddress(hostInfo.addresses().first());
|
||||
} else {
|
||||
printf("Failed to lookup logstash IP - will try again on next log attempt.\n");
|
||||
}
|
||||
}
|
||||
|
||||
return (sockaddr*) &logstashSocket;
|
||||
return logstashSocket;
|
||||
}
|
||||
|
||||
bool Logging::shouldSendStats() {
|
||||
|
@ -57,7 +57,8 @@ void Logging::stashValue(char statType, const char* key, float value) {
|
|||
NodeList *nodeList = NodeList::getInstance();
|
||||
|
||||
if (nodeList) {
|
||||
nodeList->getNodeSocket()->send(socket(), logstashPacket, numPacketBytes);
|
||||
nodeList->getNodeSocket().writeDatagram(logstashPacket, numPacketBytes,
|
||||
logstashSocket.getAddress(), logstashSocket.getPort());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,13 @@ const char STAT_TYPE_TIMER = 't';
|
|||
const char STAT_TYPE_COUNTER = 'c';
|
||||
const char STAT_TYPE_GAUGE = 'g';
|
||||
|
||||
class HifiSockAddr;
|
||||
|
||||
/// Handles custom message handling and sending of stats/logs to Logstash instance
|
||||
class Logging {
|
||||
public:
|
||||
/// \return the socket used to send stats to logstash
|
||||
static sockaddr* socket();
|
||||
static const HifiSockAddr& socket();
|
||||
|
||||
/// checks if this target should send stats to logstash, given its current environment
|
||||
/// \return true if the caller should send stats to logstash
|
||||
|
@ -44,7 +46,7 @@ public:
|
|||
/// prints various process, message type, and time information
|
||||
static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message);
|
||||
private:
|
||||
static sockaddr_in logstashSocket;
|
||||
static HifiSockAddr logstashSocket;
|
||||
static char* targetName;
|
||||
};
|
||||
|
||||
|
|
|
@ -22,10 +22,10 @@ NetworkPacket::~NetworkPacket() {
|
|||
// nothing to do
|
||||
}
|
||||
|
||||
void NetworkPacket::copyContents(const sockaddr& address, const unsigned char* packetData, ssize_t packetLength) {
|
||||
void NetworkPacket::copyContents(const HifiSockAddr& sockAddr, const unsigned char* packetData, ssize_t packetLength) {
|
||||
_packetLength = 0;
|
||||
if (packetLength >=0 && packetLength <= MAX_PACKET_SIZE) {
|
||||
memcpy(&_address, &address, sizeof(_address));
|
||||
_sockAddr = sockAddr;
|
||||
_packetLength = packetLength;
|
||||
memcpy(&_packetData[0], packetData, packetLength);
|
||||
} else {
|
||||
|
@ -34,16 +34,16 @@ void NetworkPacket::copyContents(const sockaddr& address, const unsigned char*
|
|||
}
|
||||
|
||||
NetworkPacket::NetworkPacket(const NetworkPacket& packet) {
|
||||
copyContents(packet.getAddress(), packet.getData(), packet.getLength());
|
||||
copyContents(packet.getSockAddr(), packet.getData(), packet.getLength());
|
||||
}
|
||||
|
||||
NetworkPacket::NetworkPacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength) {
|
||||
copyContents(address, packetData, packetLength);
|
||||
NetworkPacket::NetworkPacket(const HifiSockAddr& sockAddr, unsigned char* packetData, ssize_t packetLength) {
|
||||
copyContents(sockAddr, packetData, packetLength);
|
||||
};
|
||||
|
||||
// copy assignment
|
||||
NetworkPacket& NetworkPacket::operator=(NetworkPacket const& other) {
|
||||
copyContents(other.getAddress(), other.getData(), other.getLength());
|
||||
copyContents(other.getSockAddr(), other.getData(), other.getLength());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <ifaddrs.h>
|
||||
|
||||
#include "HifiSockAddr.h"
|
||||
|
||||
#include "NodeList.h" // for MAX_PACKET_SIZE
|
||||
|
||||
/// Storage of not-yet processed inbound, or not yet sent outbound generic UDP network packet
|
||||
|
@ -30,19 +32,19 @@ public:
|
|||
NetworkPacket& operator= (NetworkPacket&& other); // move assignment
|
||||
#endif
|
||||
|
||||
NetworkPacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength);
|
||||
NetworkPacket(const HifiSockAddr& sockAddr, unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
sockaddr& getAddress() { return _address; }
|
||||
const HifiSockAddr& getSockAddr() const { return _sockAddr; }
|
||||
ssize_t getLength() const { return _packetLength; }
|
||||
unsigned char* getData() { return &_packetData[0]; }
|
||||
|
||||
const sockaddr& getAddress() const { return _address; }
|
||||
const HifiSockAddr& getAddress() const { return _sockAddr; }
|
||||
const unsigned char* getData() const { return &_packetData[0]; }
|
||||
|
||||
private:
|
||||
void copyContents(const sockaddr& address, const unsigned char* packetData, ssize_t packetLength);
|
||||
void copyContents(const HifiSockAddr& sockAddr, const unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
sockaddr _address;
|
||||
HifiSockAddr _sockAddr;
|
||||
ssize_t _packetLength;
|
||||
unsigned char _packetData[MAX_PACKET_SIZE];
|
||||
};
|
||||
|
|
|
@ -19,30 +19,25 @@
|
|||
#include "Node.h"
|
||||
#include "NodeTypes.h"
|
||||
#include "SharedUtil.h"
|
||||
#include "UDPSocket.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
Node::Node(const QUuid& uuid, char type, sockaddr* publicSocket, sockaddr* localSocket) :
|
||||
Node::Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) :
|
||||
_type(type),
|
||||
_uuid(uuid),
|
||||
_wakeMicrostamp(usecTimestampNow()),
|
||||
_lastHeardMicrostamp(usecTimestampNow()),
|
||||
_publicSocket(publicSocket),
|
||||
_localSocket(localSocket),
|
||||
_activeSocket(NULL),
|
||||
_bytesReceivedMovingAverage(NULL),
|
||||
_linkedData(NULL),
|
||||
_isAlive(true)
|
||||
{
|
||||
setPublicSocket(publicSocket);
|
||||
setLocalSocket(localSocket);
|
||||
|
||||
pthread_mutex_init(&_mutex, 0);
|
||||
}
|
||||
|
||||
Node::~Node() {
|
||||
delete _publicSocket;
|
||||
delete _localSocket;
|
||||
|
||||
if (_linkedData) {
|
||||
_linkedData->deleteOrDeleteLater();
|
||||
}
|
||||
|
@ -86,47 +81,32 @@ const char* Node::getTypeName() const {
|
|||
}
|
||||
}
|
||||
|
||||
void Node::setPublicSocket(sockaddr* publicSocket) {
|
||||
if (_activeSocket == _publicSocket) {
|
||||
void Node::setPublicSocket(const HifiSockAddr& publicSocket) {
|
||||
if (_activeSocket == &_publicSocket) {
|
||||
// if the active socket was the public socket then reset it to NULL
|
||||
_activeSocket = NULL;
|
||||
}
|
||||
|
||||
if (publicSocket) {
|
||||
_publicSocket = new sockaddr(*publicSocket);
|
||||
} else {
|
||||
_publicSocket = NULL;
|
||||
}
|
||||
_publicSocket = publicSocket;
|
||||
}
|
||||
|
||||
void Node::setLocalSocket(sockaddr* localSocket) {
|
||||
if (_activeSocket == _localSocket) {
|
||||
void Node::setLocalSocket(const HifiSockAddr& localSocket) {
|
||||
if (_activeSocket == &_localSocket) {
|
||||
// if the active socket was the local socket then reset it to NULL
|
||||
_activeSocket = NULL;
|
||||
}
|
||||
|
||||
if (localSocket) {
|
||||
_localSocket = new sockaddr(*localSocket);
|
||||
} else {
|
||||
_localSocket = NULL;
|
||||
}
|
||||
_localSocket = localSocket;
|
||||
}
|
||||
|
||||
void Node::activateLocalSocket() {
|
||||
qDebug() << "Activating local socket for node" << *this << "\n";
|
||||
_activeSocket = _localSocket;
|
||||
_activeSocket = &_localSocket;
|
||||
}
|
||||
|
||||
void Node::activatePublicSocket() {
|
||||
qDebug() << "Activating public socket for node" << *this << "\n";
|
||||
_activeSocket = _publicSocket;
|
||||
}
|
||||
|
||||
bool Node::matches(sockaddr* otherPublicSocket, sockaddr* otherLocalSocket, char otherNodeType) {
|
||||
// checks if two node objects are the same node (same type + local + public address)
|
||||
return _type == otherNodeType
|
||||
&& socketMatch(_publicSocket, otherPublicSocket)
|
||||
&& socketMatch(_localSocket, otherLocalSocket);
|
||||
_activeSocket = &_publicSocket;
|
||||
}
|
||||
|
||||
void Node::recordBytesReceived(int bytesReceived) {
|
||||
|
@ -154,15 +134,8 @@ float Node::getAverageKilobitsPerSecond() {
|
|||
}
|
||||
|
||||
QDebug operator<<(QDebug debug, const Node &node) {
|
||||
char publicAddressBuffer[16] = {'\0'};
|
||||
unsigned short publicAddressPort = loadBufferWithSocketInfo(publicAddressBuffer, node.getPublicSocket());
|
||||
|
||||
char localAddressBuffer[16] = {'\0'};
|
||||
unsigned short localAddressPort = loadBufferWithSocketInfo(localAddressBuffer, node.getLocalSocket());
|
||||
|
||||
debug.nospace() << node.getTypeName() << " (" << node.getType() << ")";
|
||||
debug << " " << node.getUUID().toString().toLocal8Bit().constData() << " ";
|
||||
debug.nospace() << publicAddressBuffer << ":" << publicAddressPort;
|
||||
debug.nospace() << " / " << localAddressBuffer << ":" << localAddressPort;
|
||||
debug.nospace() << node.getLocalSocket() << "/" << node.getPublicSocket();
|
||||
return debug.nospace();
|
||||
}
|
||||
|
|
|
@ -21,19 +21,18 @@
|
|||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include "HifiSockAddr.h"
|
||||
#include "NodeData.h"
|
||||
#include "SimpleMovingAverage.h"
|
||||
|
||||
class Node {
|
||||
public:
|
||||
Node(const QUuid& uuid, char type, sockaddr* publicSocket, sockaddr* localSocket);
|
||||
Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||
~Node();
|
||||
|
||||
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }
|
||||
bool operator!=(const Node& otherNode) const { return !(*this == otherNode); }
|
||||
|
||||
bool matches(sockaddr* otherPublicSocket, sockaddr* otherLocalSocket, char otherNodeType);
|
||||
|
||||
char getType() const { return _type; }
|
||||
void setType(char type) { _type = type; }
|
||||
const char* getTypeName() const;
|
||||
|
@ -47,12 +46,12 @@ public:
|
|||
uint64_t getLastHeardMicrostamp() const { return _lastHeardMicrostamp; }
|
||||
void setLastHeardMicrostamp(uint64_t lastHeardMicrostamp) { _lastHeardMicrostamp = lastHeardMicrostamp; }
|
||||
|
||||
sockaddr* getPublicSocket() const { return _publicSocket; }
|
||||
void setPublicSocket(sockaddr* publicSocket);
|
||||
sockaddr* getLocalSocket() const { return _localSocket; }
|
||||
void setLocalSocket(sockaddr* localSocket);
|
||||
const HifiSockAddr& getPublicSocket() const { return _publicSocket; }
|
||||
void setPublicSocket(const HifiSockAddr& publicSocket);
|
||||
const HifiSockAddr& getLocalSocket() const { return _localSocket; }
|
||||
void setLocalSocket(const HifiSockAddr& localSocket);
|
||||
|
||||
sockaddr* getActiveSocket() const { return _activeSocket; }
|
||||
const HifiSockAddr* getActiveSocket() const { return _activeSocket; }
|
||||
|
||||
void activatePublicSocket();
|
||||
void activateLocalSocket();
|
||||
|
@ -87,9 +86,9 @@ private:
|
|||
QUuid _uuid;
|
||||
uint64_t _wakeMicrostamp;
|
||||
uint64_t _lastHeardMicrostamp;
|
||||
sockaddr* _publicSocket;
|
||||
sockaddr* _localSocket;
|
||||
sockaddr* _activeSocket;
|
||||
HifiSockAddr _publicSocket;
|
||||
HifiSockAddr _localSocket;
|
||||
HifiSockAddr* _activeSocket;
|
||||
SimpleMovingAverage* _bytesReceivedMovingAverage;
|
||||
NodeData* _linkedData;
|
||||
bool _isAlive;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <QtNetwork/QHostInfo>
|
||||
|
||||
#include "Assignment.h"
|
||||
#include "HifiSockAddr.h"
|
||||
#include "Logging.h"
|
||||
#include "NodeList.h"
|
||||
#include "NodeTypes.h"
|
||||
|
@ -61,22 +62,20 @@ NodeList* NodeList::getInstance() {
|
|||
|
||||
NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) :
|
||||
_domainHostname(DEFAULT_DOMAIN_HOSTNAME),
|
||||
_domainIP(),
|
||||
_domainPort(DEFAULT_DOMAIN_SERVER_PORT),
|
||||
_domainSockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)),
|
||||
_nodeBuckets(),
|
||||
_numNodes(0),
|
||||
_nodeSocket(newSocketListenPort),
|
||||
_nodeSocket(),
|
||||
_ownerType(newOwnerType),
|
||||
_nodeTypesOfInterest(NULL),
|
||||
_ownerUUID(QUuid::createUuid()),
|
||||
_numNoReplyDomainCheckIns(0),
|
||||
_assignmentServerSocket(NULL),
|
||||
_publicAddress(),
|
||||
_publicPort(0),
|
||||
_assignmentServerSocket(),
|
||||
_publicSockAddr(),
|
||||
_hasCompletedInitialSTUNFailure(false),
|
||||
_stunRequestsSinceSuccess(0)
|
||||
{
|
||||
|
||||
_nodeSocket.bind(QHostAddress::LocalHost, newSocketListenPort);
|
||||
}
|
||||
|
||||
NodeList::~NodeList() {
|
||||
|
@ -100,29 +99,29 @@ void NodeList::setDomainHostname(const QString& domainHostname) {
|
|||
_domainHostname = domainHostname.left(colonIndex);
|
||||
|
||||
// grab the port by reading the string after the colon
|
||||
_domainPort = atoi(domainHostname.mid(colonIndex + 1, domainHostname.size()).toLocal8Bit().constData());
|
||||
_domainSockAddr.setPort(atoi(domainHostname.mid(colonIndex + 1, domainHostname.size()).toLocal8Bit().constData()));
|
||||
|
||||
qDebug() << "Updated hostname to" << _domainHostname << "and port to" << _domainPort << "\n";
|
||||
qDebug() << "Updated hostname to" << _domainHostname << "and port to" << _domainSockAddr.getPort() << "\n";
|
||||
|
||||
} else {
|
||||
// no port included with the hostname, simply set the member variable and reset the domain server port to default
|
||||
_domainHostname = domainHostname;
|
||||
_domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||
_domainSockAddr.setPort(DEFAULT_DOMAIN_SERVER_PORT);
|
||||
}
|
||||
|
||||
// clear the NodeList so nodes from this domain are killed
|
||||
clear();
|
||||
|
||||
// reset our _domainIP to the null address so that a lookup happens on next check in
|
||||
_domainIP.clear();
|
||||
_domainSockAddr.setAddress(QHostAddress::Null);
|
||||
notifyDomainChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeList::timePingReply(sockaddr *nodeAddress, unsigned char *packetData) {
|
||||
void NodeList::timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData) {
|
||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
||||
if (socketMatch(node->getPublicSocket(), nodeAddress) ||
|
||||
socketMatch(node->getLocalSocket(), nodeAddress)) {
|
||||
if (node->getPublicSocket() == nodeAddress ||
|
||||
node->getLocalSocket() == nodeAddress) {
|
||||
|
||||
int pingTime = usecTimestampNow() - *(uint64_t*)(packetData + numBytesForPacketHeader(packetData));
|
||||
|
||||
|
@ -132,11 +131,11 @@ void NodeList::timePingReply(sockaddr *nodeAddress, unsigned char *packetData) {
|
|||
}
|
||||
}
|
||||
|
||||
void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetData, size_t dataBytes) {
|
||||
void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, unsigned char* packetData, size_t dataBytes) {
|
||||
switch (packetData[0]) {
|
||||
case PACKET_TYPE_DOMAIN: {
|
||||
// only process the DS if this is our current domain server
|
||||
if (_domainIP == QHostAddress(senderAddress)) {
|
||||
if (_domainSockAddr == senderSockAddr) {
|
||||
processDomainServerList(packetData, dataBytes);
|
||||
}
|
||||
|
||||
|
@ -145,15 +144,15 @@ void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetDat
|
|||
case PACKET_TYPE_PING: {
|
||||
// send it right back
|
||||
populateTypeAndVersion(packetData, PACKET_TYPE_PING_REPLY);
|
||||
_nodeSocket.send(senderAddress, packetData, dataBytes);
|
||||
_nodeSocket.writeDatagram((char*) packetData, dataBytes, senderSockAddr.getAddress(), senderSockAddr.getPort());
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_PING_REPLY: {
|
||||
// activate the appropriate socket for this node, if not yet updated
|
||||
activateSocketFromNodeCommunication(senderAddress);
|
||||
activateSocketFromNodeCommunication(senderSockAddr);
|
||||
|
||||
// set the ping time for this node for stat collection
|
||||
timePingReply(senderAddress, packetData);
|
||||
timePingReply(senderSockAddr, packetData);
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_STUN_RESPONSE: {
|
||||
|
@ -169,7 +168,7 @@ void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetDat
|
|||
}
|
||||
}
|
||||
|
||||
void NodeList::processBulkNodeData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes) {
|
||||
void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned char *packetData, int numTotalBytes) {
|
||||
|
||||
// find the avatar mixer in our node list and update the lastRecvTime from it
|
||||
Node* bulkSendNode = nodeWithAddress(senderAddress);
|
||||
|
@ -198,11 +197,11 @@ void NodeList::processBulkNodeData(sockaddr *senderAddress, unsigned char *packe
|
|||
|
||||
if (!matchingNode) {
|
||||
// we're missing this node, we need to add it to the list
|
||||
matchingNode = addOrUpdateNode(nodeUUID, NODE_TYPE_AGENT, NULL, NULL);
|
||||
matchingNode = addOrUpdateNode(nodeUUID, NODE_TYPE_AGENT, HifiSockAddr(), HifiSockAddr());
|
||||
}
|
||||
|
||||
currentPosition += updateNodeWithData(matchingNode,
|
||||
NULL,
|
||||
HifiSockAddr(),
|
||||
packetHolder,
|
||||
numTotalBytes - (currentPosition - startPosition));
|
||||
|
||||
|
@ -210,16 +209,16 @@ void NodeList::processBulkNodeData(sockaddr *senderAddress, unsigned char *packe
|
|||
}
|
||||
}
|
||||
|
||||
int NodeList::updateNodeWithData(Node *node, sockaddr* senderAddress, unsigned char *packetData, int dataBytes) {
|
||||
int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes) {
|
||||
node->lock();
|
||||
|
||||
node->setLastHeardMicrostamp(usecTimestampNow());
|
||||
|
||||
if (senderAddress) {
|
||||
activateSocketFromNodeCommunication(senderAddress);
|
||||
if (!senderSockAddr.isNull()) {
|
||||
activateSocketFromNodeCommunication(senderSockAddr);
|
||||
}
|
||||
|
||||
if (node->getActiveSocket() || !senderAddress) {
|
||||
if (node->getActiveSocket() || senderSockAddr.isNull()) {
|
||||
node->recordBytesReceived(dataBytes);
|
||||
|
||||
if (!node->getLinkedData() && linkedDataCreateCallback) {
|
||||
|
@ -238,9 +237,9 @@ int NodeList::updateNodeWithData(Node *node, sockaddr* senderAddress, unsigned c
|
|||
}
|
||||
}
|
||||
|
||||
Node* NodeList::nodeWithAddress(sockaddr *senderAddress) {
|
||||
Node* NodeList::nodeWithAddress(const HifiSockAddr &senderSockAddr) {
|
||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
||||
if (node->getActiveSocket() && socketMatch(node->getActiveSocket(), senderAddress)) {
|
||||
if (node->getActiveSocket() && *node->getActiveSocket() == senderSockAddr) {
|
||||
return &(*node);
|
||||
}
|
||||
}
|
||||
|
@ -350,10 +349,8 @@ void NodeList::sendSTUNRequest() {
|
|||
qDebug("Sending intial stun request to %s\n", stunIPAddress.toLocal8Bit().constData());
|
||||
}
|
||||
|
||||
_nodeSocket.send(stunIPAddress.toLocal8Bit().constData(),
|
||||
STUN_SERVER_PORT,
|
||||
stunRequestPacket,
|
||||
sizeof(stunRequestPacket));
|
||||
_nodeSocket.writeDatagram((char*) stunRequestPacket, sizeof(stunRequestPacket),
|
||||
QHostAddress(stunIPAddress), STUN_SERVER_PORT);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -372,8 +369,7 @@ void NodeList::sendSTUNRequest() {
|
|||
}
|
||||
|
||||
// reset the public address and port
|
||||
_publicAddress = QHostAddress::Null;
|
||||
_publicPort = 0;
|
||||
_publicSockAddr = HifiSockAddr();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,13 +421,12 @@ void NodeList::processSTUNResponse(unsigned char* packetData, size_t dataBytes)
|
|||
|
||||
QHostAddress newPublicAddress = QHostAddress(stunAddress);
|
||||
|
||||
if (newPublicAddress != _publicAddress || newPublicPort != _publicPort) {
|
||||
_publicAddress = newPublicAddress;
|
||||
_publicPort = newPublicPort;
|
||||
if (newPublicAddress != _publicSockAddr.getAddress() || newPublicPort != _publicSockAddr.getPort()) {
|
||||
_publicSockAddr = HifiSockAddr(newPublicAddress, newPublicPort);
|
||||
|
||||
qDebug("New public socket received from STUN server is %s:%hu\n",
|
||||
_publicAddress.toString().toLocal8Bit().constData(),
|
||||
_publicPort);
|
||||
_publicSockAddr.getAddress().toString().toLocal8Bit().constData(),
|
||||
_publicSockAddr.getPort());
|
||||
|
||||
}
|
||||
|
||||
|
@ -489,17 +484,17 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
static bool printedDomainServerIP = false;
|
||||
|
||||
// Lookup the IP address of the domain server if we need to
|
||||
if (_domainIP.isNull()) {
|
||||
if (_domainSockAddr.getAddress().isNull()) {
|
||||
qDebug("Looking up DS hostname %s.\n", _domainHostname.toLocal8Bit().constData());
|
||||
|
||||
QHostInfo domainServerHostInfo = QHostInfo::fromName(_domainHostname);
|
||||
|
||||
for (int i = 0; i < domainServerHostInfo.addresses().size(); i++) {
|
||||
if (domainServerHostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) {
|
||||
_domainIP = domainServerHostInfo.addresses()[i];
|
||||
_domainSockAddr.setAddress(domainServerHostInfo.addresses()[i]);
|
||||
|
||||
qDebug("DS at %s is at %s\n", _domainHostname.toLocal8Bit().constData(),
|
||||
_domainIP.toString().toLocal8Bit().constData());
|
||||
_domainSockAddr.getAddress().toString().toLocal8Bit().constData());
|
||||
|
||||
printedDomainServerIP = true;
|
||||
|
||||
|
@ -512,11 +507,11 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
}
|
||||
}
|
||||
} else if (!printedDomainServerIP) {
|
||||
qDebug("Domain Server IP: %s\n", _domainIP.toString().toLocal8Bit().constData());
|
||||
qDebug("Domain Server IP: %s\n", _domainSockAddr.getAddress().toString().toLocal8Bit().constData());
|
||||
printedDomainServerIP = true;
|
||||
}
|
||||
|
||||
if (_publicAddress.isNull() && !_hasCompletedInitialSTUNFailure) {
|
||||
if (_publicSockAddr.isNull() && !_hasCompletedInitialSTUNFailure) {
|
||||
// we don't know our public socket and we need to send it to the domain server
|
||||
// send a STUN request to figure it out
|
||||
sendSTUNRequest();
|
||||
|
@ -548,13 +543,11 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
packetPosition += rfcOwnerUUID.size();
|
||||
|
||||
// pack our public address to send to domain-server
|
||||
packetPosition += packSocket(checkInPacket + (packetPosition - checkInPacket),
|
||||
htonl(_publicAddress.toIPv4Address()), htons(_publicPort));
|
||||
packetPosition += HifiSockAddr::packSockAddr(checkInPacket + (packetPosition - checkInPacket), _publicSockAddr);
|
||||
|
||||
// pack our local address to send to domain-server
|
||||
packetPosition += packSocket(checkInPacket + (packetPosition - checkInPacket),
|
||||
getLocalAddress(),
|
||||
htons(_nodeSocket.getListeningPort()));
|
||||
packetPosition += HifiSockAddr::packSockAddr(checkInPacket + (packetPosition - checkInPacket),
|
||||
HifiSockAddr(_nodeSocket.localAddress(), _nodeSocket.localPort()));
|
||||
|
||||
// add the number of bytes for node types of interest
|
||||
*(packetPosition++) = numBytesNodesOfInterest;
|
||||
|
@ -567,9 +560,8 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
packetPosition += numBytesNodesOfInterest;
|
||||
}
|
||||
|
||||
_nodeSocket.send(_domainIP.toString().toLocal8Bit().constData(), _domainPort, checkInPacket,
|
||||
packetPosition - checkInPacket);
|
||||
|
||||
_nodeSocket.writeDatagram((char*) checkInPacket, packetPosition - checkInPacket,
|
||||
_domainSockAddr.getAddress(), _domainSockAddr.getPort());
|
||||
const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5;
|
||||
static unsigned int numDomainCheckins = 0;
|
||||
|
||||
|
@ -592,10 +584,8 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte
|
|||
char nodeType;
|
||||
|
||||
// assumes only IPv4 addresses
|
||||
sockaddr_in nodePublicSocket;
|
||||
nodePublicSocket.sin_family = AF_INET;
|
||||
sockaddr_in nodeLocalSocket;
|
||||
nodeLocalSocket.sin_family = AF_INET;
|
||||
HifiSockAddr nodePublicSocket;
|
||||
HifiSockAddr nodeLocalSocket;
|
||||
|
||||
unsigned char* readPtr = packetData + numBytesForPacketHeader(packetData);
|
||||
unsigned char* startPtr = packetData;
|
||||
|
@ -605,24 +595,24 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte
|
|||
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*) readPtr, NUM_BYTES_RFC4122_UUID));
|
||||
readPtr += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
readPtr += unpackSocket(readPtr, (sockaddr*) &nodePublicSocket);
|
||||
readPtr += unpackSocket(readPtr, (sockaddr*) &nodeLocalSocket);
|
||||
readPtr += HifiSockAddr::unpackSockAddr(readPtr, nodePublicSocket);
|
||||
readPtr += HifiSockAddr::unpackSockAddr(readPtr, nodeLocalSocket);
|
||||
|
||||
// if the public socket address is 0 then it's reachable at the same IP
|
||||
// as the domain server
|
||||
if (nodePublicSocket.sin_addr.s_addr == 0) {
|
||||
nodePublicSocket.sin_addr.s_addr = htonl(_domainIP.toIPv4Address());
|
||||
if (nodePublicSocket.getAddress().isNull()) {
|
||||
nodePublicSocket.setAddress(_domainSockAddr.getAddress());
|
||||
}
|
||||
|
||||
addOrUpdateNode(nodeUUID, nodeType, (sockaddr*) &nodePublicSocket, (sockaddr*) &nodeLocalSocket);
|
||||
addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket);
|
||||
}
|
||||
|
||||
|
||||
return readNodes;
|
||||
}
|
||||
|
||||
const sockaddr_in DEFAULT_LOCAL_ASSIGNMENT_SOCKET = socketForHostnameAndHostOrderPort(LOCAL_ASSIGNMENT_SERVER_HOSTNAME,
|
||||
DEFAULT_DOMAIN_SERVER_PORT);
|
||||
const HifiSockAddr DEFAULT_LOCAL_ASSIGNMENT_SOCKET = HifiSockAddr(QHostAddress(LOCAL_ASSIGNMENT_SERVER_HOSTNAME),
|
||||
DEFAULT_DOMAIN_SERVER_PORT);
|
||||
void NodeList::sendAssignment(Assignment& assignment) {
|
||||
unsigned char assignmentPacket[MAX_PACKET_SIZE];
|
||||
|
||||
|
@ -633,14 +623,16 @@ void NodeList::sendAssignment(Assignment& assignment) {
|
|||
int numHeaderBytes = populateTypeAndVersion(assignmentPacket, assignmentPacketType);
|
||||
int numAssignmentBytes = assignment.packToBuffer(assignmentPacket + numHeaderBytes);
|
||||
|
||||
sockaddr* assignmentServerSocket = (_assignmentServerSocket == NULL)
|
||||
? (sockaddr*) &DEFAULT_LOCAL_ASSIGNMENT_SOCKET
|
||||
: _assignmentServerSocket;
|
||||
const HifiSockAddr* assignmentServerSocket = _assignmentServerSocket.isNull()
|
||||
? &DEFAULT_LOCAL_ASSIGNMENT_SOCKET
|
||||
: &_assignmentServerSocket;
|
||||
|
||||
_nodeSocket.send(assignmentServerSocket, assignmentPacket, numHeaderBytes + numAssignmentBytes);
|
||||
_nodeSocket.writeDatagram((char*) assignmentPacket, numHeaderBytes + numAssignmentBytes,
|
||||
assignmentServerSocket->getAddress(),
|
||||
assignmentServerSocket->getPort());
|
||||
}
|
||||
|
||||
void NodeList::pingPublicAndLocalSocketsForInactiveNode(Node* node) const {
|
||||
void NodeList::pingPublicAndLocalSocketsForInactiveNode(Node* node) {
|
||||
|
||||
uint64_t currentTime = 0;
|
||||
|
||||
|
@ -652,11 +644,14 @@ void NodeList::pingPublicAndLocalSocketsForInactiveNode(Node* node) const {
|
|||
memcpy(pingPacket + numHeaderBytes, ¤tTime, sizeof(currentTime));
|
||||
|
||||
// send the ping packet to the local and public sockets for this node
|
||||
_nodeSocket.send(node->getLocalSocket(), pingPacket, sizeof(pingPacket));
|
||||
_nodeSocket.send(node->getPublicSocket(), pingPacket, sizeof(pingPacket));
|
||||
_nodeSocket.writeDatagram((char*) pingPacket, sizeof(pingPacket),
|
||||
node->getLocalSocket().getAddress(), node->getLocalSocket().getPort());
|
||||
_nodeSocket.writeDatagram((char*) pingPacket, sizeof(pingPacket),
|
||||
node->getPublicSocket().getAddress(), node->getPublicSocket().getPort());
|
||||
}
|
||||
|
||||
Node* NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType, sockaddr* publicSocket, sockaddr* localSocket) {
|
||||
Node* NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
|
||||
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
|
||||
NodeList::iterator node = end();
|
||||
|
||||
for (node = begin(); node != end(); node++) {
|
||||
|
@ -684,12 +679,12 @@ Node* NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType, sockaddr* publ
|
|||
}
|
||||
|
||||
// check if we need to change this node's public or local sockets
|
||||
if (!socketMatch(publicSocket, node->getPublicSocket())) {
|
||||
if (publicSocket != node->getPublicSocket()) {
|
||||
node->setPublicSocket(publicSocket);
|
||||
qDebug() << "Public socket change for node" << *node << "\n";
|
||||
}
|
||||
|
||||
if (!socketMatch(localSocket, node->getLocalSocket())) {
|
||||
if (localSocket != node->getLocalSocket()) {
|
||||
node->setLocalSocket(localSocket);
|
||||
qDebug() << "Local socket change for node" << *node << "\n";
|
||||
}
|
||||
|
@ -725,7 +720,8 @@ unsigned NodeList::broadcastToNodes(unsigned char* broadcastData, size_t dataByt
|
|||
if (memchr(nodeTypes, node->getType(), numNodeTypes)) {
|
||||
if (getNodeActiveSocketOrPing(&(*node))) {
|
||||
// we know which socket is good for this node, send there
|
||||
_nodeSocket.send(node->getActiveSocket(), broadcastData, dataBytes);
|
||||
_nodeSocket.writeDatagram((char*) broadcastData, dataBytes,
|
||||
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
@ -751,7 +747,7 @@ void NodeList::possiblyPingInactiveNodes() {
|
|||
}
|
||||
}
|
||||
|
||||
sockaddr* NodeList::getNodeActiveSocketOrPing(Node* node) {
|
||||
const HifiSockAddr* NodeList::getNodeActiveSocketOrPing(Node* node) {
|
||||
if (node->getActiveSocket()) {
|
||||
return node->getActiveSocket();
|
||||
} else {
|
||||
|
@ -760,15 +756,15 @@ sockaddr* NodeList::getNodeActiveSocketOrPing(Node* node) {
|
|||
}
|
||||
}
|
||||
|
||||
void NodeList::activateSocketFromNodeCommunication(sockaddr *nodeAddress) {
|
||||
void NodeList::activateSocketFromNodeCommunication(const HifiSockAddr& nodeAddress) {
|
||||
for(NodeList::iterator node = begin(); node != end(); node++) {
|
||||
if (!node->getActiveSocket()) {
|
||||
// check both the public and local addresses for each node to see if we find a match
|
||||
// prioritize the private address so that we prune erroneous local matches
|
||||
if (socketMatch(node->getPublicSocket(), nodeAddress)) {
|
||||
if (node->getPublicSocket() == nodeAddress) {
|
||||
node->activatePublicSocket();
|
||||
break;
|
||||
} else if (socketMatch(node->getLocalSocket(), nodeAddress)) {
|
||||
} else if (node->getLocalSocket() == nodeAddress) {
|
||||
node->activateLocalSocket();
|
||||
break;
|
||||
}
|
||||
|
@ -969,7 +965,7 @@ void NodeListIterator::skipDeadAndStopIncrement() {
|
|||
|
||||
void NodeList::addDomainListener(DomainChangeListener* listener) {
|
||||
_domainListeners.push_back(listener);
|
||||
QString domain = _domainHostname.isEmpty() ? _domainIP.toString() : _domainHostname;
|
||||
QString domain = _domainHostname.isEmpty() ? _domainSockAddr.getAddress().toString() : _domainHostname;
|
||||
listener->domainChanged(domain);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include <QtNetwork/QHostAddress>
|
||||
#include <QtNetwork/QUdpSocket>
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
#include "Node.h"
|
||||
#include "NodeTypes.h"
|
||||
#include "UDPSocket.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "pthread.h"
|
||||
|
@ -45,6 +45,7 @@ const char LOCAL_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost";
|
|||
const int MAX_SILENT_DOMAIN_SERVER_CHECK_INS = 5;
|
||||
|
||||
class Assignment;
|
||||
class HifiSockAddr;
|
||||
class NodeListIterator;
|
||||
|
||||
// Callers who want to hook add/kill callbacks should implement this class
|
||||
|
@ -75,19 +76,15 @@ public:
|
|||
const QString& getDomainHostname() const { return _domainHostname; }
|
||||
void setDomainHostname(const QString& domainHostname);
|
||||
|
||||
const QHostAddress& getDomainIP() const { return _domainIP; }
|
||||
void setDomainIP(const QHostAddress& domainIP) { _domainIP = domainIP; }
|
||||
void setDomainIPToLocalhost() { _domainIP = QHostAddress(INADDR_LOOPBACK); }
|
||||
const QHostAddress& getDomainIP() const { return _domainSockAddr.getAddress(); }
|
||||
void setDomainIPToLocalhost() { _domainSockAddr.setAddress(QHostAddress(INADDR_LOOPBACK)); }
|
||||
|
||||
unsigned short getDomainPort() const { return _domainPort; }
|
||||
void setDomainPort(unsigned short domainPort) { _domainPort = domainPort; }
|
||||
unsigned short getDomainPort() const { return _domainSockAddr.getPort(); }
|
||||
|
||||
const QUuid& getOwnerUUID() const { return _ownerUUID; }
|
||||
void setOwnerUUID(const QUuid& ownerUUID) { _ownerUUID = ownerUUID; }
|
||||
|
||||
UDPSocket* getNodeSocket() { return &_nodeSocket; }
|
||||
|
||||
unsigned short int getSocketListenPort() const { return _nodeSocket.getListeningPort(); }
|
||||
QUdpSocket& getNodeSocket() { return _nodeSocket; }
|
||||
|
||||
void(*linkedDataCreateCallback)(Node *);
|
||||
|
||||
|
@ -104,23 +101,23 @@ public:
|
|||
void sendDomainServerCheckIn();
|
||||
int processDomainServerList(unsigned char *packetData, size_t dataBytes);
|
||||
|
||||
void setAssignmentServerSocket(sockaddr* serverSocket) { _assignmentServerSocket = serverSocket; }
|
||||
void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; }
|
||||
void sendAssignment(Assignment& assignment);
|
||||
|
||||
void pingPublicAndLocalSocketsForInactiveNode(Node* node) const;
|
||||
void pingPublicAndLocalSocketsForInactiveNode(Node* node);
|
||||
|
||||
void sendKillNode(const char* nodeTypes, int numNodeTypes);
|
||||
|
||||
Node* nodeWithAddress(sockaddr *senderAddress);
|
||||
Node* nodeWithAddress(const HifiSockAddr& senderSockAddr);
|
||||
Node* nodeWithUUID(const QUuid& nodeUUID);
|
||||
|
||||
Node* addOrUpdateNode(const QUuid& uuid, char nodeType, sockaddr* publicSocket, sockaddr* localSocket);
|
||||
Node* addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||
void killNode(Node* node, bool mustLockNode = true);
|
||||
|
||||
void processNodeData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes);
|
||||
void processBulkNodeData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes);
|
||||
void processNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, size_t dataBytes);
|
||||
void processBulkNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, int numTotalBytes);
|
||||
|
||||
int updateNodeWithData(Node *node, sockaddr* senderAddress, unsigned char *packetData, int dataBytes);
|
||||
int updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes);
|
||||
|
||||
unsigned broadcastToNodes(unsigned char *broadcastData, size_t dataBytes, const char* nodeTypes, int numNodeTypes);
|
||||
|
||||
|
@ -143,7 +140,7 @@ public:
|
|||
void removeDomainListener(DomainChangeListener* listener);
|
||||
|
||||
void possiblyPingInactiveNodes();
|
||||
sockaddr* getNodeActiveSocketOrPing(Node* node);
|
||||
const HifiSockAddr* getNodeActiveSocketOrPing(Node* node);
|
||||
private:
|
||||
static NodeList* _sharedInstance;
|
||||
|
||||
|
@ -160,25 +157,23 @@ private:
|
|||
void processKillNode(unsigned char* packetData, size_t dataBytes);
|
||||
|
||||
QString _domainHostname;
|
||||
QHostAddress _domainIP;
|
||||
unsigned short _domainPort;
|
||||
HifiSockAddr _domainSockAddr;
|
||||
Node** _nodeBuckets[MAX_NUM_NODES / NODES_PER_BUCKET];
|
||||
int _numNodes;
|
||||
UDPSocket _nodeSocket;
|
||||
QUdpSocket _nodeSocket;
|
||||
char _ownerType;
|
||||
char* _nodeTypesOfInterest;
|
||||
QUuid _ownerUUID;
|
||||
pthread_t removeSilentNodesThread;
|
||||
pthread_t checkInWithDomainServerThread;
|
||||
int _numNoReplyDomainCheckIns;
|
||||
sockaddr* _assignmentServerSocket;
|
||||
QHostAddress _publicAddress;
|
||||
uint16_t _publicPort;
|
||||
HifiSockAddr _assignmentServerSocket;
|
||||
HifiSockAddr _publicSockAddr;
|
||||
bool _hasCompletedInitialSTUNFailure;
|
||||
unsigned int _stunRequestsSinceSuccess;
|
||||
|
||||
void activateSocketFromNodeCommunication(sockaddr *nodeAddress);
|
||||
void timePingReply(sockaddr *nodeAddress, unsigned char *packetData);
|
||||
void activateSocketFromNodeCommunication(const HifiSockAddr& nodeSockAddr);
|
||||
void timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData);
|
||||
|
||||
std::vector<NodeListHook*> _hooks;
|
||||
std::vector<DomainChangeListener*> _domainListeners;
|
||||
|
|
|
@ -44,7 +44,7 @@ PacketSender::PacketSender(PacketSenderNotify* notify, int packetsPerSecond) :
|
|||
}
|
||||
|
||||
|
||||
void PacketSender::queuePacketForSending(sockaddr& address, unsigned char* packetData, ssize_t packetLength) {
|
||||
void PacketSender::queuePacketForSending(const HifiSockAddr& address, unsigned char* packetData, ssize_t packetLength) {
|
||||
NetworkPacket packet(address, packetData, packetLength);
|
||||
lock();
|
||||
_packets.push_back(packet);
|
||||
|
@ -334,9 +334,9 @@ bool PacketSender::nonThreadedProcess() {
|
|||
unlock();
|
||||
|
||||
// send the packet through the NodeList...
|
||||
UDPSocket* nodeSocket = NodeList::getInstance()->getNodeSocket();
|
||||
|
||||
nodeSocket->send(&temporary.getAddress(), temporary.getData(), temporary.getLength());
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) temporary.getData(), temporary.getLength(),
|
||||
temporary.getSockAddr().getAddress(),
|
||||
temporary.getSockAddr().getPort());
|
||||
packetsSentThisCall++;
|
||||
_packetsOverCheckInterval++;
|
||||
_totalPacketsSent++;
|
||||
|
|
|
@ -38,11 +38,11 @@ public:
|
|||
PacketSender(PacketSenderNotify* notify = NULL, int packetsPerSecond = DEFAULT_PACKETS_PER_SECOND);
|
||||
|
||||
/// Add packet to outbound queue.
|
||||
/// \param sockaddr& address the destination address
|
||||
/// \param HifiSockAddr& address the destination address
|
||||
/// \param packetData pointer to data
|
||||
/// \param ssize_t packetLength size of data
|
||||
/// \thread any thread, typically the application thread
|
||||
void queuePacketForSending(sockaddr& address, unsigned char* packetData, ssize_t packetLength);
|
||||
void queuePacketForSending(const HifiSockAddr& address, unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
void setPacketsPerSecond(int packetsPerSecond)
|
||||
{ _packetsPerSecond = std::max(MINIMUM_PACKETS_PER_SECOND, packetsPerSecond); }
|
||||
|
|
|
@ -16,9 +16,9 @@ ReceivedPacketProcessor::ReceivedPacketProcessor() {
|
|||
_dontSleep = false;
|
||||
}
|
||||
|
||||
void ReceivedPacketProcessor::queueReceivedPacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength) {
|
||||
void ReceivedPacketProcessor::queueReceivedPacket(const HifiSockAddr& address, unsigned char* packetData, ssize_t packetLength) {
|
||||
// Make sure our Node and NodeList knows we've heard from this node.
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(&address);
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(address);
|
||||
if (node) {
|
||||
node->setLastHeardMicrostamp(usecTimestampNow());
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ bool ReceivedPacketProcessor::process() {
|
|||
NetworkPacket temporary = packet; // make a copy of the packet in case the vector is resized on us
|
||||
_packets.erase(_packets.begin()); // remove the oldest packet
|
||||
unlock(); // let others add to the packets
|
||||
processPacket(temporary.getAddress(), temporary.getData(), temporary.getLength()); // process our temporary copy
|
||||
processPacket(temporary.getSockAddr(), temporary.getData(), temporary.getLength()); // process our temporary copy
|
||||
}
|
||||
return isStillRunning(); // keep running till they terminate us
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ public:
|
|||
/// \param packetData pointer to received data
|
||||
/// \param ssize_t packetLength size of received data
|
||||
/// \thread network receive thread
|
||||
void queueReceivedPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
void queueReceivedPacket(const HifiSockAddr& senderSockAddr, unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
/// Are there received packets waiting to be processed
|
||||
bool hasPacketsToProcess() const { return _packets.size() > 0; }
|
||||
|
@ -38,7 +38,7 @@ protected:
|
|||
/// \param packetData pointer to received data
|
||||
/// \param ssize_t packetLength size of received data
|
||||
/// \thread "this" individual processing thread
|
||||
virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) = 0;
|
||||
virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) = 0;
|
||||
|
||||
/// Implements generic processing behavior for this thread.
|
||||
virtual bool process();
|
||||
|
|
|
@ -1,293 +0,0 @@
|
|||
//
|
||||
// UDPSocket.cpp
|
||||
// interface
|
||||
//
|
||||
// Created by Stephen Birarda on 1/28/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <cstdio>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Syssocket.h"
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtNetwork/QNetworkInterface>
|
||||
#include <QtNetwork/QHostAddress>
|
||||
|
||||
#include "Logging.h"
|
||||
#include "UDPSocket.h"
|
||||
|
||||
sockaddr_in destSockaddr, senderAddress;
|
||||
|
||||
bool socketMatch(const sockaddr* first, const sockaddr* second) {
|
||||
if (first != NULL && second != NULL) {
|
||||
// utility function that indicates if two sockets are equivalent
|
||||
|
||||
// currently only compares two IPv4 addresses
|
||||
// expandable to IPv6 by adding else if for AF_INET6
|
||||
|
||||
if (first->sa_family != second->sa_family) {
|
||||
// not the same family, can't be equal
|
||||
return false;
|
||||
} else if (first->sa_family == AF_INET) {
|
||||
const sockaddr_in *firstIn = (const sockaddr_in *) first;
|
||||
const sockaddr_in *secondIn = (const sockaddr_in *) second;
|
||||
|
||||
return firstIn->sin_addr.s_addr == secondIn->sin_addr.s_addr
|
||||
&& firstIn->sin_port == secondIn->sin_port;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int packSocket(unsigned char* packStore, in_addr_t inAddress, in_port_t networkOrderPort) {
|
||||
packStore[0] = inAddress >> 24;
|
||||
packStore[1] = inAddress >> 16;
|
||||
packStore[2] = inAddress >> 8;
|
||||
packStore[3] = inAddress;
|
||||
|
||||
packStore[4] = networkOrderPort >> 8;
|
||||
packStore[5] = networkOrderPort;
|
||||
|
||||
return 6; // could be dynamically more if we need IPv6
|
||||
}
|
||||
|
||||
int packSocket(unsigned char* packStore, sockaddr* socketToPack) {
|
||||
return packSocket(packStore, ((sockaddr_in*) socketToPack)->sin_addr.s_addr, ((sockaddr_in*) socketToPack)->sin_port);
|
||||
}
|
||||
|
||||
int unpackSocket(const unsigned char* packedData, sockaddr* unpackDestSocket) {
|
||||
sockaddr_in* destinationSocket = (sockaddr_in*) unpackDestSocket;
|
||||
destinationSocket->sin_family = AF_INET;
|
||||
destinationSocket->sin_addr.s_addr = (packedData[0] << 24) + (packedData[1] << 16) + (packedData[2] << 8) + packedData[3];
|
||||
destinationSocket->sin_port = (packedData[4] << 8) + packedData[5];
|
||||
return 6; // this could be more if we ever need IPv6
|
||||
}
|
||||
|
||||
void copySocketToEmptySocketPointer(sockaddr** destination, const sockaddr* source) {
|
||||
// create a new sockaddr or sockaddr_in depending on what type of address this is
|
||||
if (source->sa_family == AF_INET) {
|
||||
*destination = (sockaddr*) new sockaddr_in;
|
||||
memcpy(*destination, source, sizeof(sockaddr_in));
|
||||
} else {
|
||||
*destination = (sockaddr*) new sockaddr_in6;
|
||||
memcpy(*destination, source, sizeof(sockaddr_in6));
|
||||
}
|
||||
}
|
||||
|
||||
int getLocalAddress() {
|
||||
|
||||
static int localAddress = 0;
|
||||
|
||||
if (localAddress == 0) {
|
||||
foreach(const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) {
|
||||
if (interface.flags() & QNetworkInterface::IsUp
|
||||
&& interface.flags() & QNetworkInterface::IsRunning
|
||||
&& interface.flags() & ~QNetworkInterface::IsLoopBack) {
|
||||
// we've decided that this is the active NIC
|
||||
// enumerate it's addresses to grab the IPv4 address
|
||||
foreach(const QNetworkAddressEntry &entry, interface.addressEntries()) {
|
||||
// make sure it's an IPv4 address that isn't the loopback
|
||||
if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isLoopback()) {
|
||||
qDebug("Node's local address is %s\n", entry.ip().toString().toLocal8Bit().constData());
|
||||
|
||||
// set our localAddress and break out
|
||||
localAddress = htonl(entry.ip().toIPv4Address());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (localAddress != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return the looked up local address
|
||||
return localAddress;
|
||||
}
|
||||
|
||||
unsigned short loadBufferWithSocketInfo(char* addressBuffer, sockaddr* socket) {
|
||||
if (socket != NULL) {
|
||||
char* copyBuffer = inet_ntoa(((sockaddr_in*) socket)->sin_addr);
|
||||
memcpy(addressBuffer, copyBuffer, strlen(copyBuffer));
|
||||
return htons(((sockaddr_in*) socket)->sin_port);
|
||||
} else {
|
||||
const char* unknownAddress = "Unknown";
|
||||
memcpy(addressBuffer, unknownAddress, strlen(unknownAddress));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sockaddr_in socketForHostnameAndHostOrderPort(const char* hostname, unsigned short port) {
|
||||
struct hostent* pHostInfo;
|
||||
sockaddr_in newSocket = {};
|
||||
|
||||
if ((pHostInfo = gethostbyname(hostname))) {
|
||||
memcpy(&newSocket.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
|
||||
}
|
||||
|
||||
if (port != 0) {
|
||||
newSocket.sin_port = htons(port);
|
||||
}
|
||||
|
||||
return newSocket;
|
||||
}
|
||||
|
||||
UDPSocket::UDPSocket(unsigned short int listeningPort) :
|
||||
_listeningPort(listeningPort),
|
||||
blocking(true)
|
||||
{
|
||||
init();
|
||||
// create the socket
|
||||
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if (handle <= 0) {
|
||||
qDebug("Failed to create socket.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
destSockaddr.sin_family = AF_INET;
|
||||
|
||||
// bind the socket to the passed listeningPort
|
||||
sockaddr_in bind_address;
|
||||
bind_address.sin_family = AF_INET;
|
||||
bind_address.sin_addr.s_addr = INADDR_ANY;
|
||||
bind_address.sin_port = htons((uint16_t) _listeningPort);
|
||||
|
||||
if (bind(handle, (const sockaddr*) &bind_address, sizeof(sockaddr_in)) < 0) {
|
||||
qDebug("Failed to bind socket to port %hu.\n", _listeningPort);
|
||||
return;
|
||||
}
|
||||
|
||||
// if we requested an ephemeral port, get the actual port
|
||||
if (listeningPort == 0) {
|
||||
socklen_t addressLength = sizeof(sockaddr_in);
|
||||
getsockname(handle, (sockaddr*) &bind_address, &addressLength);
|
||||
_listeningPort = ntohs(bind_address.sin_port);
|
||||
}
|
||||
|
||||
const int DEFAULT_BLOCKING_SOCKET_TIMEOUT_USECS = 0.5 * 1000000;
|
||||
setBlockingReceiveTimeoutInUsecs(DEFAULT_BLOCKING_SOCKET_TIMEOUT_USECS);
|
||||
|
||||
qDebug("Created UDP Socket listening on %hd\n", _listeningPort);
|
||||
}
|
||||
|
||||
UDPSocket::~UDPSocket() {
|
||||
#ifdef _WIN32
|
||||
closesocket(handle);
|
||||
#else
|
||||
close(handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool UDPSocket::init() {
|
||||
#ifdef _WIN32
|
||||
WORD wVersionRequested;
|
||||
WSADATA wsaData;
|
||||
int err;
|
||||
|
||||
wVersionRequested = MAKEWORD( 2, 2 );
|
||||
|
||||
err = WSAStartup( wVersionRequested, &wsaData );
|
||||
if ( err != 0 ) {
|
||||
/* Tell the user that we could not find a usable */
|
||||
/* WinSock DLL. */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Confirm that the WinSock DLL supports 2.2.*/
|
||||
/* Note that if the DLL supports versions later */
|
||||
/* than 2.2 in addition to 2.2, it will still return */
|
||||
/* 2.2 in wVersion since that is the version we */
|
||||
/* requested. */
|
||||
|
||||
if ( LOBYTE( wsaData.wVersion ) != 2 ||
|
||||
HIBYTE( wsaData.wVersion ) != 2 ) {
|
||||
/* Tell the user that we could not find a usable */
|
||||
/* WinSock DLL. */
|
||||
WSACleanup();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
void UDPSocket::setBlocking(bool blocking) {
|
||||
this->blocking = blocking;
|
||||
|
||||
#ifdef _WIN32
|
||||
u_long mode = blocking ? 0 : 1;
|
||||
ioctlsocket(handle, FIONBIO, &mode);
|
||||
#else
|
||||
int flags = fcntl(handle, F_GETFL, 0);
|
||||
fcntl(handle, F_SETFL, blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK));
|
||||
#endif
|
||||
}
|
||||
|
||||
void UDPSocket::setBlockingReceiveTimeoutInUsecs(int timeoutUsecs) {
|
||||
struct timeval tv = {timeoutUsecs / 1000000, timeoutUsecs % 1000000};
|
||||
setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv));
|
||||
}
|
||||
|
||||
// Receive data on this socket with retrieving address of sender
|
||||
bool UDPSocket::receive(void* receivedData, ssize_t* receivedBytes) const {
|
||||
return receive((sockaddr*) &senderAddress, receivedData, receivedBytes);
|
||||
}
|
||||
|
||||
// Receive data on this socket with the address of the sender
|
||||
bool UDPSocket::receive(sockaddr* recvAddress, void* receivedData, ssize_t* receivedBytes) const {
|
||||
|
||||
#ifdef _WIN32
|
||||
int addressSize = sizeof(*recvAddress);
|
||||
#else
|
||||
socklen_t addressSize = sizeof(*recvAddress);
|
||||
#endif
|
||||
*receivedBytes = recvfrom(handle, static_cast<char*>(receivedData), MAX_BUFFER_LENGTH_BYTES,
|
||||
0, recvAddress, &addressSize);
|
||||
|
||||
return (*receivedBytes > 0);
|
||||
}
|
||||
|
||||
int UDPSocket::send(sockaddr* destAddress, const void* data, size_t byteLength) const {
|
||||
if (destAddress) {
|
||||
// send data via UDP
|
||||
int sent_bytes = sendto(handle, (const char*)data, byteLength,
|
||||
0, (sockaddr *) destAddress, sizeof(sockaddr_in));
|
||||
|
||||
if (sent_bytes != byteLength) {
|
||||
qDebug("Failed to send packet: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
return sent_bytes;
|
||||
} else {
|
||||
qDebug("UDPSocket send called with NULL destination address - Likely a node with no active socket.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int UDPSocket::send(const char* destAddress, int destPort, const void* data, size_t byteLength) const {
|
||||
|
||||
// change address and port on reusable global to passed variables
|
||||
destSockaddr.sin_addr.s_addr = inet_addr(destAddress);
|
||||
destSockaddr.sin_port = htons((uint16_t)destPort);
|
||||
|
||||
return send((sockaddr *)&destSockaddr, data, byteLength);
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
//
|
||||
// UDPSocket.h
|
||||
// interface
|
||||
//
|
||||
// Created by Stephen Birarda on 1/28/13.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__UDPSocket__
|
||||
#define __interface__UDPSocket__
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Syssocket.h"
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#define MAX_BUFFER_LENGTH_BYTES 1500
|
||||
|
||||
class UDPSocket {
|
||||
public:
|
||||
UDPSocket(unsigned short int listeningPort);
|
||||
~UDPSocket();
|
||||
|
||||
bool init();
|
||||
unsigned short int getListeningPort() const { return _listeningPort; }
|
||||
|
||||
void setBlocking(bool blocking);
|
||||
bool isBlocking() const { return blocking; }
|
||||
void setBlockingReceiveTimeoutInUsecs(int timeoutUsecs);
|
||||
|
||||
int send(sockaddr* destAddress, const void* data, size_t byteLength) const;
|
||||
int send(const char* destAddress, int destPort, const void* data, size_t byteLength) const;
|
||||
|
||||
bool receive(void* receivedData, ssize_t* receivedBytes) const;
|
||||
bool receive(sockaddr* recvAddress, void* receivedData, ssize_t* receivedBytes) const;
|
||||
private:
|
||||
int handle;
|
||||
unsigned short int _listeningPort;
|
||||
bool blocking;
|
||||
};
|
||||
|
||||
bool socketMatch(const sockaddr* first, const sockaddr* second);
|
||||
int packSocket(unsigned char* packStore, in_addr_t inAddress, in_port_t networkOrderPort);
|
||||
int packSocket(unsigned char* packStore, sockaddr* socketToPack);
|
||||
int unpackSocket(const unsigned char* packedData, sockaddr* unpackDestSocket);
|
||||
void copySocketToEmptySocketPointer(sockaddr** destination, const sockaddr* source);
|
||||
int getLocalAddress();
|
||||
unsigned short loadBufferWithSocketInfo(char* addressBuffer, sockaddr* socket);
|
||||
sockaddr_in socketForHostnameAndHostOrderPort(const char* hostname, unsigned short port = 0);
|
||||
|
||||
#endif /* defined(__interface__UDPSocket__) */
|
|
@ -103,22 +103,28 @@ int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
|
|||
statsMessageLength += nodeData->getPacketLength();
|
||||
|
||||
// actually send it
|
||||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), statsMessage, statsMessageLength);
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) statsMessage, statsMessageLength,
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
} else {
|
||||
// not enough room in the packet, send two packets
|
||||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), statsMessage, statsMessageLength);
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) statsMessage, statsMessageLength,
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
trueBytesSent += statsMessageLength;
|
||||
truePacketsSent++;
|
||||
packetsSent++;
|
||||
|
||||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(),
|
||||
nodeData->getPacket(), nodeData->getPacketLength());
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) nodeData->getPacket(), nodeData->getPacketLength(),
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
}
|
||||
nodeData->stats.markAsSent();
|
||||
} else {
|
||||
// just send the voxel packet
|
||||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(),
|
||||
nodeData->getPacket(), nodeData->getPacketLength());
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) nodeData->getPacket(), nodeData->getPacketLength(),
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
}
|
||||
// remember to track our stats
|
||||
nodeData->stats.packetSent(nodeData->getPacketLength());
|
||||
|
@ -335,7 +341,9 @@ int VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nod
|
|||
envPacketLength += _myServer->getEnvironmentData(i)->getBroadcastData(_tempOutputBuffer + envPacketLength);
|
||||
}
|
||||
|
||||
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), _tempOutputBuffer, envPacketLength);
|
||||
NodeList::getInstance()->getNodeSocket().writeDatagram((char*) _tempOutputBuffer, envPacketLength,
|
||||
node->getActiveSocket()->getAddress(),
|
||||
node->getActiveSocket()->getPort());
|
||||
trueBytesSent += envPacketLength;
|
||||
truePacketsSent++;
|
||||
packetsSentThisInterval++;
|
||||
|
|
|
@ -618,7 +618,7 @@ void VoxelServer::run() {
|
|||
qDebug("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, _packetsPerClientPerInterval);
|
||||
}
|
||||
|
||||
sockaddr senderAddress;
|
||||
HifiSockAddr senderSockAddr;
|
||||
|
||||
unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE];
|
||||
ssize_t packetLength;
|
||||
|
@ -668,7 +668,9 @@ void VoxelServer::run() {
|
|||
// ping our inactive nodes to punch holes with them
|
||||
nodeList->possiblyPingInactiveNodes();
|
||||
|
||||
if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) &&
|
||||
if ((packetLength = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE,
|
||||
senderSockAddr.getAddressPointer(),
|
||||
senderSockAddr.getPortPointer())) &&
|
||||
packetVersionMatch(packetData)) {
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
|
@ -682,7 +684,7 @@ void VoxelServer::run() {
|
|||
Node* node = nodeList->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (node) {
|
||||
nodeList->updateNodeWithData(node, &senderAddress, packetData, packetLength);
|
||||
nodeList->updateNodeWithData(node, senderSockAddr, packetData, packetLength);
|
||||
if (!node->getActiveSocket()) {
|
||||
// we don't have an active socket for this node, but they're talking to us
|
||||
// this means they've heard from us and can reply, let's assume public is active
|
||||
|
@ -695,7 +697,7 @@ void VoxelServer::run() {
|
|||
}
|
||||
} else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
|
||||
if (_jurisdictionSender) {
|
||||
_jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength);
|
||||
_jurisdictionSender->queueReceivedPacket(senderSockAddr, packetData, packetLength);
|
||||
}
|
||||
} else if (_voxelServerPacketProcessor &&
|
||||
(packetData[0] == PACKET_TYPE_SET_VOXEL
|
||||
|
@ -730,10 +732,10 @@ void VoxelServer::run() {
|
|||
}
|
||||
}
|
||||
|
||||
_voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength);
|
||||
_voxelServerPacketProcessor->queueReceivedPacket(senderSockAddr, packetData, packetLength);
|
||||
} else {
|
||||
// let processNodeData handle it.
|
||||
NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength);
|
||||
NodeList::getInstance()->processNodeData(senderSockAddr, packetData, packetLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@ void VoxelServerPacketProcessor::resetStats() {
|
|||
}
|
||||
|
||||
|
||||
void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
void VoxelServerPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr,
|
||||
unsigned char* packetData, ssize_t packetLength) {
|
||||
|
||||
bool debugProcessPacket = _myServer->wantsVerboseDebug();
|
||||
|
||||
|
@ -135,7 +136,7 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned
|
|||
}
|
||||
|
||||
// Make sure our Node and NodeList knows we've heard from this node.
|
||||
Node* senderNode = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||
Node* senderNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
QUuid& nodeUUID = DEFAULT_NODE_ID_REF;
|
||||
if (senderNode) {
|
||||
senderNode->setLastHeardMicrostamp(usecTimestampNow());
|
||||
|
@ -170,7 +171,7 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned
|
|||
_myServer->getServerTree().unlock();
|
||||
|
||||
// Make sure our Node and NodeList knows we've heard from this node.
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
if (node) {
|
||||
node->setLastHeardMicrostamp(usecTimestampNow());
|
||||
}
|
||||
|
@ -199,7 +200,7 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned
|
|||
}
|
||||
|
||||
// Make sure our Node and NodeList knows we've heard from this node.
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
if (node) {
|
||||
node->setLastHeardMicrostamp(usecTimestampNow());
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; }
|
||||
|
||||
protected:
|
||||
virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
virtual void processPacket(const HifiSockAddr& senderSockAddr, unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
private:
|
||||
void trackInboundPackets(const QUuid& nodeUUID, int sequence, uint64_t transitTime,
|
||||
|
|
|
@ -48,7 +48,7 @@ bool JurisdictionListener::queueJurisdictionRequest() {
|
|||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (nodeList->getNodeActiveSocketOrPing(&(*node)) && node->getType() == NODE_TYPE_VOXEL_SERVER) {
|
||||
sockaddr* nodeAddress = node->getActiveSocket();
|
||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||
PacketSender::queuePacketForSending(*nodeAddress, bufferOut, sizeOut);
|
||||
nodeCount++;
|
||||
}
|
||||
|
@ -64,9 +64,9 @@ bool JurisdictionListener::queueJurisdictionRequest() {
|
|||
return isStillRunning();
|
||||
}
|
||||
|
||||
void JurisdictionListener::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
void JurisdictionListener::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) {
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||
if (node) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
JurisdictionMap map;
|
||||
|
|
|
@ -45,7 +45,7 @@ protected:
|
|||
/// \param packetData pointer to received data
|
||||
/// \param ssize_t packetLength size of received data
|
||||
/// \thread "this" individual processing thread
|
||||
virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
private:
|
||||
NodeToJurisdictionMap _jurisdictions;
|
||||
|
|
|
@ -29,9 +29,9 @@ JurisdictionSender::~JurisdictionSender() {
|
|||
}
|
||||
|
||||
|
||||
void JurisdictionSender::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
void JurisdictionSender::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) {
|
||||
if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) {
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress);
|
||||
Node* node = NodeList::getInstance()->nodeWithAddress(senderAddress);
|
||||
if (node) {
|
||||
QUuid nodeUUID = node->getUUID();
|
||||
lockRequestingNodes();
|
||||
|
@ -66,7 +66,7 @@ bool JurisdictionSender::process() {
|
|||
Node* node = NodeList::getInstance()->nodeWithUUID(nodeUUID);
|
||||
|
||||
if (node->getActiveSocket() != NULL) {
|
||||
sockaddr* nodeAddress = node->getActiveSocket();
|
||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||
queuePacketForSending(*nodeAddress, bufferOut, sizeOut);
|
||||
nodeCount++;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
virtual bool process();
|
||||
|
||||
protected:
|
||||
virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength);
|
||||
|
||||
/// Locks all the resources of the thread.
|
||||
void lockRequestingNodes() { pthread_mutex_lock(&_requestingNodeMutex); }
|
||||
|
|
|
@ -123,7 +123,7 @@ void VoxelEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned ch
|
|||
if (node->getType() == NODE_TYPE_VOXEL_SERVER &&
|
||||
((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) {
|
||||
if (nodeList->getNodeActiveSocketOrPing(&(*node))) {
|
||||
sockaddr* nodeAddress = node->getActiveSocket();
|
||||
const HifiSockAddr* nodeAddress = node->getActiveSocket();
|
||||
queuePacketForSending(*nodeAddress, buffer, length);
|
||||
|
||||
// debugging output...
|
||||
|
|
|
@ -5,9 +5,13 @@ set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
|
|||
|
||||
set(TARGET_NAME pairing-server)
|
||||
|
||||
find_package(Qt5Network REQUIRED)
|
||||
|
||||
include(${MACRO_DIR}/SetupHifiProject.cmake)
|
||||
setup_hifi_project(${TARGET_NAME} TRUE)
|
||||
|
||||
qt5_use_modules(${TARGET_NAME} Network)
|
||||
|
||||
# link the shared hifi library
|
||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
|
@ -11,17 +11,20 @@
|
|||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <UDPSocket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <QtNetwork/QUdpSocket>
|
||||
|
||||
#include <HifiSockAddr.h>
|
||||
|
||||
const int PAIRING_SERVER_LISTEN_PORT = 7247;
|
||||
const int MAX_PACKET_SIZE_BYTES = 1400;
|
||||
|
||||
struct PairableDevice {
|
||||
char identifier[64];
|
||||
char name[64];
|
||||
sockaddr_in sendingSocket;
|
||||
sockaddr_in localSocket;
|
||||
HifiSockAddr sendingSocket;
|
||||
HifiSockAddr localSocket;
|
||||
};
|
||||
|
||||
struct RequestingClient {
|
||||
|
@ -29,7 +32,7 @@ struct RequestingClient {
|
|||
int port;
|
||||
};
|
||||
|
||||
UDPSocket serverSocket(PAIRING_SERVER_LISTEN_PORT);
|
||||
QUdpSocket serverSocket;
|
||||
PairableDevice* lastDevice = NULL;
|
||||
RequestingClient* lastClient = NULL;
|
||||
|
||||
|
@ -47,17 +50,20 @@ void sendLastClientToLastDevice() {
|
|||
char pairData[INET_ADDRSTRLEN + 6] = {};
|
||||
int bytesWritten = sprintf(pairData, "%s:%d", ::lastClient->address, ::lastClient->port);
|
||||
|
||||
::serverSocket.send((sockaddr*) &::lastDevice->sendingSocket, pairData, bytesWritten);
|
||||
::serverSocket.writeDatagram(pairData, bytesWritten,
|
||||
::lastDevice->sendingSocket.getAddress(), ::lastDevice->sendingSocket.getPort());
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
|
||||
sockaddr_in senderSocket;
|
||||
serverSocket.bind(QHostAddress::LocalHost, PAIRING_SERVER_LISTEN_PORT);
|
||||
|
||||
HifiSockAddr senderSockAddr;
|
||||
char senderData[MAX_PACKET_SIZE_BYTES] = {};
|
||||
ssize_t receivedBytes = 0;
|
||||
|
||||
while (true) {
|
||||
if (::serverSocket.receive((sockaddr*) &senderSocket, &senderData, &receivedBytes)) {
|
||||
if (::serverSocket.readDatagram(senderData, MAX_PACKET_SIZE_BYTES,
|
||||
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer())) {
|
||||
if (senderData[0] == 'A') {
|
||||
// this is a device reporting itself as available
|
||||
|
||||
|
@ -76,12 +82,11 @@ int main(int argc, const char* argv[]) {
|
|||
// if we have fewer than 3 matches the packet wasn't properly formatted
|
||||
|
||||
// setup the localSocket for the pairing device
|
||||
tempDevice.localSocket.sin_family = AF_INET;
|
||||
inet_pton(AF_INET, deviceAddress, &::lastDevice);
|
||||
tempDevice.localSocket.sin_port = socketPort;
|
||||
tempDevice.localSocket.setAddress(QHostAddress(deviceAddress));
|
||||
tempDevice.localSocket.setPort(socketPort);
|
||||
|
||||
// store this device's sending socket so we can talk back to it
|
||||
tempDevice.sendingSocket = senderSocket;
|
||||
tempDevice.sendingSocket = senderSockAddr;
|
||||
|
||||
// push this new device into the vector
|
||||
printf("New last device is %s (%s) at %s:%d\n",
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
set(ROOT_DIR ..)
|
||||
set(MACRO_DIR ${ROOT_DIR}/cmake/macros)
|
||||
|
||||
set(TARGET_NAME space-server)
|
||||
|
||||
include(${MACRO_DIR}/SetupHifiProject.cmake)
|
||||
|
||||
setup_hifi_project(${TARGET_NAME} TRUE)
|
||||
|
||||
include(${MACRO_DIR}/LinkHifiLibrary.cmake)
|
||||
link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR})
|
|
@ -1,2 +0,0 @@
|
|||
0 00000100001011101110 domain4.highfidelity.co domain4
|
||||
0 00000100110100010001 domain3.highfidelity.co domain3
|
|
@ -1,20 +0,0 @@
|
|||
//
|
||||
// TreeNode.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 2/13/13.
|
||||
//
|
||||
//
|
||||
|
||||
#include "TreeNode.h"
|
||||
|
||||
std::string EMPTY_STRING = "";
|
||||
|
||||
TreeNode::TreeNode() {
|
||||
for (int i = 0; i < CHILDREN_PER_NODE; ++i) {
|
||||
child[i] = NULL;
|
||||
}
|
||||
|
||||
hostname = NULL;
|
||||
nickname = NULL;
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
//
|
||||
// TreeNode.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 2/13/13.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __hifi__TreeNode__
|
||||
#define __hifi__TreeNode__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
const int CHILDREN_PER_NODE = 8;
|
||||
|
||||
class TreeNode {
|
||||
public:
|
||||
TreeNode();
|
||||
|
||||
TreeNode *child[CHILDREN_PER_NODE];
|
||||
char *hostname;
|
||||
char *nickname;
|
||||
int domain_id;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__TreeNode__) */
|
|
@ -1,160 +0,0 @@
|
|||
//
|
||||
// main.cpp
|
||||
// space
|
||||
//
|
||||
// Created by Leonardo Murillo on 2/6/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "TreeNode.h"
|
||||
#include "UDPSocket.h"
|
||||
|
||||
const char *CONFIG_FILE = "/Users/birarda/code/worklist/checkouts/hifi/space/example.data.txt";
|
||||
const unsigned short SPACE_LISTENING_PORT = 55551;
|
||||
const short MAX_NAME_LENGTH = 255;
|
||||
|
||||
const char ROOT_HOSTNAME[] = "root.highfidelity.co";
|
||||
const char ROOT_NICKNAME[] = "root";
|
||||
|
||||
const size_t PACKET_LENGTH_BYTES = 1024;
|
||||
|
||||
sockaddr_in destAddress;
|
||||
socklen_t destLength = sizeof(destAddress);
|
||||
|
||||
char *lastKnownHostname;
|
||||
|
||||
TreeNode rootNode;
|
||||
UDPSocket spaceSocket(SPACE_LISTENING_PORT);
|
||||
|
||||
TreeNode *findOrCreateNode(int lengthInBits,
|
||||
unsigned char *addressBytes,
|
||||
char *hostname,
|
||||
char *nickname,
|
||||
int domainID) {
|
||||
|
||||
TreeNode *currentNode = &rootNode;
|
||||
|
||||
for (int i = 0; i < lengthInBits; i += 3) {
|
||||
unsigned char octet;
|
||||
|
||||
if (i%8 < 6) {
|
||||
octet = addressBytes[i/8] << i%8 >> (5);
|
||||
} else {
|
||||
octet = (addressBytes[i/8] << i >> (11 - i)) | (addressBytes[i/8 + 1] >> (11 - i + 2));
|
||||
}
|
||||
|
||||
if (currentNode->child[octet] == NULL) {
|
||||
currentNode->child[octet] = new TreeNode;
|
||||
} else if (currentNode->child[octet]->hostname != NULL) {
|
||||
lastKnownHostname = currentNode->child[octet]->hostname;
|
||||
}
|
||||
|
||||
currentNode = currentNode->child[octet];
|
||||
}
|
||||
|
||||
if (currentNode->hostname == NULL) {
|
||||
currentNode->hostname = hostname;
|
||||
currentNode->nickname = nickname;
|
||||
}
|
||||
|
||||
return currentNode;
|
||||
};
|
||||
|
||||
bool loadSpaceData(void) {
|
||||
FILE *configFile = std::fopen(CONFIG_FILE, "r");
|
||||
char formatString[10];
|
||||
|
||||
if (configFile == NULL) {
|
||||
std::cout << "Unable to load config file!\n";
|
||||
return false;
|
||||
} else {
|
||||
char *lengthBitString = new char[8];
|
||||
int itemsRead = 0;
|
||||
|
||||
while ((itemsRead = fscanf(configFile, "0 %8c", lengthBitString)) > 0) {
|
||||
|
||||
// calculate the number of bits in the address and bits required for padding
|
||||
unsigned long threeBitCodes = strtoul(lengthBitString, NULL, 2);
|
||||
int bitsInAddress = threeBitCodes * 3;
|
||||
int paddingBits = 8 - (bitsInAddress % 8);
|
||||
int addressByteLength = (bitsInAddress + paddingBits) / 8;
|
||||
|
||||
// create an unsigned char * to hold the padded address
|
||||
unsigned char *paddedAddress = new unsigned char[addressByteLength];
|
||||
|
||||
char *fullByteBitString = new char[8];
|
||||
|
||||
for (int c = 0; c < addressByteLength; c++) {
|
||||
if (c + 1 == addressByteLength && paddingBits > 0) {
|
||||
// this is the last byte, and we need some padding bits
|
||||
// pull as many bits as are left
|
||||
int goodBits = 8 - paddingBits;
|
||||
sprintf(formatString, "%%%dc", goodBits);
|
||||
itemsRead = fscanf(configFile, formatString, fullByteBitString);
|
||||
|
||||
// fill out the rest with zeros
|
||||
memset(fullByteBitString + goodBits, '0', paddingBits);
|
||||
} else {
|
||||
// pull 8 bits (which will be one byte) from the file
|
||||
itemsRead = fscanf(configFile, "%8c", fullByteBitString);
|
||||
}
|
||||
|
||||
// set the corresponding value in the unsigned char array
|
||||
*(paddedAddress + c) = strtoul(fullByteBitString, NULL, 2);
|
||||
}
|
||||
|
||||
char *nodeHostname = new char[MAX_NAME_LENGTH];
|
||||
char *nodeNickname = new char[MAX_NAME_LENGTH];
|
||||
itemsRead = fscanf(configFile, "%s %s\n", nodeHostname, nodeNickname);
|
||||
|
||||
findOrCreateNode(bitsInAddress, paddedAddress, nodeHostname, nodeNickname, 0);
|
||||
}
|
||||
|
||||
std::fclose(configFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int main (int argc, const char *argv[]) {
|
||||
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
|
||||
unsigned char packetData[PACKET_LENGTH_BYTES];
|
||||
ssize_t receivedBytes = 0;
|
||||
|
||||
rootNode.hostname = new char[MAX_NAME_LENGTH];
|
||||
rootNode.nickname = new char[MAX_NAME_LENGTH];
|
||||
|
||||
strcpy(rootNode.hostname, ROOT_HOSTNAME);
|
||||
strcpy(rootNode.nickname, ROOT_NICKNAME);
|
||||
|
||||
loadSpaceData();
|
||||
|
||||
std::cout << "[DEBUG] Listening for Datagrams" << std::endl;
|
||||
|
||||
while (true) {
|
||||
if (spaceSocket.receive((sockaddr *)&destAddress, &packetData, &receivedBytes)) {
|
||||
unsigned long lengthInBits;
|
||||
lengthInBits = packetData[0] * 3;
|
||||
|
||||
unsigned char addressData[sizeof(packetData)-1];
|
||||
for (int i = 0; i < sizeof(packetData)-1; ++i) {
|
||||
addressData[i] = packetData[i+1];
|
||||
}
|
||||
|
||||
TreeNode *thisNode = findOrCreateNode(lengthInBits, addressData, NULL, NULL, 0);
|
||||
char *hostnameToSend = (thisNode->hostname == NULL)
|
||||
? lastKnownHostname
|
||||
: thisNode->hostname;
|
||||
|
||||
spaceSocket.send((sockaddr *)&destAddress, &hostnameToSend, sizeof(hostnameToSend));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in a new issue