mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-16 09:00:31 +02:00
152 lines
4.8 KiB
C++
152 lines
4.8 KiB
C++
//
|
|
// Packet.cpp
|
|
// libraries/networking/src
|
|
//
|
|
// Created by Clement on 7/2/15.
|
|
// Copyright 2015 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include "Packet.h"
|
|
|
|
using namespace udt;
|
|
|
|
std::unique_ptr<Packet> Packet::create(qint64 size, bool isReliable, bool isPartOfMessage) {
|
|
auto packet = std::unique_ptr<Packet>(new Packet(size, isReliable, isPartOfMessage));
|
|
|
|
packet->open(QIODevice::ReadWrite);
|
|
|
|
return packet;
|
|
}
|
|
|
|
std::unique_ptr<Packet> Packet::fromReceivedPacket(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr) {
|
|
// Fail with invalid size
|
|
Q_ASSERT(size >= 0);
|
|
|
|
// allocate memory
|
|
auto packet = std::unique_ptr<Packet>(new Packet(std::move(data), size, senderSockAddr));
|
|
|
|
packet->open(QIODevice::ReadOnly);
|
|
|
|
return packet;
|
|
}
|
|
|
|
std::unique_ptr<Packet> Packet::createCopy(const 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 {
|
|
return localHeaderSize();
|
|
}
|
|
|
|
qint64 Packet::localHeaderSize() const {
|
|
return localHeaderSize(_isPartOfMessage);
|
|
}
|
|
|
|
Packet::Packet(qint64 size, bool isReliable, bool isPartOfMessage) :
|
|
BasePacket(size),
|
|
_isReliable(isReliable),
|
|
_isPartOfMessage(isPartOfMessage)
|
|
{
|
|
_payloadCapacity = size;
|
|
_payloadStart = _packet.get() + (_packetSize - _payloadCapacity);
|
|
|
|
// set the UDT header to default values
|
|
writeSequenceNumber(0);
|
|
}
|
|
|
|
Packet::Packet(std::unique_ptr<char> data, qint64 size, const HifiSockAddr& senderSockAddr) :
|
|
BasePacket(std::move(data), size, senderSockAddr)
|
|
{
|
|
readIsReliable();
|
|
readIsPartOfMessage();
|
|
readSequenceNumber();
|
|
|
|
_payloadCapacity = _packetSize - localHeaderSize();
|
|
_payloadSize = _payloadCapacity;
|
|
_payloadStart = _packet.get() + (_packetSize - _payloadCapacity);
|
|
}
|
|
|
|
Packet::Packet(const Packet& other) :
|
|
BasePacket(other)
|
|
{
|
|
_isReliable = other._isReliable;
|
|
_isPartOfMessage = other._isPartOfMessage;
|
|
_sequenceNumber = other._sequenceNumber;
|
|
}
|
|
|
|
Packet& Packet::operator=(const Packet& other) {
|
|
BasePacket::operator=(other);
|
|
|
|
_isReliable = other._isReliable;
|
|
_isPartOfMessage = other._isPartOfMessage;
|
|
_sequenceNumber = other._sequenceNumber;
|
|
|
|
return *this;
|
|
}
|
|
|
|
Packet::Packet(Packet&& other) :
|
|
BasePacket(other)
|
|
{
|
|
_isReliable = other._isReliable;
|
|
_isPartOfMessage = other._isPartOfMessage;
|
|
_sequenceNumber = other._sequenceNumber;
|
|
}
|
|
|
|
Packet& Packet::operator=(Packet&& other) {
|
|
BasePacket::operator=(std::move(other));
|
|
|
|
_isReliable = other._isReliable;
|
|
_isPartOfMessage = other._isPartOfMessage;
|
|
_sequenceNumber = other._sequenceNumber;
|
|
|
|
return *this;
|
|
}
|
|
|
|
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 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;
|
|
|
|
void Packet::readIsReliable() {
|
|
SequenceNumberAndBitField seqNumBitField = *reinterpret_cast<SequenceNumberAndBitField*>(_packet.get());
|
|
_isReliable = (bool) (seqNumBitField & RELIABILITY_BIT_MASK); // Only keep reliability bit
|
|
}
|
|
|
|
void Packet::readIsPartOfMessage() {
|
|
SequenceNumberAndBitField seqNumBitField = *reinterpret_cast<SequenceNumberAndBitField*>(_packet.get());
|
|
_isReliable = (bool) (seqNumBitField & MESSAGE_BIT_MASK); // Only keep message bit
|
|
}
|
|
|
|
void Packet::readSequenceNumber() {
|
|
SequenceNumberAndBitField seqNumBitField = *reinterpret_cast<SequenceNumberAndBitField*>(_packet.get());
|
|
_sequenceNumber = (seqNumBitField & ~BIT_FIELD_MASK); // Remove the bit field
|
|
}
|
|
|
|
static const uint32_t MAX_SEQUENCE_NUMBER = UINT32_MAX >> BIT_FIELD_LENGTH;
|
|
|
|
void Packet::writeSequenceNumber(SequenceNumber sequenceNumber) {
|
|
// make sure this is a sequence number <= 29 bit unsigned max (536,870,911)
|
|
Q_ASSERT(sequenceNumber <= MAX_SEQUENCE_NUMBER);
|
|
|
|
// 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;
|
|
}
|