shuffle Packet headers, use static enum for PacketType

This commit is contained in:
Stephen Birarda 2015-07-23 13:56:47 -07:00
parent aa08bee69f
commit 9e7fb9ae16
53 changed files with 426 additions and 357 deletions

View file

@ -97,7 +97,7 @@ AudioMixer::AudioMixer(NLPacket& packet) :
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver(); auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
QSet<PacketType::Value> nodeAudioPackets { QSet<PacketType> nodeAudioPackets {
PacketType::MicrophoneAudioNoEcho, PacketType::MicrophoneAudioWithEcho, PacketType::MicrophoneAudioNoEcho, PacketType::MicrophoneAudioWithEcho,
PacketType::InjectAudio, PacketType::SilentAudioFrame, PacketType::InjectAudio, PacketType::SilentAudioFrame,
PacketType::AudioStreamStats PacketType::AudioStreamStats

View file

@ -50,7 +50,7 @@ AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() const {
} }
int AudioMixerClientData::parseData(NLPacket& packet) { int AudioMixerClientData::parseData(NLPacket& packet) {
PacketType::Value packetType = packet.getType(); PacketType packetType = packet.getType();
if (packetType == PacketType::AudioStreamStats) { if (packetType == PacketType::AudioStreamStats) {

View file

@ -18,7 +18,7 @@ AvatarAudioStream::AvatarAudioStream(bool isStereo, const InboundAudioStream::Se
{ {
} }
int AvatarAudioStream::parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { int AvatarAudioStream::parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) {
int readBytes = 0; int readBytes = 0;
if (type == PacketType::SilentAudioFrame) { if (type == PacketType::SilentAudioFrame) {

View file

@ -25,7 +25,7 @@ private:
AvatarAudioStream(const AvatarAudioStream&); AvatarAudioStream(const AvatarAudioStream&);
AvatarAudioStream& operator= (const AvatarAudioStream&); AvatarAudioStream& operator= (const AvatarAudioStream&);
int parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& numAudioSamples); int parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples);
}; };
#endif // hifi_AvatarAudioStream_h #endif // hifi_AvatarAudioStream_h

View file

@ -22,7 +22,7 @@ public:
OctreeQueryNode(), OctreeQueryNode(),
_lastDeletedEntitiesSentAt(0) { } _lastDeletedEntitiesSentAt(0) { }
virtual PacketType::Value getMyPacketType() const { return PacketType::EntityData; } virtual PacketType getMyPacketType() const { return PacketType::EntityData; }
quint64 getLastDeletedEntitiesSentAt() const { return _lastDeletedEntitiesSentAt; } quint64 getLastDeletedEntitiesSentAt() const { return _lastDeletedEntitiesSentAt; }
void setLastDeletedEntitiesSentAt(quint64 sentAt) { _lastDeletedEntitiesSentAt = sentAt; } void setLastDeletedEntitiesSentAt(quint64 sentAt) { _lastDeletedEntitiesSentAt = sentAt; }

View file

@ -28,11 +28,11 @@ public:
// Subclasses must implement these methods // Subclasses must implement these methods
virtual OctreeQueryNode* createOctreeQueryNode(); virtual OctreeQueryNode* createOctreeQueryNode();
virtual char getMyNodeType() const { return NodeType::EntityServer; } virtual char getMyNodeType() const { return NodeType::EntityServer; }
virtual PacketType::Value getMyQueryMessageType() const { return PacketType::EntityQuery; } virtual PacketType getMyQueryMessageType() const { return PacketType::EntityQuery; }
virtual const char* getMyServerName() const { return MODEL_SERVER_NAME; } virtual const char* getMyServerName() const { return MODEL_SERVER_NAME; }
virtual const char* getMyLoggingServerTargetName() const { return MODEL_SERVER_LOGGING_TARGET_NAME; } virtual const char* getMyLoggingServerTargetName() const { return MODEL_SERVER_LOGGING_TARGET_NAME; }
virtual const char* getMyDefaultPersistFilename() const { return LOCAL_MODELS_PERSIST_FILE; } virtual const char* getMyDefaultPersistFilename() const { return LOCAL_MODELS_PERSIST_FILE; }
virtual PacketType::Value getMyEditNackType() const { return PacketType::EntityEditNack; } virtual PacketType getMyEditNackType() const { return PacketType::EntityEditNack; }
virtual QString getMyDomainSettingsKey() const { return QString("entity_server_settings"); } virtual QString getMyDomainSettingsKey() const { return QString("entity_server_settings"); }
// subclass may implement these method // subclass may implement these method

View file

@ -89,7 +89,7 @@ void OctreeInboundPacketProcessor::processPacket(QSharedPointer<NLPacket> packet
} }
// Ask our tree subclass if it can handle the incoming packet... // Ask our tree subclass if it can handle the incoming packet...
PacketType::Value packetType = packet->getType(); PacketType packetType = packet->getType();
if (_myServer->getOctree()->handlesEditPacketType(packetType)) { if (_myServer->getOctree()->handlesEditPacketType(packetType)) {
PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE", debugProcessPacket); PerformanceWarning warn(debugProcessPacket, "processPacket KNOWN TYPE", debugProcessPacket);

View file

@ -34,7 +34,7 @@ public:
virtual ~OctreeQueryNode(); virtual ~OctreeQueryNode();
void init(); // called after creation to set up some virtual items void init(); // called after creation to set up some virtual items
virtual PacketType::Value getMyPacketType() const = 0; virtual PacketType getMyPacketType() const = 0;
void resetOctreePacket(); // resets octree packet to after "V" header void resetOctreePacket(); // resets octree packet to after "V" header
@ -150,7 +150,7 @@ private:
quint64 _lastRootTimestamp; quint64 _lastRootTimestamp;
PacketType::Value _myPacketType; PacketType _myPacketType;
bool _isShuttingDown; bool _isShuttingDown;
SentPacketHistory _sentPacketHistory; SentPacketHistory _sentPacketHistory;

View file

@ -63,11 +63,11 @@ public:
// Subclasses must implement these methods // Subclasses must implement these methods
virtual OctreeQueryNode* createOctreeQueryNode() = 0; virtual OctreeQueryNode* createOctreeQueryNode() = 0;
virtual char getMyNodeType() const = 0; virtual char getMyNodeType() const = 0;
virtual PacketType::Value getMyQueryMessageType() const = 0; virtual PacketType getMyQueryMessageType() const = 0;
virtual const char* getMyServerName() const = 0; virtual const char* getMyServerName() const = 0;
virtual const char* getMyLoggingServerTargetName() const = 0; virtual const char* getMyLoggingServerTargetName() const = 0;
virtual const char* getMyDefaultPersistFilename() const = 0; virtual const char* getMyDefaultPersistFilename() const = 0;
virtual PacketType::Value getMyEditNackType() const = 0; virtual PacketType getMyEditNackType() const = 0;
virtual QString getMyDomainSettingsKey() const { return QString("octree_server_settings"); } virtual QString getMyDomainSettingsKey() const { return QString("octree_server_settings"); }
// subclass may implement these method // subclass may implement these method

View file

@ -49,26 +49,30 @@ IceServer::IceServer(int argc, char* argv[]) :
} }
bool IceServer::packetVersionMatch(const udt::Packet& packet) { bool IceServer::packetVersionMatch(const udt::Packet& packet) {
if (packet.getVersion() == versionForPacketType(packet.getType())) { PacketType headerType = NLPacket::typeInHeader(packet);
PacketVersion headerVersion = NLPacket::versionInHeader(packet);
if (headerVersion == versionForPacketType(headerType)) {
return true; return true;
} else { } else {
qDebug() << "Packet version mismatch for packet" << packet.getType() qDebug() << "Packet version mismatch for packet" << headerType
<< "(" << nameForPacketType(packet.getType()) << ") from" << packet.getSenderSockAddr(); << "(" << nameForPacketType(headerType) << ") from" << packet.getSenderSockAddr();
return false; return false;
} }
} }
void IceServer::processPacket(std::unique_ptr<udt::Packet> packet) { void IceServer::processPacket(std::unique_ptr<udt::Packet> packet) {
PacketType::Value packetType = packet->getType();
if (packetType == PacketType::ICEServerHeartbeat) { auto nlPacket = NLPacket::fromBase(std::move(packet));
SharedNetworkPeer peer = addOrUpdateHeartbeatingPeer(*packet);
if (nlPacket->getType() == PacketType::ICEServerHeartbeat) {
SharedNetworkPeer peer = addOrUpdateHeartbeatingPeer(*nlPacket);
// so that we can send packets to the heartbeating peer when we need, we need to activate a socket now // so that we can send packets to the heartbeating peer when we need, we need to activate a socket now
peer->activateMatchingOrNewSymmetricSocket(packet->getSenderSockAddr()); peer->activateMatchingOrNewSymmetricSocket(nlPacket->getSenderSockAddr());
} else if (packetType == PacketType::ICEServerQuery) { } else if (nlPacket->getType() == PacketType::ICEServerQuery) {
QDataStream heartbeatStream(packet.get()); QDataStream heartbeatStream(nlPacket.get());
// this is a node hoping to connect to a heartbeating peer - do we have the heartbeating peer? // this is a node hoping to connect to a heartbeating peer - do we have the heartbeating peer?
QUuid senderUUID; QUuid senderUUID;
@ -89,7 +93,7 @@ void IceServer::processPacket(std::unique_ptr<udt::Packet> packet) {
qDebug() << "Sending information for peer" << connectRequestID << "to peer" << senderUUID; qDebug() << "Sending information for peer" << connectRequestID << "to peer" << senderUUID;
// we have the peer they want to connect to - send them pack the information for that peer // we have the peer they want to connect to - send them pack the information for that peer
sendPeerInformationPacket(*matchingPeer, &packet->getSenderSockAddr()); sendPeerInformationPacket(*matchingPeer, &nlPacket->getSenderSockAddr());
// we also need to send them to the active peer they are hoping to connect to // we also need to send them to the active peer they are hoping to connect to
// create a dummy peer object we can pass to sendPeerInformationPacket // create a dummy peer object we can pass to sendPeerInformationPacket
@ -102,7 +106,7 @@ void IceServer::processPacket(std::unique_ptr<udt::Packet> packet) {
} }
} }
SharedNetworkPeer IceServer::addOrUpdateHeartbeatingPeer(udt::Packet& packet) { SharedNetworkPeer IceServer::addOrUpdateHeartbeatingPeer(NLPacket& packet) {
// pull the UUID, public and private sock addrs for this peer // pull the UUID, public and private sock addrs for this peer
QUuid senderUUID; QUuid senderUUID;
@ -135,7 +139,7 @@ SharedNetworkPeer IceServer::addOrUpdateHeartbeatingPeer(udt::Packet& packet) {
} }
void IceServer::sendPeerInformationPacket(const NetworkPeer& peer, const HifiSockAddr* destinationSockAddr) { void IceServer::sendPeerInformationPacket(const NetworkPeer& peer, const HifiSockAddr* destinationSockAddr) {
auto peerPacket = udt::Packet::create(PacketType::ICEServerPeerInformation); auto peerPacket = NLPacket::create(PacketType::ICEServerPeerInformation);
// get the byte array for this peer // get the byte array for this peer
peerPacket->write(peer.toByteArray()); peerPacket->write(peer.toByteArray());

View file

@ -19,7 +19,7 @@
#include <NetworkPeer.h> #include <NetworkPeer.h>
#include <HTTPConnection.h> #include <HTTPConnection.h>
#include <HTTPManager.h> #include <HTTPManager.h>
#include <udt/Packet.h> #include <NLPacket.h>
#include <udt/Socket.h> #include <udt/Socket.h>
typedef QHash<QUuid, SharedNetworkPeer> NetworkPeerHash; typedef QHash<QUuid, SharedNetworkPeer> NetworkPeerHash;
@ -35,7 +35,7 @@ private:
bool packetVersionMatch(const udt::Packet& packet); bool packetVersionMatch(const udt::Packet& packet);
void processPacket(std::unique_ptr<udt::Packet> packet); void processPacket(std::unique_ptr<udt::Packet> packet);
SharedNetworkPeer addOrUpdateHeartbeatingPeer(udt::Packet& incomingPacket); SharedNetworkPeer addOrUpdateHeartbeatingPeer(NLPacket& incomingPacket);
void sendPeerInformationPacket(const NetworkPeer& peer, const HifiSockAddr* destinationSockAddr); void sendPeerInformationPacket(const NetworkPeer& peer, const HifiSockAddr* destinationSockAddr);
QUuid _id; QUuid _id;

View file

@ -2706,7 +2706,7 @@ int Application::sendNackPackets() {
return packetsSent; return packetsSent;
} }
void Application::queryOctree(NodeType_t serverType, PacketType::Value packetType, NodeToJurisdictionMap& jurisdictions) { void Application::queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions) {
//qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView(); //qCDebug(interfaceapp) << ">>> inside... queryOctree()... _viewFrustum.getFieldOfView()=" << _viewFrustum.getFieldOfView();
bool wantExtraDebugging = getLogger()->extraDebugging(); bool wantExtraDebugging = getLogger()->extraDebugging();

View file

@ -478,7 +478,7 @@ private:
void renderLookatIndicator(glm::vec3 pointOfInterest); void renderLookatIndicator(glm::vec3 pointOfInterest);
void queryOctree(NodeType_t serverType, PacketType::Value packetType, NodeToJurisdictionMap& jurisdictions); void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions);
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum); void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
glm::vec3 getSunDirection(); glm::vec3 getSunDirection();

View file

@ -19,7 +19,7 @@
OctreePacketProcessor::OctreePacketProcessor() { OctreePacketProcessor::OctreePacketProcessor() {
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver(); auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
QSet<PacketType::Value> types { QSet<PacketType> types {
PacketType::OctreeStats, PacketType::EntityData, PacketType::OctreeStats, PacketType::EntityData,
PacketType::EntityErase, PacketType::OctreeStats PacketType::EntityErase, PacketType::OctreeStats
}; };
@ -44,7 +44,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
Application* app = Application::getInstance(); Application* app = Application::getInstance();
bool wasStatsPacket = false; bool wasStatsPacket = false;
PacketType::Value octreePacketType = packet->getType(); PacketType octreePacketType = packet->getType();
// note: PacketType_OCTREE_STATS can have PacketType_VOXEL_DATA // note: PacketType_OCTREE_STATS can have PacketType_VOXEL_DATA
// immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first // immediately following them inside the same packet. So, we process the PacketType_OCTREE_STATS first
@ -68,11 +68,11 @@ void OctreePacketProcessor::processPacket(QSharedPointer<NLPacket> packet, Share
} }
} // fall through to piggyback message } // fall through to piggyback message
PacketType::Value packetType = packet->getType(); PacketType packetType = packet->getType();
// check version of piggyback packet against expected version // check version of piggyback packet against expected version
if (packet->getVersion() != versionForPacketType(packet->getType())) { if (packet->getVersion() != versionForPacketType(packet->getType())) {
static QMultiMap<QUuid, PacketType::Value> versionDebugSuppressMap; static QMultiMap<QUuid, PacketType> versionDebugSuppressMap;
const QUuid& senderUUID = packet->getSourceID(); const QUuid& senderUUID = packet->getSourceID();
if (!versionDebugSuppressMap.contains(senderUUID, packetType)) { if (!versionDebugSuppressMap.contains(senderUUID, packetType)) {

View file

@ -164,7 +164,7 @@ int InboundAudioStream::parseData(NLPacket& packet) {
return packet.pos(); return packet.pos();
} }
int InboundAudioStream::parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { int InboundAudioStream::parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) {
if (type == PacketType::SilentAudioFrame) { if (type == PacketType::SilentAudioFrame) {
quint16 numSilentSamples = 0; quint16 numSilentSamples = 0;
memcpy(&numSilentSamples, packetAfterSeqNum.constData(), sizeof(quint16)); memcpy(&numSilentSamples, packetAfterSeqNum.constData(), sizeof(quint16));
@ -177,7 +177,7 @@ int InboundAudioStream::parseStreamProperties(PacketType::Value type, const QByt
} }
} }
int InboundAudioStream::parseAudioData(PacketType::Value type, const QByteArray& packetAfterStreamProperties, int numAudioSamples) { int InboundAudioStream::parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties, int numAudioSamples) {
return _ringBuffer.writeData(packetAfterStreamProperties.data(), numAudioSamples * sizeof(int16_t)); return _ringBuffer.writeData(packetAfterStreamProperties.data(), numAudioSamples * sizeof(int16_t));
} }

View file

@ -194,11 +194,11 @@ protected:
/// parses the info between the seq num and the audio data in the network packet and calculates /// parses the info between the seq num and the audio data in the network packet and calculates
/// how many audio samples this packet contains (used when filling in samples for dropped packets). /// how many audio samples this packet contains (used when filling in samples for dropped packets).
/// default implementation assumes no stream properties and raw audio samples after stream propertiess /// default implementation assumes no stream properties and raw audio samples after stream propertiess
virtual int parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& networkSamples); virtual int parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& networkSamples);
/// parses the audio data in the network packet. /// parses the audio data in the network packet.
/// default implementation assumes packet contains raw audio samples after stream properties /// default implementation assumes packet contains raw audio samples after stream properties
virtual int parseAudioData(PacketType::Value type, const QByteArray& packetAfterStreamProperties, int networkSamples); virtual int parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties, int networkSamples);
/// writes silent samples to the buffer that may be dropped to reduce latency caused by the buffer /// writes silent samples to the buffer that may be dropped to reduce latency caused by the buffer
virtual int writeDroppableSilentSamples(int silentSamples); virtual int writeDroppableSilentSamples(int silentSamples);

View file

@ -30,7 +30,7 @@ InjectedAudioStream::InjectedAudioStream(const QUuid& streamIdentifier, const bo
const uchar MAX_INJECTOR_VOLUME = 255; const uchar MAX_INJECTOR_VOLUME = 255;
int InjectedAudioStream::parseStreamProperties(PacketType::Value type, int InjectedAudioStream::parseStreamProperties(PacketType type,
const QByteArray& packetAfterSeqNum, const QByteArray& packetAfterSeqNum,
int& numAudioSamples) { int& numAudioSamples) {
// setup a data stream to read from this packet // setup a data stream to read from this packet

View file

@ -31,7 +31,7 @@ private:
InjectedAudioStream& operator= (const InjectedAudioStream&); InjectedAudioStream& operator= (const InjectedAudioStream&);
AudioStreamStats getAudioStreamStats() const; AudioStreamStats getAudioStreamStats() const;
int parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& numAudioSamples); int parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples);
const QUuid _streamIdentifier; const QUuid _streamIdentifier;
float _radius; float _radius;

View file

@ -42,7 +42,7 @@ int MixedProcessedAudioStream::writeLastFrameRepeatedWithFade(int samples) {
return deviceSamplesWritten; return deviceSamplesWritten;
} }
int MixedProcessedAudioStream::parseAudioData(PacketType::Value type, const QByteArray& packetAfterStreamProperties, int networkSamples) { int MixedProcessedAudioStream::parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties, int networkSamples) {
emit addedStereoSamples(packetAfterStreamProperties); emit addedStereoSamples(packetAfterStreamProperties);

View file

@ -35,7 +35,7 @@ public:
protected: protected:
int writeDroppableSilentSamples(int silentSamples); int writeDroppableSilentSamples(int silentSamples);
int writeLastFrameRepeatedWithFade(int samples); int writeLastFrameRepeatedWithFade(int samples);
int parseAudioData(PacketType::Value type, const QByteArray& packetAfterStreamProperties, int networkSamples); int parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties, int networkSamples);
private: private:
int networkToDeviceSamples(int networkSamples); int networkToDeviceSamples(int networkSamples);

View file

@ -43,8 +43,8 @@ public:
virtual ~EntityTreeRenderer(); virtual ~EntityTreeRenderer();
virtual char getMyNodeType() const { return NodeType::EntityServer; } virtual char getMyNodeType() const { return NodeType::EntityServer; }
virtual PacketType::Value getMyQueryMessageType() const { return PacketType::EntityQuery; } virtual PacketType getMyQueryMessageType() const { return PacketType::EntityQuery; }
virtual PacketType::Value getExpectedPacketType() const { return PacketType::EntityData; } virtual PacketType getExpectedPacketType() const { return PacketType::EntityData; }
virtual void renderElement(OctreeElement* element, RenderArgs* args); virtual void renderElement(OctreeElement* element, RenderArgs* args);
virtual float getSizeScale() const; virtual float getSizeScale() const;
virtual int getBoundaryLevelAdjust() const; virtual int getBoundaryLevelAdjust() const;

View file

@ -28,13 +28,13 @@ void EntityEditPacketSender::processEntityEditNackPacket(QSharedPointer<NLPacket
} }
} }
void EntityEditPacketSender::adjustEditPacketForClockSkew(PacketType::Value type, QByteArray& buffer, int clockSkew) { void EntityEditPacketSender::adjustEditPacketForClockSkew(PacketType type, QByteArray& buffer, int clockSkew) {
if (type == PacketType::EntityAdd || type == PacketType::EntityEdit) { if (type == PacketType::EntityAdd || type == PacketType::EntityEdit) {
EntityItem::adjustEditPacketForClockSkew(buffer, clockSkew); EntityItem::adjustEditPacketForClockSkew(buffer, clockSkew);
} }
} }
void EntityEditPacketSender::queueEditEntityMessage(PacketType::Value type, EntityItemID modelID, void EntityEditPacketSender::queueEditEntityMessage(PacketType type, EntityItemID modelID,
const EntityItemProperties& properties) { const EntityItemProperties& properties) {
if (!_shouldSend) { if (!_shouldSend) {
return; // bail early return; // bail early

View file

@ -26,13 +26,13 @@ public:
/// which voxel-server node or nodes the packet should be sent to. Can be called even before voxel servers are known, in /// which voxel-server node or nodes the packet should be sent to. Can be called even before voxel servers are known, in
/// which case up to MaxPendingMessages will be buffered and processed when voxel servers are known. /// which case up to MaxPendingMessages will be buffered and processed when voxel servers are known.
/// NOTE: EntityItemProperties assumes that all distances are in meter units /// NOTE: EntityItemProperties assumes that all distances are in meter units
void queueEditEntityMessage(PacketType::Value type, EntityItemID modelID, const EntityItemProperties& properties); void queueEditEntityMessage(PacketType type, EntityItemID modelID, const EntityItemProperties& properties);
void queueEraseEntityMessage(const EntityItemID& entityItemID); void queueEraseEntityMessage(const EntityItemID& entityItemID);
// My server type is the model server // My server type is the model server
virtual char getMyNodeType() const { return NodeType::EntityServer; } virtual char getMyNodeType() const { return NodeType::EntityServer; }
virtual void adjustEditPacketForClockSkew(PacketType::Value type, QByteArray& buffer, int clockSkew); virtual void adjustEditPacketForClockSkew(PacketType type, QByteArray& buffer, int clockSkew);
public slots: public slots:
void processEntityEditNackPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode); void processEntityEditNackPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode);

View file

@ -618,7 +618,7 @@ void EntityItemPropertiesFromScriptValueHonorReadOnly(const QScriptValue &object
// //
// TODO: Implement support for script and visible properties. // TODO: Implement support for script and visible properties.
// //
bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, EntityItemID id, const EntityItemProperties& properties, bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties,
QByteArray& buffer) { QByteArray& buffer) {
OctreePacketData ourDataPacket(false, buffer.size()); // create a packetData object to add out packet details too. OctreePacketData ourDataPacket(false, buffer.size()); // create a packetData object to add out packet details too.
OctreePacketData* packetData = &ourDataPacket; // we want a pointer to this so we can use our APPEND_ENTITY_PROPERTY macro OctreePacketData* packetData = &ourDataPacket; // we want a pointer to this so we can use our APPEND_ENTITY_PROPERTY macro

View file

@ -174,7 +174,7 @@ public:
void setGlowLevel(float value) { _glowLevel = value; _glowLevelChanged = true; } void setGlowLevel(float value) { _glowLevel = value; _glowLevelChanged = true; }
void setLocalRenderAlpha(float value) { _localRenderAlpha = value; _localRenderAlphaChanged = true; } void setLocalRenderAlpha(float value) { _localRenderAlpha = value; _localRenderAlphaChanged = true; }
static bool encodeEntityEditPacket(PacketType::Value command, EntityItemID id, const EntityItemProperties& properties, static bool encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties,
QByteArray& buffer); QByteArray& buffer);
static bool encodeEraseEntityMessage(const EntityItemID& entityItemID, QByteArray& buffer); static bool encodeEraseEntityMessage(const EntityItemID& entityItemID, QByteArray& buffer);

View file

@ -32,7 +32,7 @@ EntityScriptingInterface::EntityScriptingInterface() :
connect(nodeList.data(), &NodeList::canRezChanged, this, &EntityScriptingInterface::canRezChanged); connect(nodeList.data(), &NodeList::canRezChanged, this, &EntityScriptingInterface::canRezChanged);
} }
void EntityScriptingInterface::queueEntityMessage(PacketType::Value packetType, void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
EntityItemID entityID, const EntityItemProperties& properties) { EntityItemID entityID, const EntityItemProperties& properties) {
getEntityPacketSender()->queueEditEntityMessage(packetType, entityID, properties); getEntityPacketSender()->queueEditEntityMessage(packetType, entityID, properties);
} }

View file

@ -164,7 +164,7 @@ private:
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulation*, EntityItemPointer)> actor); bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulation*, EntityItemPointer)> actor);
bool setVoxels(QUuid entityID, std::function<void(PolyVoxEntityItem&)> actor); bool setVoxels(QUuid entityID, std::function<void(PolyVoxEntityItem&)> actor);
bool setPoints(QUuid entityID, std::function<bool(LineEntityItem&)> actor); bool setPoints(QUuid entityID, std::function<bool(LineEntityItem&)> actor);
void queueEntityMessage(PacketType::Value packetType, EntityItemID entityID, const EntityItemProperties& properties); void queueEntityMessage(PacketType packetType, EntityItemID entityID, const EntityItemProperties& properties);
/// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode /// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,

View file

@ -63,7 +63,7 @@ void EntityTree::eraseAllOctreeElements(bool createNewRoot) {
resetClientEditStats(); resetClientEditStats();
} }
bool EntityTree::handlesEditPacketType(PacketType::Value packetType) const { bool EntityTree::handlesEditPacketType(PacketType packetType) const {
// we handle these types of "edit" packets // we handle these types of "edit" packets
switch (packetType) { switch (packetType) {
case PacketType::EntityAdd: case PacketType::EntityAdd:

View file

@ -62,10 +62,10 @@ public:
// These methods will allow the OctreeServer to send your tree inbound edit packets of your // These methods will allow the OctreeServer to send your tree inbound edit packets of your
// own definition. Implement these to allow your octree based server to support editing // own definition. Implement these to allow your octree based server to support editing
virtual bool getWantSVOfileVersions() const { return true; } virtual bool getWantSVOfileVersions() const { return true; }
virtual PacketType::Value expectedDataPacketType() const { return PacketType::EntityData; } virtual PacketType expectedDataPacketType() const { return PacketType::EntityData; }
virtual bool canProcessVersion(PacketVersion thisVersion) const virtual bool canProcessVersion(PacketVersion thisVersion) const
{ return thisVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS; } { return thisVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS; }
virtual bool handlesEditPacketType(PacketType::Value packetType) const; virtual bool handlesEditPacketType(PacketType packetType) const;
virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength, virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength,
const SharedNodePointer& senderNode); const SharedNodePointer& senderNode);

View file

@ -31,8 +31,8 @@ public:
virtual ~EntityTreeHeadlessViewer(); virtual ~EntityTreeHeadlessViewer();
virtual char getMyNodeType() const { return NodeType::EntityServer; } virtual char getMyNodeType() const { return NodeType::EntityServer; }
virtual PacketType::Value getMyQueryMessageType() const { return PacketType::EntityQuery; } virtual PacketType getMyQueryMessageType() const { return PacketType::EntityQuery; }
virtual PacketType::Value getExpectedPacketType() const { return PacketType::EntityData; } virtual PacketType getExpectedPacketType() const { return PacketType::EntityData; }
void update(); void update();

View file

@ -157,40 +157,42 @@ bool LimitedNodeList::isPacketVerified(const udt::Packet& packet) {
} }
bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) { bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) {
PacketType headerType = NLPacket::typeInHeader(packet);
PacketVersion headerVersion = NLPacket::versionInHeader(packet);
if (packet.getVersion() != versionForPacketType(packet.getType())) { if (headerVersion != versionForPacketType(headerType)) {
static QMultiHash<QUuid, PacketType::Value> sourcedVersionDebugSuppressMap; static QMultiHash<QUuid, PacketType> sourcedVersionDebugSuppressMap;
static QMultiHash<HifiSockAddr, PacketType::Value> versionDebugSuppressMap; static QMultiHash<HifiSockAddr, PacketType> versionDebugSuppressMap;
bool hasBeenOutput = false; bool hasBeenOutput = false;
QString senderString; QString senderString;
if (NON_SOURCED_PACKETS.contains(packet.getType())) { if (NON_SOURCED_PACKETS.contains(headerType)) {
const HifiSockAddr& senderSockAddr = packet.getSenderSockAddr(); const HifiSockAddr& senderSockAddr = packet.getSenderSockAddr();
hasBeenOutput = versionDebugSuppressMap.contains(senderSockAddr, packet.getType()); hasBeenOutput = versionDebugSuppressMap.contains(senderSockAddr, headerType);
if (!hasBeenOutput) { if (!hasBeenOutput) {
versionDebugSuppressMap.insert(senderSockAddr, packet.getType()); versionDebugSuppressMap.insert(senderSockAddr, headerType);
senderString = QString("%1:%2").arg(senderSockAddr.getAddress().toString()).arg(senderSockAddr.getPort()); senderString = QString("%1:%2").arg(senderSockAddr.getAddress().toString()).arg(senderSockAddr.getPort());
} }
} else { } else {
QUuid sourceID = QUuid::fromRfc4122(QByteArray::fromRawData(packet.getPayload(), NUM_BYTES_RFC4122_UUID)); QUuid sourceID = NLPacket::sourceIDInHeader(packet);
hasBeenOutput = sourcedVersionDebugSuppressMap.contains(sourceID, packet.getType()); hasBeenOutput = sourcedVersionDebugSuppressMap.contains(sourceID, headerType);
if (!hasBeenOutput) { if (!hasBeenOutput) {
sourcedVersionDebugSuppressMap.insert(sourceID, packet.getType()); sourcedVersionDebugSuppressMap.insert(sourceID, headerType);
senderString = uuidStringWithoutCurlyBraces(sourceID.toString()); senderString = uuidStringWithoutCurlyBraces(sourceID.toString());
} }
} }
if (!hasBeenOutput) { if (!hasBeenOutput) {
qCDebug(networking) << "Packet version mismatch on" << packet.getType() << "- Sender" qCDebug(networking) << "Packet version mismatch on" << headerType << "- Sender"
<< senderString << "sent" << qPrintable(QString::number(packet.getVersion())) << "but" << senderString << "sent" << qPrintable(QString::number(headerVersion)) << "but"
<< qPrintable(QString::number(versionForPacketType(packet.getType()))) << "expected."; << qPrintable(QString::number(versionForPacketType(headerType))) << "expected.";
emit packetVersionMismatch(packet.getType()); emit packetVersionMismatch(headerType);
} }
return false; return false;
@ -201,7 +203,9 @@ bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) {
bool LimitedNodeList::packetSourceAndHashMatch(const udt::Packet& packet) { bool LimitedNodeList::packetSourceAndHashMatch(const udt::Packet& packet) {
if (NON_SOURCED_PACKETS.contains(packet.getType())) { PacketType headerType = NLPacket::typeInHeader(packet);
if (NON_SOURCED_PACKETS.contains(headerType)) {
return true; return true;
} else { } else {
QUuid sourceID = NLPacket::sourceIDInHeader(packet); QUuid sourceID = NLPacket::sourceIDInHeader(packet);
@ -210,19 +214,19 @@ bool LimitedNodeList::packetSourceAndHashMatch(const udt::Packet& packet) {
SharedNodePointer matchingNode = nodeWithUUID(sourceID); SharedNodePointer matchingNode = nodeWithUUID(sourceID);
if (matchingNode) { if (matchingNode) {
if (!NON_VERIFIED_PACKETS.contains(packet.getType())) { if (!NON_VERIFIED_PACKETS.contains(headerType)) {
QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet); QByteArray packetHeaderHash = NLPacket::verificationHashInHeader(packet);
QByteArray expectedHash = NLPacket::hashForPacketAndSecret(packet, matchingNode->getConnectionSecret()); QByteArray expectedHash = NLPacket::hashForPacketAndSecret(packet, matchingNode->getConnectionSecret());
// check if the md5 hash in the header matches the hash we would expect // check if the md5 hash in the header matches the hash we would expect
if (packetHeaderHash != expectedHash) { if (packetHeaderHash != expectedHash) {
static QMultiMap<QUuid, PacketType::Value> hashDebugSuppressMap; static QMultiMap<QUuid, PacketType> hashDebugSuppressMap;
if (!hashDebugSuppressMap.contains(sourceID, packet.getType())) { if (!hashDebugSuppressMap.contains(sourceID, headerType)) {
qCDebug(networking) << "Packet hash mismatch on" << packet.getType() << "- Sender" << sourceID; qCDebug(networking) << "Packet hash mismatch on" << headerType << "- Sender" << sourceID;
hashDebugSuppressMap.insert(sourceID, packet.getType()); hashDebugSuppressMap.insert(sourceID, headerType);
} }
return false; return false;
@ -235,7 +239,7 @@ bool LimitedNodeList::packetSourceAndHashMatch(const udt::Packet& packet) {
static QString repeatedMessage static QString repeatedMessage
= LogHandler::getInstance().addRepeatedMessageRegex("Packet of type \\d+ \\([\\sa-zA-Z]+\\) received from unknown node with UUID"); = LogHandler::getInstance().addRepeatedMessageRegex("Packet of type \\d+ \\([\\sa-zA-Z]+\\) received from unknown node with UUID");
qCDebug(networking) << "Packet of type" << packet.getType() << "(" << qPrintable(nameForPacketType(packet.getType())) << ")" qCDebug(networking) << "Packet of type" << headerType << "(" << qPrintable(nameForPacketType(headerType)) << ")"
<< "received from unknown node with UUID" << qPrintable(uuidStringWithoutCurlyBraces(sourceID)); << "received from unknown node with UUID" << qPrintable(uuidStringWithoutCurlyBraces(sourceID));
} }
} }
@ -786,7 +790,7 @@ void LimitedNodeList::sendPeerQueryToIceServer(const HifiSockAddr& iceServerSock
sendPacketToIceServer(PacketType::ICEServerQuery, iceServerSockAddr, clientID, peerID); sendPacketToIceServer(PacketType::ICEServerQuery, iceServerSockAddr, clientID, peerID);
} }
void LimitedNodeList::sendPacketToIceServer(PacketType::Value packetType, const HifiSockAddr& iceServerSockAddr, void LimitedNodeList::sendPacketToIceServer(PacketType packetType, const HifiSockAddr& iceServerSockAddr,
const QUuid& clientID, const QUuid& peerID) { const QUuid& clientID, const QUuid& peerID) {
auto icePacket = NLPacket::create(packetType); auto icePacket = NLPacket::create(packetType);

View file

@ -231,7 +231,7 @@ public slots:
signals: signals:
void dataSent(quint8 channelType, int bytes); void dataSent(quint8 channelType, int bytes);
void packetVersionMismatch(PacketType::Value type); void packetVersionMismatch(PacketType type);
void uuidChanged(const QUuid& ownerUUID, const QUuid& oldUUID); void uuidChanged(const QUuid& ownerUUID, const QUuid& oldUUID);
void nodeAdded(SharedNodePointer); void nodeAdded(SharedNodePointer);
@ -261,7 +261,7 @@ protected:
void stopInitialSTUNUpdate(bool success); void stopInitialSTUNUpdate(bool success);
void sendPacketToIceServer(PacketType::Value packetType, const HifiSockAddr& iceServerSockAddr, const QUuid& clientID, void sendPacketToIceServer(PacketType packetType, const HifiSockAddr& iceServerSockAddr, const QUuid& clientID,
const QUuid& peerRequestID = QUuid()); const QUuid& peerRequestID = QUuid());
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const Node& destinationNode, qint64 sendPacket(std::unique_ptr<NLPacket> packet, const Node& destinationNode,

View file

@ -11,14 +11,18 @@
#include "NLPacket.h" #include "NLPacket.h"
qint64 NLPacket::localHeaderSize(PacketType::Value type) { qint64 NLPacket::maxPayloadSize(PacketType type) {
return Packet::maxPayloadSize(false) - localHeaderSize(type);
}
qint64 NLPacket::localHeaderSize(PacketType type) {
qint64 size = ((NON_SOURCED_PACKETS.contains(type)) ? 0 : NUM_BYTES_RFC4122_UUID) + qint64 size = ((NON_SOURCED_PACKETS.contains(type)) ? 0 : NUM_BYTES_RFC4122_UUID) +
((NON_SOURCED_PACKETS.contains(type) || NON_VERIFIED_PACKETS.contains(type)) ? 0 : NUM_BYTES_MD5_HASH); ((NON_SOURCED_PACKETS.contains(type) || NON_VERIFIED_PACKETS.contains(type)) ? 0 : NUM_BYTES_MD5_HASH);
return size; return size;
} }
qint64 NLPacket::maxPayloadSize(PacketType::Value type) { qint64 NLPacket::maxPayloadSize() const {
return Packet::maxPayloadSize(type) - localHeaderSize(type); return Packet::maxPayloadSize() - localHeaderSize();
} }
qint64 NLPacket::totalHeadersSize() const { qint64 NLPacket::totalHeadersSize() const {
@ -29,7 +33,7 @@ qint64 NLPacket::localHeaderSize() const {
return localHeaderSize(_type); return localHeaderSize(_type);
} }
std::unique_ptr<NLPacket> NLPacket::create(PacketType::Value type, qint64 size) { std::unique_ptr<NLPacket> NLPacket::create(PacketType type, qint64 size) {
std::unique_ptr<NLPacket> packet; std::unique_ptr<NLPacket> packet;
if (size == -1) { if (size == -1) {
@ -75,17 +79,21 @@ std::unique_ptr<NLPacket> NLPacket::createCopy(const NLPacket& other) {
return std::unique_ptr<NLPacket>(new NLPacket(other)); return std::unique_ptr<NLPacket>(new NLPacket(other));
} }
NLPacket::NLPacket(PacketType::Value type, qint64 size) : NLPacket::NLPacket(PacketType type, bool isReliable, bool isPartOfMessage) :
Packet(type, localHeaderSize(type) + size) Packet(-1, isReliable, isPartOfMessage),
_type(type),
_version(versionForPacketType(type))
{ {
Q_ASSERT(size >= 0);
adjustPayloadStartAndCapacity(); adjustPayloadStartAndCapacity();
} }
NLPacket::NLPacket(PacketType::Value type) : NLPacket::NLPacket(PacketType type, qint64 size, bool isReliable, bool isPartOfMessage) :
Packet(type, -1) Packet(localHeaderSize(type) + size, isReliable, isPartOfMessage),
_type(type),
_version(versionForPacketType(type))
{ {
Q_ASSERT(size >= 0);
adjustPayloadStartAndCapacity(); adjustPayloadStartAndCapacity();
} }
@ -103,12 +111,14 @@ NLPacket::NLPacket(const NLPacket& other) : Packet(other) {
NLPacket::NLPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr) : NLPacket::NLPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr) :
Packet(std::move(data), size, senderSockAddr) Packet(std::move(data), size, senderSockAddr)
{ {
// sanity check before we decrease the payloadSize with the payloadCapacity // sanity check before we decrease the payloadSize with the payloadCapacity
Q_ASSERT(_payloadSize == _payloadCapacity); Q_ASSERT(_payloadSize == _payloadCapacity);
adjustPayloadStartAndCapacity(_payloadSize > 0); adjustPayloadStartAndCapacity(_payloadSize > 0);
readType();
readVersion();
readSourceID(); readSourceID();
} }
@ -135,20 +145,29 @@ NLPacket& NLPacket::operator=(NLPacket&& other) {
return *this; return *this;
} }
PacketType NLPacket::typeInHeader(const udt::Packet& packet) {
return *reinterpret_cast<const PacketType*>(packet.getData());
}
PacketVersion NLPacket::versionInHeader(const udt::Packet& packet) {
return *reinterpret_cast<const PacketVersion*>(packet.getData() + sizeof(PacketType));
}
QUuid NLPacket::sourceIDInHeader(const udt::Packet& packet) { QUuid NLPacket::sourceIDInHeader(const udt::Packet& packet) {
int offset = packet.Packet::localHeaderSize(); int offset = packet.Packet::localHeaderSize() + sizeof(PacketType) + sizeof(PacketVersion);
return QUuid::fromRfc4122(QByteArray::fromRawData(packet.getData() + offset, NUM_BYTES_RFC4122_UUID)); return QUuid::fromRfc4122(QByteArray::fromRawData(packet.getData() + offset, NUM_BYTES_RFC4122_UUID));
} }
QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) { QByteArray NLPacket::verificationHashInHeader(const udt::Packet& packet) {
int offset = packet.Packet::localHeaderSize() + NUM_BYTES_RFC4122_UUID; int offset = packet.Packet::localHeaderSize() + sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID;
return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH); return QByteArray(packet.getData() + offset, NUM_BYTES_MD5_HASH);
} }
QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret) { QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret) {
QCryptographicHash hash(QCryptographicHash::Md5); QCryptographicHash hash(QCryptographicHash::Md5);
int offset = packet.Packet::localHeaderSize() + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH; int offset = packet.Packet::localHeaderSize() + sizeof(PacketType) + sizeof(PacketVersion)
+ NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH;
// add the packet payload and the connection UUID // add the packet payload and the connection UUID
hash.addData(packet.getData() + offset, packet.getDataSize() - offset); hash.addData(packet.getData() + offset, packet.getDataSize() - offset);
@ -158,6 +177,36 @@ QByteArray NLPacket::hashForPacketAndSecret(const udt::Packet& packet, const QUu
return hash.result(); return hash.result();
} }
void NLPacket::writePacketTypeAndVersion() {
// Pack the packet type
memcpy(_packet.get(), &_type, sizeof(PacketType));
// Pack the packet version
auto version = versionForPacketType(_type);
memcpy(_packet.get() + sizeof(PacketType), &version, sizeof(version));
}
void NLPacket::setType(PacketType type) {
auto currentHeaderSize = totalHeadersSize();
_type = type;
_version = versionForPacketType(_type);
writePacketTypeAndVersion();
// Setting new packet type with a different header size not currently supported
Q_ASSERT(currentHeaderSize == totalHeadersSize());
Q_UNUSED(currentHeaderSize);
}
void NLPacket::readType() {
_type = NLPacket::typeInHeader(*this);
}
void NLPacket::readVersion() {
_version = NLPacket::versionInHeader(*this);
}
void NLPacket::adjustPayloadStartAndCapacity(bool shouldDecreasePayloadSize) { void NLPacket::adjustPayloadStartAndCapacity(bool shouldDecreasePayloadSize) {
qint64 headerSize = localHeaderSize(_type); qint64 headerSize = localHeaderSize(_type);
_payloadStart += headerSize; _payloadStart += headerSize;

View file

@ -19,7 +19,7 @@
class NLPacket : public udt::Packet { class NLPacket : public udt::Packet {
Q_OBJECT Q_OBJECT
public: public:
static std::unique_ptr<NLPacket> create(PacketType::Value type, qint64 size = -1); static std::unique_ptr<NLPacket> create(PacketType type, qint64 size = -1);
static std::unique_ptr<NLPacket> fromReceivedPacket(std::unique_ptr<char> data, qint64 size, static std::unique_ptr<NLPacket> fromReceivedPacket(std::unique_ptr<char> data, qint64 size,
const HifiSockAddr& senderSockAddr); const HifiSockAddr& senderSockAddr);
static std::unique_ptr<NLPacket> fromBase(std::unique_ptr<Packet> packet); static std::unique_ptr<NLPacket> fromBase(std::unique_ptr<Packet> packet);
@ -27,15 +27,24 @@ public:
// Provided for convenience, try to limit use // Provided for convenience, try to limit use
static std::unique_ptr<NLPacket> createCopy(const NLPacket& other); static std::unique_ptr<NLPacket> createCopy(const NLPacket& other);
static PacketType typeInHeader(const udt::Packet& packet);
static PacketVersion versionInHeader(const udt::Packet& packet);
static QUuid sourceIDInHeader(const udt::Packet& packet); static QUuid sourceIDInHeader(const udt::Packet& packet);
static QByteArray verificationHashInHeader(const udt::Packet& packet); static QByteArray verificationHashInHeader(const udt::Packet& packet);
static QByteArray hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret); static QByteArray hashForPacketAndSecret(const udt::Packet& packet, const QUuid& connectionSecret);
static qint64 localHeaderSize(PacketType::Value type); static qint64 maxPayloadSize(PacketType type);
static qint64 maxPayloadSize(PacketType::Value type); static qint64 localHeaderSize(PacketType type);
virtual qint64 maxPayloadSize() const; // The maximum payload size this packet can use to fit in MTU
virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers
virtual qint64 localHeaderSize() const; // Current level's header size virtual qint64 localHeaderSize() const; // Current level's header size
PacketType getType() const { return _type; }
void setType(PacketType type);
PacketVersion getVersion() const { return _version; }
const QUuid& getSourceID() const { return _sourceID; } const QUuid& getSourceID() const { return _sourceID; }
@ -44,10 +53,8 @@ public:
protected: protected:
void adjustPayloadStartAndCapacity(bool shouldDecreasePayloadSize = false); NLPacket(PacketType type, bool forceReliable = false, bool isPartOfMessage = false);
NLPacket(PacketType type, qint64 size, bool forceReliable = false, bool isPartOfMessage = false);
NLPacket(PacketType::Value type);
NLPacket(PacketType::Value type, qint64 size);
NLPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr); NLPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr);
NLPacket(std::unique_ptr<Packet> packet); NLPacket(std::unique_ptr<Packet> packet);
NLPacket(const NLPacket& other); NLPacket(const NLPacket& other);
@ -55,9 +62,19 @@ protected:
NLPacket& operator=(const NLPacket& other); NLPacket& operator=(const NLPacket& other);
NLPacket& operator=(NLPacket&& other); NLPacket& operator=(NLPacket&& other);
void adjustPayloadStartAndCapacity(bool shouldDecreasePayloadSize = false);
// Header writers
void writePacketTypeAndVersion();
// Header readers, used to set member variables after getting a packet from the network
void readType();
void readVersion();
void readSourceID(); void readSourceID();
PacketType _type;
PacketVersion _version;
QUuid _sourceID; QUuid _sourceID;
}; };

View file

@ -13,7 +13,7 @@
#include "NLPacket.h" #include "NLPacket.h"
NLPacketList::NLPacketList(PacketType::Value packetType, QByteArray extendedHeader) : NLPacketList::NLPacketList(PacketType packetType, QByteArray extendedHeader) :
PacketList(packetType, extendedHeader) PacketList(packetType, extendedHeader)
{ {

View file

@ -16,7 +16,7 @@
class NLPacketList : public udt::PacketList { class NLPacketList : public udt::PacketList {
public: public:
NLPacketList(PacketType::Value packetType, QByteArray extendedHeader = QByteArray()); NLPacketList(PacketType packetType, QByteArray extendedHeader = QByteArray());
private: private:
NLPacketList(const NLPacketList& other) = delete; NLPacketList(const NLPacketList& other) = delete;

View file

@ -85,7 +85,7 @@ private:
bool _canAdjustLocks; bool _canAdjustLocks;
bool _canRez; bool _canRez;
std::map<PacketType::Value, udt::Packet::SequenceNumber> _lastSequenceNumbers; std::map<PacketType, udt::Packet::SequenceNumber> _lastSequenceNumbers;
}; };
typedef QSharedPointer<Node> SharedNodePointer; typedef QSharedPointer<Node> SharedNodePointer;

View file

@ -231,7 +231,7 @@ void NodeList::sendDomainServerCheckIn() {
} else if (!_domainHandler.getIP().isNull()) { } else if (!_domainHandler.getIP().isNull()) {
bool isUsingDTLS = false; bool isUsingDTLS = false;
PacketType::Value domainPacketType = !_domainHandler.isConnected() PacketType domainPacketType = !_domainHandler.isConnected()
? PacketType::DomainConnectRequest : PacketType::DomainListRequest; ? PacketType::DomainConnectRequest : PacketType::DomainListRequest;
if (!_domainHandler.isConnected()) { if (!_domainHandler.isConnected()) {
@ -525,7 +525,7 @@ void NodeList::parseNodeFromPacketStream(QDataStream& packetStream) {
void NodeList::sendAssignment(Assignment& assignment) { void NodeList::sendAssignment(Assignment& assignment) {
PacketType::Value assignmentPacketType = assignment.getCommand() == Assignment::CreateCommand PacketType assignmentPacketType = assignment.getCommand() == Assignment::CreateCommand
? PacketType::CreateAssignment ? PacketType::CreateAssignment
: PacketType::RequestAssignment; : PacketType::RequestAssignment;

View file

@ -24,11 +24,11 @@ PacketReceiver::PacketReceiver(QObject* parent) :
qRegisterMetaType<QSharedPointer<NLPacket>>(); qRegisterMetaType<QSharedPointer<NLPacket>>();
} }
bool PacketReceiver::registerListenerForTypes(const QSet<PacketType::Value>& types, QObject* listener, const char* slot) { bool PacketReceiver::registerListenerForTypes(const QSet<PacketType>& types, QObject* listener, const char* slot) {
QSet<PacketType::Value> nonSourcedTypes; QSet<PacketType> nonSourcedTypes;
QSet<PacketType::Value> sourcedTypes; QSet<PacketType> sourcedTypes;
foreach(PacketType::Value type, types) { foreach(PacketType type, types) {
if (NON_SOURCED_PACKETS.contains(type)) { if (NON_SOURCED_PACKETS.contains(type)) {
nonSourcedTypes << type; nonSourcedTypes << type;
} else { } else {
@ -41,7 +41,7 @@ bool PacketReceiver::registerListenerForTypes(const QSet<PacketType::Value>& typ
if (nonSourcedTypes.size() > 0) { if (nonSourcedTypes.size() > 0) {
QMetaMethod nonSourcedMethod = matchingMethodForListener(*nonSourcedTypes.begin(), listener, slot); QMetaMethod nonSourcedMethod = matchingMethodForListener(*nonSourcedTypes.begin(), listener, slot);
if (nonSourcedMethod.isValid()) { if (nonSourcedMethod.isValid()) {
foreach(PacketType::Value type, nonSourcedTypes) { foreach(PacketType type, nonSourcedTypes) {
registerVerifiedListener(type, listener, nonSourcedMethod); registerVerifiedListener(type, listener, nonSourcedMethod);
} }
} else { } else {
@ -52,7 +52,7 @@ bool PacketReceiver::registerListenerForTypes(const QSet<PacketType::Value>& typ
if (sourcedTypes.size() > 0) { if (sourcedTypes.size() > 0) {
QMetaMethod sourcedMethod = matchingMethodForListener(*sourcedTypes.begin(), listener, slot); QMetaMethod sourcedMethod = matchingMethodForListener(*sourcedTypes.begin(), listener, slot);
if (sourcedMethod.isValid()) { if (sourcedMethod.isValid()) {
foreach(PacketType::Value type, sourcedTypes) { foreach(PacketType type, sourcedTypes) {
registerVerifiedListener(type, listener, sourcedMethod); registerVerifiedListener(type, listener, sourcedMethod);
} }
} else { } else {
@ -63,7 +63,7 @@ bool PacketReceiver::registerListenerForTypes(const QSet<PacketType::Value>& typ
return true; return true;
} }
void PacketReceiver::registerDirectListener(PacketType::Value type, QObject* listener, const char* slot) { void PacketReceiver::registerDirectListener(PacketType type, QObject* listener, const char* slot) {
bool success = registerListener(type, listener, slot); bool success = registerListener(type, listener, slot);
if (success) { if (success) {
_directConnectSetMutex.lock(); _directConnectSetMutex.lock();
@ -75,7 +75,7 @@ void PacketReceiver::registerDirectListener(PacketType::Value type, QObject* lis
} }
} }
void PacketReceiver::registerDirectListenerForTypes(const QSet<PacketType::Value>& types, void PacketReceiver::registerDirectListenerForTypes(const QSet<PacketType>& types,
QObject* listener, const char* slot) { QObject* listener, const char* slot) {
// just call register listener for types to start // just call register listener for types to start
bool success = registerListenerForTypes(types, listener, slot); bool success = registerListenerForTypes(types, listener, slot);
@ -89,7 +89,7 @@ void PacketReceiver::registerDirectListenerForTypes(const QSet<PacketType::Value
} }
} }
bool PacketReceiver::registerListener(PacketType::Value type, QObject* listener, const char* slot) { bool PacketReceiver::registerListener(PacketType type, QObject* listener, const char* slot) {
Q_ASSERT(listener); Q_ASSERT(listener);
QMetaMethod matchingMethod = matchingMethodForListener(type, listener, slot); QMetaMethod matchingMethod = matchingMethodForListener(type, listener, slot);
@ -102,7 +102,7 @@ bool PacketReceiver::registerListener(PacketType::Value type, QObject* listener,
} }
} }
QMetaMethod PacketReceiver::matchingMethodForListener(PacketType::Value type, QObject* object, const char* slot) const { QMetaMethod PacketReceiver::matchingMethodForListener(PacketType type, QObject* object, const char* slot) const {
Q_ASSERT(object); Q_ASSERT(object);
// normalize the slot with the expected parameters // normalize the slot with the expected parameters
@ -155,7 +155,7 @@ QMetaMethod PacketReceiver::matchingMethodForListener(PacketType::Value type, QO
} }
} }
void PacketReceiver::registerVerifiedListener(PacketType::Value type, QObject* object, const QMetaMethod& slot) { void PacketReceiver::registerVerifiedListener(PacketType type, QObject* object, const QMetaMethod& slot) {
_packetListenerLock.lock(); _packetListenerLock.lock();
if (_packetListenerMap.contains(type)) { if (_packetListenerMap.contains(type)) {
@ -243,7 +243,7 @@ void PacketReceiver::handleVerifiedPacket(std::unique_ptr<udt::Packet> packet) {
_directConnectSetMutex.unlock(); _directConnectSetMutex.unlock();
PacketType::Value packetType = nlPacket->getType(); PacketType packetType = nlPacket->getType();
if (matchingNode) { if (matchingNode) {
emit dataReceived(matchingNode->getType(), nlPacket->getDataSize()); emit dataReceived(matchingNode->getType(), nlPacket->getDataSize());
@ -311,7 +311,7 @@ void PacketReceiver::handleVerifiedPacket(std::unique_ptr<udt::Packet> packet) {
qWarning() << "No listener found for packet type " << nameForPacketType(nlPacket->getType()); qWarning() << "No listener found for packet type " << nameForPacketType(nlPacket->getType());
// insert a dummy listener so we don't print this again // insert a dummy listener so we don't print this again
_packetListenerMap.insert(packet->getType(), { nullptr, QMetaMethod() }); _packetListenerMap.insert(nlPacket->getType(), { nullptr, QMetaMethod() });
} }
_packetListenerLock.unlock(); _packetListenerLock.unlock();

View file

@ -41,8 +41,8 @@ public:
void resetCounters() { _inPacketCount = 0; _inByteCount = 0; } void resetCounters() { _inPacketCount = 0; _inByteCount = 0; }
bool registerListenerForTypes(const QSet<PacketType::Value>& types, QObject* listener, const char* slot); bool registerListenerForTypes(const QSet<PacketType>& types, QObject* listener, const char* slot);
bool registerListener(PacketType::Value type, QObject* listener, const char* slot); bool registerListener(PacketType type, QObject* listener, const char* slot);
void unregisterListener(QObject* listener); void unregisterListener(QObject* listener);
void handleVerifiedPacket(std::unique_ptr<udt::Packet> packet); void handleVerifiedPacket(std::unique_ptr<udt::Packet> packet);
@ -53,16 +53,16 @@ signals:
private: private:
// these are brutal hacks for now - ideally GenericThread / ReceivedPacketProcessor // these are brutal hacks for now - ideally GenericThread / ReceivedPacketProcessor
// should be changed to have a true event loop and be able to handle our QMetaMethod::invoke // should be changed to have a true event loop and be able to handle our QMetaMethod::invoke
void registerDirectListenerForTypes(const QSet<PacketType::Value>& types, QObject* listener, const char* slot); void registerDirectListenerForTypes(const QSet<PacketType>& types, QObject* listener, const char* slot);
void registerDirectListener(PacketType::Value type, QObject* listener, const char* slot); void registerDirectListener(PacketType type, QObject* listener, const char* slot);
QMetaMethod matchingMethodForListener(PacketType::Value type, QObject* object, const char* slot) const; QMetaMethod matchingMethodForListener(PacketType type, QObject* object, const char* slot) const;
void registerVerifiedListener(PacketType::Value type, QObject* listener, const QMetaMethod& slot); void registerVerifiedListener(PacketType type, QObject* listener, const QMetaMethod& slot);
using ObjectMethodPair = std::pair<QPointer<QObject>, QMetaMethod>; using ObjectMethodPair = std::pair<QPointer<QObject>, QMetaMethod>;
QMutex _packetListenerLock; QMutex _packetListenerLock;
QHash<PacketType::Value, ObjectMethodPair> _packetListenerMap; QHash<PacketType, ObjectMethodPair> _packetListenerMap;
int _inPacketCount = 0; int _inPacketCount = 0;
int _inByteCount = 0; int _inByteCount = 0;
bool _shouldDropPackets = false; bool _shouldDropPackets = false;

View file

@ -15,18 +15,8 @@ using namespace udt;
const qint64 Packet::PACKET_WRITE_ERROR = -1; const qint64 Packet::PACKET_WRITE_ERROR = -1;
qint64 Packet::localHeaderSize(PacketType::Value type) { std::unique_ptr<Packet> Packet::create(qint64 size, bool isReliable, bool isPartOfMessage) {
// TODO: check the bitfield to see if the message is included auto packet = std::unique_ptr<Packet>(new Packet(size, isReliable, isPartOfMessage));
qint64 size = sizeof(SequenceNumberAndBitField);
return size;
}
qint64 Packet::maxPayloadSize(PacketType::Value type) {
return MAX_PACKET_SIZE - localHeaderSize(type);
}
std::unique_ptr<Packet> Packet::create(PacketType::Value type, qint64 size) {
auto packet = std::unique_ptr<Packet>(new Packet(type, size));
packet->open(QIODevice::ReadWrite); packet->open(QIODevice::ReadWrite);
@ -49,25 +39,38 @@ std::unique_ptr<Packet> Packet::createCopy(const Packet& other) {
return std::unique_ptr<Packet>(new Packet(other)); return std::unique_ptr<Packet>(new Packet(other));
} }
qint64 Packet::maxPayloadSize(bool isPartOfMessage) {
return MAX_PACKET_SIZE - localHeaderSize(isPartOfMessage);
}
qint64 Packet::localHeaderSize(bool isPartOfMessage) {
return sizeof(SequenceNumberAndBitField) + (isPartOfMessage ? sizeof(MessageNumberAndBitField) : 0);
}
qint64 Packet::maxPayloadSize() const {
return MAX_PACKET_SIZE - localHeaderSize();
}
qint64 Packet::totalHeadersSize() const { qint64 Packet::totalHeadersSize() const {
return localHeaderSize(); return localHeaderSize();
} }
qint64 Packet::localHeaderSize() const { qint64 Packet::localHeaderSize() const {
return localHeaderSize(_type); return localHeaderSize(_isPartOfMessage);
} }
Packet::Packet(PacketType::Value type, qint64 size) : Packet::Packet(qint64 size, bool isReliable, bool isPartOfMessage) :
_type(type), _isReliable(isReliable),
_version(0) _isPartOfMessage(isPartOfMessage)
{ {
auto maxPayload = maxPayloadSize(type); auto maxPayload = maxPayloadSize();
if (size == -1) { if (size == -1) {
// default size of -1, means biggest packet possible // default size of -1, means biggest packet possible
size = maxPayload; size = maxPayload;
} }
_packetSize = localHeaderSize(type) + size; _packetSize = localHeaderSize() + size;
_packet.reset(new char[_packetSize]); _packet.reset(new char[_packetSize]);
_payloadCapacity = size; _payloadCapacity = size;
_payloadStart = _packet.get() + (_packetSize - _payloadCapacity); _payloadStart = _packet.get() + (_packetSize - _payloadCapacity);
@ -84,9 +87,11 @@ Packet::Packet(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& send
_packet(std::move(data)), _packet(std::move(data)),
_senderSockAddr(senderSockAddr) _senderSockAddr(senderSockAddr)
{ {
_type = readType(); readIsReliable();
_version = readVersion(); readIsPartOfMessage();
_payloadCapacity = _packetSize - localHeaderSize(_type); readSequenceNumber();
_payloadCapacity = _packetSize - localHeaderSize();
_payloadSize = _payloadCapacity; _payloadSize = _payloadCapacity;
_payloadStart = _packet.get() + (_packetSize - _payloadCapacity); _payloadStart = _packet.get() + (_packetSize - _payloadCapacity);
} }
@ -98,9 +103,6 @@ Packet::Packet(const Packet& other) :
} }
Packet& Packet::operator=(const Packet& other) { Packet& Packet::operator=(const Packet& other) {
_type = other._type;
_version = other._version;
_packetSize = other._packetSize; _packetSize = other._packetSize;
_packet = std::unique_ptr<char>(new char[_packetSize]); _packet = std::unique_ptr<char>(new char[_packetSize]);
memcpy(_packet.get(), other._packet.get(), _packetSize); memcpy(_packet.get(), other._packet.get(), _packetSize);
@ -124,9 +126,6 @@ Packet::Packet(Packet&& other) {
} }
Packet& Packet::operator=(Packet&& other) { Packet& Packet::operator=(Packet&& other) {
_type = other._type;
_version = other._version;
_packetSize = other._packetSize; _packetSize = other._packetSize;
_packet = std::move(other._packet); _packet = std::move(other._packet);
@ -164,55 +163,38 @@ bool Packet::reset() {
return QIODevice::reset(); return QIODevice::reset();
} }
void Packet::setType(PacketType::Value type) {
auto currentHeaderSize = totalHeadersSize();
_type = type;
writePacketTypeAndVersion(_type);
// Setting new packet type with a different header size not currently supported
Q_ASSERT(currentHeaderSize == totalHeadersSize());
Q_UNUSED(currentHeaderSize);
}
PacketType::Value Packet::readType() const {
return (PacketType::Value)arithmeticCodingValueFromBuffer(_packet.get());
}
PacketVersion Packet::readVersion() const {
return *reinterpret_cast<PacketVersion*>(_packet.get() + numBytesForArithmeticCodedPacketType(_type));
}
static const uint32_t CONTROL_BIT_MASK = 1 << (sizeof(Packet::SequenceNumberAndBitField) - 1); static const uint32_t CONTROL_BIT_MASK = 1 << (sizeof(Packet::SequenceNumberAndBitField) - 1);
static const uint32_t RELIABILITY_BIT_MASK = 1 << (sizeof(Packet::SequenceNumberAndBitField) - 2); static const uint32_t RELIABILITY_BIT_MASK = 1 << (sizeof(Packet::SequenceNumberAndBitField) - 2);
static const uint32_t MESSAGE_BIT_MASK = 1 << (sizeof(Packet::SequenceNumberAndBitField) - 3); static const uint32_t MESSAGE_BIT_MASK = 1 << (sizeof(Packet::SequenceNumberAndBitField) - 3);
static const int BIT_FIELD_LENGTH = 3;
static const uint32_t BIT_FIELD_MASK = CONTROL_BIT_MASK | RELIABILITY_BIT_MASK | MESSAGE_BIT_MASK; static const uint32_t BIT_FIELD_MASK = CONTROL_BIT_MASK | RELIABILITY_BIT_MASK | MESSAGE_BIT_MASK;
void Packet::readIsReliable() {
Packet::SequenceNumber Packet::readSequenceNumber() const {
SequenceNumberAndBitField seqNumBitField = *reinterpret_cast<SequenceNumberAndBitField*>(_packet.get()); SequenceNumberAndBitField seqNumBitField = *reinterpret_cast<SequenceNumberAndBitField*>(_packet.get());
return seqNumBitField & ~BIT_FIELD_MASK; // Remove the bit field _isReliable = (bool) (seqNumBitField & RELIABILITY_BIT_MASK); // Only keep reliability bit
} }
bool Packet::readIsControlPacket() const { void Packet::readIsPartOfMessage() {
SequenceNumberAndBitField seqNumBitField = *reinterpret_cast<SequenceNumberAndBitField*>(_packet.get()); SequenceNumberAndBitField seqNumBitField = *reinterpret_cast<SequenceNumberAndBitField*>(_packet.get());
return seqNumBitField & CONTROL_BIT_MASK; // Only keep control bit _isReliable = (bool) (seqNumBitField & MESSAGE_BIT_MASK); // Only keep message bit
} }
void Packet::writePacketTypeAndVersion(PacketType::Value type) { void Packet::readSequenceNumber() {
// Pack the packet type SequenceNumberAndBitField seqNumBitField = *reinterpret_cast<SequenceNumberAndBitField*>(_packet.get());
auto offset = packArithmeticallyCodedValue(type, _packet.get()); _sequenceNumber = (seqNumBitField & ~BIT_FIELD_MASK); // Remove the bit field
// Pack the packet version
auto version = versionForPacketType(type);
memcpy(_packet.get() + offset, &version, sizeof(version));
} }
void Packet::writeSequenceNumber(SequenceNumber seqNum) { static const uint32_t MAX_SEQUENCE_NUMBER = UINT32_MAX >> BIT_FIELD_LENGTH;
// Here we are overriding the control bit to 0.
// But that is not an issue since we should only ever set the seqNum void Packet::writeSequenceNumber(SequenceNumber sequenceNumber) {
// for data packets going out // make sure this is a sequence number <= 29 bit unsigned max (536,870,911)
memcpy(_packet.get() + numBytesForArithmeticCodedPacketType(_type) + sizeof(PacketVersion), Q_ASSERT(sequenceNumber <= MAX_SEQUENCE_NUMBER);
&seqNum, sizeof(seqNum));
// grab pointer to current SequenceNumberAndBitField
SequenceNumberAndBitField* seqNumBitField = reinterpret_cast<SequenceNumberAndBitField*>(_packet.get());
// write new value by ORing (old value & BIT_FIELD_MASK) with new seqNum
*seqNumBitField = (*seqNumBitField & BIT_FIELD_MASK) | sequenceNumber;
} }
QByteArray Packet::read(qint64 maxSize) { QByteArray Packet::read(qint64 maxSize) {

View file

@ -24,25 +24,33 @@ namespace udt {
class Packet : public QIODevice { class Packet : public QIODevice {
Q_OBJECT Q_OBJECT
public: public:
// NOTE: The SequenceNumber must actually only be 29 bits MAX to leave room for a bit field // NOTE: The SequenceNumber is only actually 29 bits to leave room for a bit field
using SequenceNumber = uint32_t; using SequenceNumber = uint32_t;
using SequenceNumberAndBitField = uint32_t; using SequenceNumberAndBitField = uint32_t;
// NOTE: The MessageNumber is only actually 29 bits to leave room for a bit field
using MessageNumber = uint32_t;
using MessageNumberAndBitField = uint32_t;
static const uint32_t DEFAULT_SEQUENCE_NUMBER = 0; static const uint32_t DEFAULT_SEQUENCE_NUMBER = 0;
static const qint64 PACKET_WRITE_ERROR; static const qint64 PACKET_WRITE_ERROR;
static std::unique_ptr<Packet> create(PacketType::Value type, qint64 size = -1); static std::unique_ptr<Packet> create(qint64 size = -1, bool isReliable = false, bool isPartOfMessage = false);
static std::unique_ptr<Packet> fromReceivedPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr); static std::unique_ptr<Packet> fromReceivedPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr);
// Provided for convenience, try to limit use // Provided for convenience, try to limit use
static std::unique_ptr<Packet> createCopy(const Packet& other); static std::unique_ptr<Packet> createCopy(const Packet& other);
static qint64 localHeaderSize(PacketType::Value type); // The maximum payload size this packet can use to fit in MTU
static qint64 maxPayloadSize(PacketType::Value type); static qint64 maxPayloadSize(bool isPartOfMessage);
virtual qint64 maxPayloadSize() const;
// Current level's header size
static qint64 localHeaderSize(bool isPartOfMessage);
virtual qint64 localHeaderSize() const;
virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers
virtual qint64 localHeaderSize() const; // Current level's header size
// Payload direct access to the payload, use responsibly! // Payload direct access to the payload, use responsibly!
char* getPayload() { return _payloadStart; } char* getPayload() { return _payloadStart; }
@ -51,11 +59,6 @@ public:
// Return direct access to the entire packet, use responsibly! // Return direct access to the entire packet, use responsibly!
char* getData() { return _packet.get(); } char* getData() { return _packet.get(); }
const char* getData() const { return _packet.get(); } const char* getData() const { return _packet.get(); }
PacketType::Value getType() const { return _type; }
void setType(PacketType::Value type);
PacketVersion getVersion() const { return _version; }
// Returns the size of the packet, including the header // Returns the size of the packet, including the header
qint64 getDataSize() const { return totalHeadersSize() + _payloadSize; } qint64 getDataSize() const { return totalHeadersSize() + _payloadSize; }
@ -75,9 +78,7 @@ public:
HifiSockAddr& getSenderSockAddr() { return _senderSockAddr; } HifiSockAddr& getSenderSockAddr() { return _senderSockAddr; }
const HifiSockAddr& getSenderSockAddr() const { return _senderSockAddr; } const HifiSockAddr& getSenderSockAddr() const { return _senderSockAddr; }
void writeSequenceNumber(SequenceNumber seqNum); void writeSequenceNumber(SequenceNumber sequenceNumber);
SequenceNumber readSequenceNumber() const;
bool readIsControlPacket() const;
// QIODevice virtual functions // QIODevice virtual functions
// WARNING: Those methods all refer to the payload ONLY and NOT the entire packet // WARNING: Those methods all refer to the payload ONLY and NOT the entire packet
@ -93,26 +94,21 @@ public:
template<typename T> qint64 writePrimitive(const T& data); template<typename T> qint64 writePrimitive(const T& data);
protected: protected:
Packet(PacketType::Value type, qint64 size); Packet(qint64 size, bool isReliable = false, bool isPartOfMessage = false);
Packet(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr); Packet(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr);
Packet(const Packet& other); Packet(const Packet& other);
Packet& operator=(const Packet& other); Packet& operator=(const Packet& other);
Packet(Packet&& other); Packet(Packet&& other);
Packet& operator=(Packet&& other); Packet& operator=(Packet&& other);
// Header readers
PacketType::Value readType() const;
PacketVersion readVersion() const;
// QIODevice virtual functions // QIODevice virtual functions
virtual qint64 writeData(const char* data, qint64 maxSize); virtual qint64 writeData(const char* data, qint64 maxSize);
virtual qint64 readData(char* data, qint64 maxSize); virtual qint64 readData(char* data, qint64 maxSize);
// Header writers // Header readers - these read data to member variables after pulling packet off wire
void writePacketTypeAndVersion(PacketType::Value type); void readIsPartOfMessage();
void readIsReliable();
PacketType::Value _type; // Packet type void readSequenceNumber();
PacketVersion _version; // Packet version
qint64 _packetSize = 0; // Total size of the allocated memory qint64 _packetSize = 0; // Total size of the allocated memory
std::unique_ptr<char> _packet; // Allocated memory std::unique_ptr<char> _packet; // Allocated memory
@ -121,6 +117,10 @@ protected:
qint64 _payloadCapacity = 0; // Total capacity of the payload qint64 _payloadCapacity = 0; // Total capacity of the payload
qint64 _payloadSize = 0; // How much of the payload is actually used qint64 _payloadSize = 0; // How much of the payload is actually used
bool _isReliable { false };
bool _isPartOfMessage { false };
SequenceNumber _sequenceNumber { 0 };
HifiSockAddr _senderSockAddr; // sender address for packet (only used on receiving end) HifiSockAddr _senderSockAddr; // sender address for packet (only used on receiving end)
}; };

View file

@ -15,22 +15,22 @@
#include <QtCore/QDebug> #include <QtCore/QDebug>
using namespace PacketType; const QSet<PacketType> NON_VERIFIED_PACKETS = QSet<PacketType>()
<< PacketType::NodeJsonStats << PacketType::EntityQuery
<< PacketType::OctreeDataNack << PacketType::EntityEditNack
<< PacketType::DomainListRequest << PacketType::StopNode;
const QSet<PacketType::Value> NON_VERIFIED_PACKETS = QSet<PacketType::Value>() const QSet<PacketType> NON_SOURCED_PACKETS = QSet<PacketType>()
<< NodeJsonStats << EntityQuery << PacketType::StunResponse << PacketType::CreateAssignment << PacketType::RequestAssignment
<< OctreeDataNack << EntityEditNack << PacketType::DomainServerRequireDTLS << PacketType::DomainConnectRequest
<< DomainListRequest << StopNode; << PacketType::DomainList << PacketType::DomainConnectionDenied
<< PacketType::DomainServerPathQuery << PacketType::DomainServerPathResponse
<< PacketType::DomainServerAddedNode
<< PacketType::ICEServerPeerInformation << PacketType::ICEServerQuery << PacketType::ICEServerHeartbeat
<< PacketType::ICEPing << PacketType::ICEPingReply
<< PacketType::AssignmentClientStatus << PacketType::StopNode;
const QSet<PacketType::Value> NON_SOURCED_PACKETS = QSet<PacketType::Value>() const QSet<PacketType> RELIABLE_PACKETS = QSet<PacketType>();
<< StunResponse << CreateAssignment << RequestAssignment
<< DomainServerRequireDTLS << DomainConnectRequest
<< DomainList << DomainConnectionDenied
<< DomainServerPathQuery << DomainServerPathResponse
<< DomainServerAddedNode
<< ICEServerPeerInformation << ICEServerQuery << ICEServerHeartbeat
<< ICEPing << ICEPingReply
<< AssignmentClientStatus << StopNode;
int arithmeticCodingValueFromBuffer(const char* checkValue) { int arithmeticCodingValueFromBuffer(const char* checkValue) {
if (((uchar) *checkValue) < 255) { if (((uchar) *checkValue) < 255) {
@ -60,11 +60,11 @@ int packArithmeticallyCodedValue(int value, char* destination) {
} }
} }
PacketVersion versionForPacketType(PacketType::Value packetType) { PacketVersion versionForPacketType(PacketType packetType) {
switch (packetType) { switch (packetType) {
case EntityAdd: case PacketType::EntityAdd:
case EntityEdit: case PacketType::EntityEdit:
case EntityData: case PacketType::EntityData:
return VERSION_ENTITIES_NEW_PROTOCOL_LAYER; return VERSION_ENTITIES_NEW_PROTOCOL_LAYER;
default: default:
return 11; return 11;
@ -73,56 +73,66 @@ PacketVersion versionForPacketType(PacketType::Value packetType) {
#define PACKET_TYPE_NAME_LOOKUP(x) case x: return QString(#x); #define PACKET_TYPE_NAME_LOOKUP(x) case x: return QString(#x);
QString nameForPacketType(PacketType::Value packetType) { QString nameForPacketType(PacketType packetType) {
switch (packetType) { switch (packetType) {
PACKET_TYPE_NAME_LOOKUP(Unknown); PACKET_TYPE_NAME_LOOKUP(PacketType::Unknown);
PACKET_TYPE_NAME_LOOKUP(StunResponse); PACKET_TYPE_NAME_LOOKUP(PacketType::StunResponse);
PACKET_TYPE_NAME_LOOKUP(DomainList); PACKET_TYPE_NAME_LOOKUP(PacketType::DomainList);
PACKET_TYPE_NAME_LOOKUP(Ping); PACKET_TYPE_NAME_LOOKUP(PacketType::Ping);
PACKET_TYPE_NAME_LOOKUP(PingReply); PACKET_TYPE_NAME_LOOKUP(PacketType::PingReply);
PACKET_TYPE_NAME_LOOKUP(KillAvatar); PACKET_TYPE_NAME_LOOKUP(PacketType::KillAvatar);
PACKET_TYPE_NAME_LOOKUP(AvatarData); PACKET_TYPE_NAME_LOOKUP(PacketType::AvatarData);
PACKET_TYPE_NAME_LOOKUP(InjectAudio); PACKET_TYPE_NAME_LOOKUP(PacketType::InjectAudio);
PACKET_TYPE_NAME_LOOKUP(MixedAudio); PACKET_TYPE_NAME_LOOKUP(PacketType::MixedAudio);
PACKET_TYPE_NAME_LOOKUP(MicrophoneAudioNoEcho); PACKET_TYPE_NAME_LOOKUP(PacketType::MicrophoneAudioNoEcho);
PACKET_TYPE_NAME_LOOKUP(MicrophoneAudioWithEcho); PACKET_TYPE_NAME_LOOKUP(PacketType::MicrophoneAudioWithEcho);
PACKET_TYPE_NAME_LOOKUP(BulkAvatarData); PACKET_TYPE_NAME_LOOKUP(PacketType::BulkAvatarData);
PACKET_TYPE_NAME_LOOKUP(SilentAudioFrame); PACKET_TYPE_NAME_LOOKUP(PacketType::SilentAudioFrame);
PACKET_TYPE_NAME_LOOKUP(DomainListRequest); PACKET_TYPE_NAME_LOOKUP(PacketType::DomainListRequest);
PACKET_TYPE_NAME_LOOKUP(RequestAssignment); PACKET_TYPE_NAME_LOOKUP(PacketType::RequestAssignment);
PACKET_TYPE_NAME_LOOKUP(CreateAssignment); PACKET_TYPE_NAME_LOOKUP(PacketType::CreateAssignment);
PACKET_TYPE_NAME_LOOKUP(DomainConnectionDenied); PACKET_TYPE_NAME_LOOKUP(PacketType::DomainConnectionDenied);
PACKET_TYPE_NAME_LOOKUP(MuteEnvironment); PACKET_TYPE_NAME_LOOKUP(PacketType::MuteEnvironment);
PACKET_TYPE_NAME_LOOKUP(AudioStreamStats); PACKET_TYPE_NAME_LOOKUP(PacketType::AudioStreamStats);
PACKET_TYPE_NAME_LOOKUP(OctreeStats); PACKET_TYPE_NAME_LOOKUP(PacketType::OctreeStats);
PACKET_TYPE_NAME_LOOKUP(Jurisdiction); PACKET_TYPE_NAME_LOOKUP(PacketType::Jurisdiction);
PACKET_TYPE_NAME_LOOKUP(JurisdictionRequest); PACKET_TYPE_NAME_LOOKUP(PacketType::JurisdictionRequest);
PACKET_TYPE_NAME_LOOKUP(AvatarIdentity); PACKET_TYPE_NAME_LOOKUP(PacketType::AvatarIdentity);
PACKET_TYPE_NAME_LOOKUP(AvatarBillboard); PACKET_TYPE_NAME_LOOKUP(PacketType::AvatarBillboard);
PACKET_TYPE_NAME_LOOKUP(DomainConnectRequest); PACKET_TYPE_NAME_LOOKUP(PacketType::DomainConnectRequest);
PACKET_TYPE_NAME_LOOKUP(DomainServerRequireDTLS); PACKET_TYPE_NAME_LOOKUP(PacketType::DomainServerRequireDTLS);
PACKET_TYPE_NAME_LOOKUP(NodeJsonStats); PACKET_TYPE_NAME_LOOKUP(PacketType::NodeJsonStats);
PACKET_TYPE_NAME_LOOKUP(EntityQuery); PACKET_TYPE_NAME_LOOKUP(PacketType::EntityQuery);
PACKET_TYPE_NAME_LOOKUP(EntityData); PACKET_TYPE_NAME_LOOKUP(PacketType::EntityData);
PACKET_TYPE_NAME_LOOKUP(EntityErase); PACKET_TYPE_NAME_LOOKUP(PacketType::EntityErase);
PACKET_TYPE_NAME_LOOKUP(OctreeDataNack); PACKET_TYPE_NAME_LOOKUP(PacketType::OctreeDataNack);
PACKET_TYPE_NAME_LOOKUP(StopNode); PACKET_TYPE_NAME_LOOKUP(PacketType::StopNode);
PACKET_TYPE_NAME_LOOKUP(AudioEnvironment); PACKET_TYPE_NAME_LOOKUP(PacketType::AudioEnvironment);
PACKET_TYPE_NAME_LOOKUP(EntityEditNack); PACKET_TYPE_NAME_LOOKUP(PacketType::EntityEditNack);
PACKET_TYPE_NAME_LOOKUP(ICEServerHeartbeat); PACKET_TYPE_NAME_LOOKUP(PacketType::ICEServerHeartbeat);
PACKET_TYPE_NAME_LOOKUP(DomainServerAddedNode); PACKET_TYPE_NAME_LOOKUP(PacketType::DomainServerAddedNode);
PACKET_TYPE_NAME_LOOKUP(ICEServerQuery); PACKET_TYPE_NAME_LOOKUP(PacketType::ICEServerQuery);
PACKET_TYPE_NAME_LOOKUP(ICEServerPeerInformation); PACKET_TYPE_NAME_LOOKUP(PacketType::ICEServerPeerInformation);
PACKET_TYPE_NAME_LOOKUP(ICEPing); PACKET_TYPE_NAME_LOOKUP(PacketType::ICEPing);
PACKET_TYPE_NAME_LOOKUP(ICEPingReply); PACKET_TYPE_NAME_LOOKUP(PacketType::ICEPingReply);
PACKET_TYPE_NAME_LOOKUP(EntityAdd); PACKET_TYPE_NAME_LOOKUP(PacketType::EntityAdd);
PACKET_TYPE_NAME_LOOKUP(EntityEdit); PACKET_TYPE_NAME_LOOKUP(PacketType::EntityEdit);
default: default:
return QString("Type: ") + QString::number((int)packetType); return QString("Type: ") + QString::number((int)packetType);
} }
return QString("unexpected"); return QString("unexpected");
} }
int numBytesForArithmeticCodedPacketType(PacketType::Value packetType) { int numBytesForArithmeticCodedPacketType(PacketType packetType) {
return (int) ceilf((float) packetType / 255); return (int) ceilf((float) packetType / 255);
} }
uint qHash(const PacketType& key, uint seed) {
// seems odd that Qt couldn't figure out this cast itself, but this fixes a compile error after switch to
// strongly typed enum for PacketType
return qHash((quint8) key, seed);
}
QDebug operator<<(QDebug debug, const PacketType& type) {
return debug.nospace() << (uint8_t) type << " (" << qPrintable(nameForPacketType(type)) << ")";
}

View file

@ -26,55 +26,53 @@
// NOTE: if adding a new packet packetType, you can replace one marked usable or add at the end // NOTE: if adding a new packet packetType, you can replace one marked usable or add at the end
// NOTE: if you want the name of the packet packetType to be available for debugging or logging, update nameForPacketType() as well // NOTE: if you want the name of the packet packetType to be available for debugging or logging, update nameForPacketType() as well
namespace PacketType { enum class PacketType : uint8_t {
enum Value { Unknown,
Unknown, StunResponse,
StunResponse, DomainList,
DomainList, Ping,
Ping, PingReply,
PingReply, KillAvatar,
KillAvatar, AvatarData,
AvatarData, InjectAudio,
InjectAudio, MixedAudio,
MixedAudio, MicrophoneAudioNoEcho,
MicrophoneAudioNoEcho, MicrophoneAudioWithEcho,
MicrophoneAudioWithEcho, BulkAvatarData,
BulkAvatarData, SilentAudioFrame,
SilentAudioFrame, DomainListRequest,
DomainListRequest, RequestAssignment,
RequestAssignment, CreateAssignment,
CreateAssignment, DomainConnectionDenied,
DomainConnectionDenied, MuteEnvironment,
MuteEnvironment, AudioStreamStats,
AudioStreamStats, DomainServerPathQuery,
DomainServerPathQuery, DomainServerPathResponse,
DomainServerPathResponse, DomainServerAddedNode,
DomainServerAddedNode, ICEServerPeerInformation,
ICEServerPeerInformation, ICEServerQuery,
ICEServerQuery, OctreeStats,
OctreeStats, Jurisdiction,
Jurisdiction, JurisdictionRequest,
JurisdictionRequest, AssignmentClientStatus,
AssignmentClientStatus, NoisyMute,
NoisyMute, AvatarIdentity,
AvatarIdentity, AvatarBillboard,
AvatarBillboard, DomainConnectRequest,
DomainConnectRequest, DomainServerRequireDTLS,
DomainServerRequireDTLS, NodeJsonStats,
NodeJsonStats, OctreeDataNack,
OctreeDataNack, StopNode,
StopNode, AudioEnvironment,
AudioEnvironment, EntityEditNack,
EntityEditNack, ICEServerHeartbeat,
ICEServerHeartbeat, ICEPing,
ICEPing, ICEPingReply,
ICEPingReply, EntityData,
EntityData, EntityQuery,
EntityQuery, EntityAdd,
EntityAdd, EntityErase,
EntityErase, EntityEdit
EntityEdit
};
}; };
const int NUM_BYTES_MD5_HASH = 16; const int NUM_BYTES_MD5_HASH = 16;
@ -84,19 +82,23 @@ const int MAX_PACKET_HEADER_BYTES = 4 + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_H
typedef char PacketVersion; typedef char PacketVersion;
extern const QSet<PacketType::Value> NON_VERIFIED_PACKETS; extern const QSet<PacketType> NON_VERIFIED_PACKETS;
extern const QSet<PacketType::Value> NON_SOURCED_PACKETS; extern const QSet<PacketType> NON_SOURCED_PACKETS;
extern const QSet<PacketType> RELIABLE_PACKETS;
QString nameForPacketType(PacketType::Value packetType); QString nameForPacketType(PacketType packetType);
PacketVersion versionForPacketType(PacketType::Value packetType); PacketVersion versionForPacketType(PacketType packetType);
int numBytesForArithmeticCodedPacketType(PacketType::Value packetType); int numBytesForArithmeticCodedPacketType(PacketType packetType);
int numBytesForPacketHeaderGivenPacketType(PacketType::Value packetType); int numBytesForPacketHeaderGivenPacketType(PacketType packetType);
int packArithmeticallyCodedValue(int value, char* destination); int packArithmeticallyCodedValue(int value, char* destination);
int arithmeticCodingValueFromBuffer(const char* checkValue); int arithmeticCodingValueFromBuffer(const char* checkValue);
int numBytesArithmeticCodingFromBuffer(const char* checkValue); int numBytesArithmeticCodingFromBuffer(const char* checkValue);
uint qHash(const PacketType& key, uint seed);
QDebug operator<<(QDebug debug, const PacketType& type);
const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1; const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1;
const PacketVersion VERSION_ENTITIES_HAVE_ANIMATION = 1; const PacketVersion VERSION_ENTITIES_HAVE_ANIMATION = 1;
const PacketVersion VERSION_ROOT_ELEMENT_HAS_DATA = 2; const PacketVersion VERSION_ROOT_ELEMENT_HAS_DATA = 2;

View file

@ -17,7 +17,7 @@
using namespace udt; using namespace udt;
PacketList::PacketList(PacketType::Value packetType, QByteArray extendedHeader) : PacketList::PacketList(PacketType packetType, QByteArray extendedHeader) :
_packetType(packetType), _packetType(packetType),
_extendedHeader(extendedHeader) _extendedHeader(extendedHeader)
{ {
@ -34,7 +34,8 @@ void PacketList::endSegment() {
std::unique_ptr<Packet> PacketList::createPacket() { std::unique_ptr<Packet> PacketList::createPacket() {
// use the static create method to create a new packet // use the static create method to create a new packet
return Packet::create(getType()); // TODO: create a packet with correct reliability and messaging
return Packet::create();
} }
std::unique_ptr<Packet> PacketList::createPacketWithExtendedHeader() { std::unique_ptr<Packet> PacketList::createPacketWithExtendedHeader() {

View file

@ -27,14 +27,14 @@ class Packet;
class PacketList : public QIODevice { class PacketList : public QIODevice {
Q_OBJECT Q_OBJECT
public: public:
PacketList(PacketType::Value packetType, QByteArray extendedHeader = QByteArray()); PacketList(PacketType packetType, QByteArray extendedHeader = QByteArray());
virtual bool isSequential() const { return true; } virtual bool isSequential() const { return true; }
void startSegment(); void startSegment();
void endSegment(); void endSegment();
PacketType::Value getType() const { return _packetType; } PacketType getType() const { return _packetType; }
int getNumPackets() const { return _packets.size() + (_currentPacket ? 1 : 0); } int getNumPackets() const { return _packets.size() + (_currentPacket ? 1 : 0); }
void closeCurrentPacket(bool shouldSendEmpty = false); void closeCurrentPacket(bool shouldSendEmpty = false);
@ -58,7 +58,7 @@ private:
virtual std::unique_ptr<Packet> createPacket(); virtual std::unique_ptr<Packet> createPacket();
std::unique_ptr<Packet> createPacketWithExtendedHeader(); std::unique_ptr<Packet> createPacketWithExtendedHeader();
PacketType::Value _packetType; PacketType _packetType;
bool _isOrdered = false; bool _isOrdered = false;
std::unique_ptr<Packet> _currentPacket; std::unique_ptr<Packet> _currentPacket;

View file

@ -1894,7 +1894,7 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr
bool wantImportProgress = true; bool wantImportProgress = true;
PacketType::Value expectedType = expectedDataPacketType(); PacketType expectedType = expectedDataPacketType();
PacketVersion expectedVersion = versionForPacketType(expectedType); PacketVersion expectedVersion = versionForPacketType(expectedType);
bool hasBufferBreaks = versionHasSVOfileBreaks(expectedVersion); bool hasBufferBreaks = versionHasSVOfileBreaks(expectedVersion);
@ -1902,7 +1902,7 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr
if (getWantSVOfileVersions()) { if (getWantSVOfileVersions()) {
// read just enough of the file to parse the header... // read just enough of the file to parse the header...
const unsigned long HEADER_LENGTH = sizeof(PacketType::Value) + sizeof(PacketVersion); const unsigned long HEADER_LENGTH = sizeof(PacketType) + sizeof(PacketVersion);
unsigned char fileHeader[HEADER_LENGTH]; unsigned char fileHeader[HEADER_LENGTH];
inputStream.readRawData((char*)&fileHeader, HEADER_LENGTH); inputStream.readRawData((char*)&fileHeader, HEADER_LENGTH);
@ -1912,7 +1912,7 @@ bool Octree::readSVOFromStream(unsigned long streamLength, QDataStream& inputStr
unsigned long dataLength = HEADER_LENGTH; unsigned long dataLength = HEADER_LENGTH;
// if so, read the first byte of the file and see if it matches the expected version code // if so, read the first byte of the file and see if it matches the expected version code
PacketType::Value gotType; PacketType gotType;
memcpy(&gotType, dataAt, sizeof(gotType)); memcpy(&gotType, dataAt, sizeof(gotType));
dataAt += sizeof(expectedType); dataAt += sizeof(expectedType);
@ -2055,7 +2055,7 @@ void Octree::writeToJSONFile(const char* fileName, OctreeElement* element) {
} }
// include the "bitstream" version // include the "bitstream" version
PacketType::Value expectedType = expectedDataPacketType(); PacketType expectedType = expectedDataPacketType();
PacketVersion expectedVersion = versionForPacketType(expectedType); PacketVersion expectedVersion = versionForPacketType(expectedType);
entityDescription["Version"] = (int) expectedVersion; entityDescription["Version"] = (int) expectedVersion;
@ -2076,7 +2076,7 @@ void Octree::writeToSVOFile(const char* fileName, OctreeElement* element) {
if(file.is_open()) { if(file.is_open()) {
qCDebug(octree, "Saving binary SVO to file %s...", fileName); qCDebug(octree, "Saving binary SVO to file %s...", fileName);
PacketType::Value expectedType = expectedDataPacketType(); PacketType expectedType = expectedDataPacketType();
PacketVersion expectedVersion = versionForPacketType(expectedType); PacketVersion expectedVersion = versionForPacketType(expectedType);
bool hasBufferBreaks = versionHasSVOfileBreaks(expectedVersion); bool hasBufferBreaks = versionHasSVOfileBreaks(expectedVersion);

View file

@ -228,11 +228,11 @@ public:
// These methods will allow the OctreeServer to send your tree inbound edit packets of your // These methods will allow the OctreeServer to send your tree inbound edit packets of your
// own definition. Implement these to allow your octree based server to support editing // own definition. Implement these to allow your octree based server to support editing
virtual bool getWantSVOfileVersions() const { return false; } virtual bool getWantSVOfileVersions() const { return false; }
virtual PacketType::Value expectedDataPacketType() const { return PacketType::Unknown; } virtual PacketType expectedDataPacketType() const { return PacketType::Unknown; }
virtual bool canProcessVersion(PacketVersion thisVersion) const { virtual bool canProcessVersion(PacketVersion thisVersion) const {
return thisVersion == versionForPacketType(expectedDataPacketType()); } return thisVersion == versionForPacketType(expectedDataPacketType()); }
virtual PacketVersion expectedVersion() const { return versionForPacketType(expectedDataPacketType()); } virtual PacketVersion expectedVersion() const { return versionForPacketType(expectedDataPacketType()); }
virtual bool handlesEditPacketType(PacketType::Value packetType) const { return false; } virtual bool handlesEditPacketType(PacketType packetType) const { return false; }
virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength, virtual int processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength,
const SharedNodePointer& sourceNode) { return 0; } const SharedNodePointer& sourceNode) { return 0; }

View file

@ -194,7 +194,7 @@ void OctreeEditPacketSender::queuePacketToNodes(std::unique_ptr<NLPacket> packet
// NOTE: editMessage - is JUST the octcode/color and does not contain the packet header // NOTE: editMessage - is JUST the octcode/color and does not contain the packet header
void OctreeEditPacketSender::queueOctreeEditMessage(PacketType::Value type, QByteArray& editMessage) { void OctreeEditPacketSender::queueOctreeEditMessage(PacketType type, QByteArray& editMessage) {
if (!_shouldSend) { if (!_shouldSend) {
return; // bail early return; // bail early
@ -315,7 +315,7 @@ void OctreeEditPacketSender::releaseQueuedPacket(const QUuid& nodeID, std::uniqu
_releaseQueuedPacketMutex.unlock(); _releaseQueuedPacketMutex.unlock();
} }
std::unique_ptr<NLPacket> OctreeEditPacketSender::initializePacket(PacketType::Value type, int nodeClockSkew) { std::unique_ptr<NLPacket> OctreeEditPacketSender::initializePacket(PacketType type, int nodeClockSkew) {
auto newPacket = NLPacket::create(type); auto newPacket = NLPacket::create(type);
// skip over sequence number for now; will be packed when packet is ready to be sent out // skip over sequence number for now; will be packed when packet is ready to be sent out

View file

@ -36,7 +36,7 @@ public:
/// Queues a single edit message. Will potentially send a pending multi-command packet. Determines which server /// Queues a single edit message. Will potentially send a pending multi-command packet. Determines which server
/// node or nodes the packet should be sent to. Can be called even before servers are known, in which case up to /// node or nodes the packet should be sent to. Can be called even before servers are known, in which case up to
/// MaxPendingMessages will be buffered and processed when servers are known. /// MaxPendingMessages will be buffered and processed when servers are known.
void queueOctreeEditMessage(PacketType::Value type, QByteArray& editMessage); void queueOctreeEditMessage(PacketType type, QByteArray& editMessage);
/// Releases all queued messages even if those messages haven't filled an MTU packet. This will move the packed message /// Releases all queued messages even if those messages haven't filled an MTU packet. This will move the packed message
/// packets onto the send queue. If running in threaded mode, the caller does not need to do any further processing to /// packets onto the send queue. If running in threaded mode, the caller does not need to do any further processing to
@ -81,7 +81,7 @@ public:
// you must override these... // you must override these...
virtual char getMyNodeType() const = 0; virtual char getMyNodeType() const = 0;
virtual void adjustEditPacketForClockSkew(PacketType::Value type, QByteArray& buffer, int clockSkew) { } virtual void adjustEditPacketForClockSkew(PacketType type, QByteArray& buffer, int clockSkew) { }
void processNackPacket(NLPacket& packet, SharedNodePointer sendingNode); void processNackPacket(NLPacket& packet, SharedNodePointer sendingNode);
@ -89,13 +89,13 @@ public slots:
void nodeKilled(SharedNodePointer node); void nodeKilled(SharedNodePointer node);
protected: protected:
using EditMessagePair = std::pair<PacketType::Value, QByteArray>; using EditMessagePair = std::pair<PacketType, QByteArray>;
bool _shouldSend; bool _shouldSend;
void queuePacketToNode(const QUuid& nodeID, std::unique_ptr<NLPacket> packet); void queuePacketToNode(const QUuid& nodeID, std::unique_ptr<NLPacket> packet);
void queuePendingPacketToNodes(std::unique_ptr<NLPacket> packet); void queuePendingPacketToNodes(std::unique_ptr<NLPacket> packet);
void queuePacketToNodes(std::unique_ptr<NLPacket> packet); void queuePacketToNodes(std::unique_ptr<NLPacket> packet);
std::unique_ptr<NLPacket> initializePacket(PacketType::Value type, int nodeClockSkew); std::unique_ptr<NLPacket> initializePacket(PacketType type, int nodeClockSkew);
void releaseQueuedPacket(const QUuid& nodeUUID, std::unique_ptr<NLPacket> packetBuffer); // releases specific queued packet void releaseQueuedPacket(const QUuid& nodeUUID, std::unique_ptr<NLPacket> packetBuffer); // releases specific queued packet
void processPreServerExistsPackets(); void processPreServerExistsPackets();

View file

@ -33,7 +33,7 @@ void OctreeHeadlessViewer::init() {
void OctreeHeadlessViewer::queryOctree() { void OctreeHeadlessViewer::queryOctree() {
char serverType = getMyNodeType(); char serverType = getMyNodeType();
PacketType::Value packetType = getMyQueryMessageType(); PacketType packetType = getMyQueryMessageType();
NodeToJurisdictionMap& jurisdictions = *_jurisdictionListener->getJurisdictions(); NodeToJurisdictionMap& jurisdictions = *_jurisdictionListener->getJurisdictions();
bool wantExtraDebugging = false; bool wantExtraDebugging = false;

View file

@ -42,7 +42,7 @@ typedef quint64 OCTREE_PACKET_SENT_TIME;
typedef uint16_t OCTREE_PACKET_INTERNAL_SECTION_SIZE; typedef uint16_t OCTREE_PACKET_INTERNAL_SECTION_SIZE;
const int MAX_OCTREE_PACKET_SIZE = MAX_PACKET_SIZE; const int MAX_OCTREE_PACKET_SIZE = MAX_PACKET_SIZE;
// this is overly conservative - sizeof(PacketType) is 8 bytes but a packed PacketType::Value could be as small as one byte // this is overly conservative - sizeof(PacketType) is 8 bytes but a packed PacketType could be as small as one byte
const unsigned int OCTREE_PACKET_EXTRA_HEADERS_SIZE = sizeof(OCTREE_PACKET_FLAGS) const unsigned int OCTREE_PACKET_EXTRA_HEADERS_SIZE = sizeof(OCTREE_PACKET_FLAGS)
+ sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME); + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME);

View file

@ -36,8 +36,8 @@ public:
virtual ~OctreeRenderer(); virtual ~OctreeRenderer();
virtual char getMyNodeType() const = 0; virtual char getMyNodeType() const = 0;
virtual PacketType::Value getMyQueryMessageType() const = 0; virtual PacketType getMyQueryMessageType() const = 0;
virtual PacketType::Value getExpectedPacketType() const = 0; virtual PacketType getExpectedPacketType() const = 0;
virtual void renderElement(OctreeElement* element, RenderArgs* args) = 0; virtual void renderElement(OctreeElement* element, RenderArgs* args) = 0;
virtual float getSizeScale() const { return DEFAULT_OCTREE_SIZE_SCALE; } virtual float getSizeScale() const { return DEFAULT_OCTREE_SIZE_SCALE; }
virtual int getBoundaryLevelAdjust() const { return 0; } virtual int getBoundaryLevelAdjust() const { return 0; }