mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 13:33:30 +02:00
160 lines
4.5 KiB
C++
160 lines
4.5 KiB
C++
//
|
|
// Node.cpp
|
|
// hifi
|
|
//
|
|
// Created by Stephen Birarda on 2/15/13.
|
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
|
//
|
|
|
|
#include "stdio.h"
|
|
|
|
#include <pthread.h>
|
|
#include "Node.h"
|
|
#include "NodeTypes.h"
|
|
#include <cstring>
|
|
#include "Log.h"
|
|
#include "UDPSocket.h"
|
|
#include "SharedUtil.h"
|
|
|
|
#ifdef _WIN32
|
|
#include "Syssocket.h"
|
|
#else
|
|
#include <arpa/inet.h>
|
|
#endif
|
|
|
|
int unpackNodeId(unsigned char* packedData, uint16_t* nodeId) {
|
|
memcpy(nodeId, packedData, sizeof(uint16_t));
|
|
return sizeof(uint16_t);
|
|
}
|
|
|
|
int packNodeId(unsigned char* packStore, uint16_t nodeId) {
|
|
memcpy(packStore, &nodeId, sizeof(uint16_t));
|
|
return sizeof(uint16_t);
|
|
}
|
|
|
|
Node::Node(sockaddr* publicSocket, sockaddr* localSocket, char type, uint16_t nodeID) :
|
|
_type(type),
|
|
_nodeID(nodeID),
|
|
_wakeMicrostamp(usecTimestampNow()),
|
|
_lastHeardMicrostamp(usecTimestampNow()),
|
|
_activeSocket(NULL),
|
|
_bytesReceivedMovingAverage(NULL),
|
|
_linkedData(NULL),
|
|
_isAlive(true)
|
|
{
|
|
if (publicSocket) {
|
|
_publicSocket = new sockaddr(*publicSocket);
|
|
} else {
|
|
_publicSocket = NULL;
|
|
}
|
|
|
|
if (localSocket) {
|
|
_localSocket = new sockaddr(*localSocket);
|
|
} else {
|
|
_localSocket = NULL;
|
|
}
|
|
|
|
pthread_mutex_init(&_mutex, 0);
|
|
}
|
|
|
|
Node::~Node() {
|
|
delete _publicSocket;
|
|
delete _localSocket;
|
|
delete _linkedData;
|
|
delete _bytesReceivedMovingAverage;
|
|
|
|
pthread_mutex_destroy(&_mutex);
|
|
}
|
|
|
|
// Names of Node Types
|
|
const char* NODE_TYPE_NAME_DOMAIN = "Domain";
|
|
const char* NODE_TYPE_NAME_VOXEL_SERVER = "Voxel Server";
|
|
const char* NODE_TYPE_NAME_INTERFACE = "Client Interface";
|
|
const char* NODE_TYPE_NAME_AUDIO_MIXER = "Audio Mixer";
|
|
const char* NODE_TYPE_NAME_AVATAR_MIXER = "Avatar Mixer";
|
|
const char* NODE_TYPE_NAME_AUDIO_INJECTOR = "Audio Injector";
|
|
const char* NODE_TYPE_NAME_ANIMATION_SERVER = "Animation Server";
|
|
const char* NODE_TYPE_NAME_UNASSIGNED = "Unassigned";
|
|
const char* NODE_TYPE_NAME_UNKNOWN = "Unknown";
|
|
|
|
const char* Node::getTypeName() const {
|
|
switch (this->_type) {
|
|
case NODE_TYPE_DOMAIN:
|
|
return NODE_TYPE_NAME_DOMAIN;
|
|
case NODE_TYPE_VOXEL_SERVER:
|
|
return NODE_TYPE_NAME_VOXEL_SERVER;
|
|
case NODE_TYPE_AGENT:
|
|
return NODE_TYPE_NAME_INTERFACE;
|
|
case NODE_TYPE_AUDIO_MIXER:
|
|
return NODE_TYPE_NAME_AUDIO_MIXER;
|
|
case NODE_TYPE_AVATAR_MIXER:
|
|
return NODE_TYPE_NAME_AVATAR_MIXER;
|
|
case NODE_TYPE_AUDIO_INJECTOR:
|
|
return NODE_TYPE_NAME_AUDIO_INJECTOR;
|
|
case NODE_TYPE_ANIMATION_SERVER:
|
|
return NODE_TYPE_NAME_ANIMATION_SERVER;
|
|
case NODE_TYPE_UNASSIGNED:
|
|
return NODE_TYPE_NAME_UNASSIGNED;
|
|
default:
|
|
return NODE_TYPE_NAME_UNKNOWN;
|
|
}
|
|
}
|
|
|
|
void Node::activateLocalSocket() {
|
|
_activeSocket = _localSocket;
|
|
}
|
|
|
|
void Node::activatePublicSocket() {
|
|
_activeSocket = _publicSocket;
|
|
}
|
|
|
|
bool Node::operator==(const Node& otherNode) {
|
|
return matches(otherNode._publicSocket, otherNode._localSocket, otherNode._type);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
void Node::recordBytesReceived(int bytesReceived) {
|
|
if (_bytesReceivedMovingAverage == NULL) {
|
|
_bytesReceivedMovingAverage = new SimpleMovingAverage(100);
|
|
}
|
|
|
|
_bytesReceivedMovingAverage->updateAverage((float) bytesReceived);
|
|
}
|
|
|
|
float Node::getAveragePacketsPerSecond() {
|
|
if (_bytesReceivedMovingAverage) {
|
|
return (1 / _bytesReceivedMovingAverage->getEventDeltaAverage());
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
float Node::getAverageKilobitsPerSecond() {
|
|
if (_bytesReceivedMovingAverage) {
|
|
return (_bytesReceivedMovingAverage->getAverageSampleValuePerSecond() * (8.0f / 1000));
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void Node::printLog(Node const& node) {
|
|
|
|
char publicAddressBuffer[16] = {'\0'};
|
|
unsigned short publicAddressPort = loadBufferWithSocketInfo(publicAddressBuffer, node._publicSocket);
|
|
|
|
//char localAddressBuffer[16] = {'\0'};
|
|
//unsigned short localAddressPort = loadBufferWithSocketInfo(localAddressBuffer, node.localSocket);
|
|
|
|
::printLog("# %d %s (%c) @ %s:%d\n",
|
|
node._nodeID,
|
|
node.getTypeName(),
|
|
node._type,
|
|
publicAddressBuffer,
|
|
publicAddressPort);
|
|
}
|