// // Node.cpp // libraries/networking/src // // Created by Stephen Birarda on 2/15/13. // Copyright 2013 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include #include #include #include "Node.h" #include "SharedUtil.h" #include #include const QString UNKNOWN_NodeType_t_NAME = "Unknown"; namespace NodeType { QHash TypeNameHash; } void NodeType::init() { TypeNameHash.insert(NodeType::DomainServer, "Domain Server"); TypeNameHash.insert(NodeType::VoxelServer, "Voxel Server"); TypeNameHash.insert(NodeType::EntityServer, "Entity Server"); TypeNameHash.insert(NodeType::MetavoxelServer, "Metavoxel Server"); TypeNameHash.insert(NodeType::Agent, "Agent"); TypeNameHash.insert(NodeType::AudioMixer, "Audio Mixer"); TypeNameHash.insert(NodeType::AvatarMixer, "Avatar Mixer"); TypeNameHash.insert(NodeType::AnimationServer, "Animation Server"); TypeNameHash.insert(NodeType::Unassigned, "Unassigned"); } const QString& NodeType::getNodeTypeName(NodeType_t nodeType) { QHash::iterator matchedTypeName = TypeNameHash.find(nodeType); return matchedTypeName != TypeNameHash.end() ? matchedTypeName.value() : UNKNOWN_NodeType_t_NAME; } Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) : NetworkPeer(uuid, publicSocket, localSocket), _type(type), _activeSocket(NULL), _symmetricSocket(), _connectionSecret(), _bytesReceivedMovingAverage(NULL), _linkedData(NULL), _isAlive(true), _clockSkewUsec(0), _mutex(), _clockSkewMovingPercentile(30, 0.8f) // moving 80th percentile of 30 samples { } Node::~Node() { delete _linkedData; delete _bytesReceivedMovingAverage; } void Node::recordBytesReceived(int bytesReceived) { if (!_bytesReceivedMovingAverage) { _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::updateClockSkewUsec(int clockSkewSample) { _clockSkewMovingPercentile.updatePercentile((float)clockSkewSample); _clockSkewUsec = (int)_clockSkewMovingPercentile.getValueAtPercentile(); } void Node::setPublicSocket(const HifiSockAddr& publicSocket) { if (publicSocket != _publicSocket) { if (_activeSocket == &_publicSocket) { // if the active socket was the public socket then reset it to NULL _activeSocket = NULL; } if (!_publicSocket.isNull()) { qDebug() << "Public socket change for node" << *this; } _publicSocket = publicSocket; } } void Node::setLocalSocket(const HifiSockAddr& localSocket) { if (localSocket != _localSocket) { if (_activeSocket == &_localSocket) { // if the active socket was the local socket then reset it to NULL _activeSocket = NULL; } if (!_localSocket.isNull()) { qDebug() << "Local socket change for node" << *this; } _localSocket = localSocket; } } void Node::setSymmetricSocket(const HifiSockAddr& symmetricSocket) { if (symmetricSocket != _symmetricSocket) { if (_activeSocket == &_symmetricSocket) { // if the active socket was the symmetric socket then reset it to NULL _activeSocket = NULL; } if (!_symmetricSocket.isNull()) { qDebug() << "Symmetric socket change for node" << *this; } _symmetricSocket = symmetricSocket; } } void Node::activateLocalSocket() { qDebug() << "Activating local socket for network peer with ID" << uuidStringWithoutCurlyBraces(_uuid); _activeSocket = &_localSocket; } void Node::activatePublicSocket() { qDebug() << "Activating public socket for network peer with ID" << uuidStringWithoutCurlyBraces(_uuid); _activeSocket = &_publicSocket; } void Node::activateSymmetricSocket() { qDebug() << "Activating symmetric socket for network peer with ID" << uuidStringWithoutCurlyBraces(_uuid); _activeSocket = &_symmetricSocket; } QDataStream& operator<<(QDataStream& out, const Node& node) { out << node._type; out << node._uuid; out << node._publicSocket; out << node._localSocket; return out; } QDataStream& operator>>(QDataStream& in, Node& node) { in >> node._type; in >> node._uuid; in >> node._publicSocket; in >> node._localSocket; return in; } QDebug operator<<(QDebug debug, const Node &node) { debug.nospace() << NodeType::getNodeTypeName(node.getType()) << " (" << node.getType() << ")"; debug << " " << node.getUUID().toString().toLocal8Bit().constData() << " "; debug.nospace() << node.getPublicSocket() << "/" << node.getLocalSocket(); return debug.nospace(); }