mirror of
https://github.com/overte-org/overte.git
synced 2025-04-14 00:47:33 +02:00
Merge remote-tracking branch 'clement/protocol' into atp
This commit is contained in:
commit
f5dad95184
9 changed files with 334 additions and 125 deletions
|
@ -118,7 +118,7 @@ static const float DDE_COEFFICIENT_SCALES[] = {
|
|||
1.0f // CheekSquint_R
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
struct DDEPacket {
|
||||
//roughly in mm
|
||||
float focal_length[1];
|
||||
float translation[3];
|
||||
|
@ -347,7 +347,7 @@ void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
|
|||
|
||||
bool isFiltering = Menu::getInstance()->isOptionChecked(MenuOption::VelocityFilter);
|
||||
|
||||
Packet packet;
|
||||
DDEPacket packet;
|
||||
int bytesToCopy = glm::min((int)sizeof(packet), buffer.size());
|
||||
memset(&packet.name, '\n', MAX_NAME_SIZE + 1);
|
||||
memcpy(&packet, buffer.data(), bytesToCopy);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "DomainHandler.h"
|
||||
#include "Node.h"
|
||||
#include "NLPacket.h"
|
||||
#include "PacketHeaders.h"
|
||||
#include "UUIDHasher.h"
|
||||
|
||||
|
|
54
libraries/networking/src/NLPacket.cpp
Normal file
54
libraries/networking/src/NLPacket.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// NLPacket.cpp
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Clement on 7/6/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 "NLPacket.h"
|
||||
|
||||
int64_t NLPacket::localHeaderSize(PacketType::Value type) {
|
||||
int64_t size = ((NON_SOURCED_PACKETS.contains(type)) ? 0 : NUM_BYTES_RFC4122_UUID) +
|
||||
((NON_VERIFIED_PACKETS.contains(type)) ? 0 : NUM_BYTES_RFC4122_UUID);
|
||||
return size;
|
||||
}
|
||||
|
||||
int64_t NLPacket::maxPayloadSize(PacketType::Value type) {
|
||||
return Packet::maxPayloadSize(type) - localHeaderSize(type);
|
||||
}
|
||||
|
||||
qint64 Packet::totalHeadersSize() const {
|
||||
return localHeaderSize() + Packet::localHeaderSize();
|
||||
}
|
||||
|
||||
qint64 Packet::localHeaderSize() const {
|
||||
return localHeaderSize(_type);
|
||||
}
|
||||
|
||||
std::unique_ptr<NLPacket> NLPacket::create(PacketType::Value type, int64_t size) {
|
||||
if (size > maxPayloadSize(type)) {
|
||||
return std::unique_ptr<NLPacket>();
|
||||
}
|
||||
|
||||
return std::unique_ptr<NLPacket>(new NLPacket(type, size));
|
||||
}
|
||||
|
||||
NLPacket::NLPacket(PacketType::Value type, int64_t size) : Packet(type, localHeaderSize(type) + size) {
|
||||
}
|
||||
|
||||
void NLPacket::setSourceUuid(QUuid sourceUuid) {
|
||||
Q_ASSERT(!NON_SOURCED_PACKETS.contains(_type));
|
||||
auto offset = Packet::totalHeadersSize();
|
||||
memcpy(_packet.get() + offset, sourceUuid.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID);
|
||||
}
|
||||
|
||||
void NLPacket::setConnectionUuid(QUuid connectionUuid) {
|
||||
Q_ASSERT(!NON_VERIFIED_PACKETS.contains(_type));
|
||||
auto offset = Packet::totalHeadersSize() +
|
||||
((NON_SOURCED_PACKETS.contains(_type)) ? 0 : NUM_BYTES_RFC4122_UUID);
|
||||
memcpy(_packet.get() + offset, connectionUuid.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID);
|
||||
}
|
34
libraries/networking/src/NLPacket.h
Normal file
34
libraries/networking/src/NLPacket.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// NLPacket.h
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Clement on 7/6/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
|
||||
//
|
||||
|
||||
#ifndef hifi_NLPacket_h
|
||||
#define hifi_NLPacket_h
|
||||
|
||||
#include "Packet.h"
|
||||
|
||||
class NLPacket : public Packet {
|
||||
public:
|
||||
static std::unique_ptr<NLPacket> create(PacketType::Value type, int64_t size = -1);
|
||||
|
||||
static int64_t localHeaderSize(PacketType::Value type);
|
||||
static int64_t maxPayloadSize(PacketType::Value type);
|
||||
|
||||
virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers
|
||||
virtual qint64 localHeaderSize() const; // Current level's header size
|
||||
|
||||
protected:
|
||||
NLPacket(PacketType::Value type, int64_t size);
|
||||
|
||||
void setSourceUuid(QUuid sourceUuid);
|
||||
void setConnectionUuid(QUuid connectionUuid);
|
||||
};
|
||||
|
||||
#endif // hifi_NLPacket_h
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Packet.cpp
|
||||
//
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Clement on 7/2/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
|
@ -11,12 +11,183 @@
|
|||
|
||||
#include "Packet.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include "LimitedNodeList.h"
|
||||
|
||||
std::unique_ptr<Packet> Packet::makePacket() {
|
||||
return std::unique_ptr<Packet>(new Packet());
|
||||
qint64 Packet::localHeaderSize(PacketType::Value type) {
|
||||
qint64 size = numBytesForArithmeticCodedPacketType(type) + sizeof(PacketVersion) +
|
||||
((SEQUENCE_NUMBERED_PACKETS.contains(type)) ? sizeof(SequenceNumber) : 0);
|
||||
return size;
|
||||
}
|
||||
|
||||
QByteArray Packet::payload() {
|
||||
return QByteArray();
|
||||
}
|
||||
qint64 Packet::maxPayloadSize(PacketType::Value type) {
|
||||
return MAX_PACKET_SIZE - localHeaderSize(type);
|
||||
}
|
||||
|
||||
std::unique_ptr<Packet> Packet::create(PacketType::Value type, qint64 size) {
|
||||
auto maxPayload = maxPayloadSize(type);
|
||||
if (size == -1) {
|
||||
// default size of -1, means biggest packet possible
|
||||
size = maxPayload;
|
||||
}
|
||||
if (size <= 0 || size > maxPayload) {
|
||||
// Invalid size, return null pointer
|
||||
return std::unique_ptr<Packet>();
|
||||
}
|
||||
|
||||
// allocate memory
|
||||
return std::unique_ptr<Packet>(new Packet(type, size));
|
||||
}
|
||||
|
||||
qint64 Packet::totalHeadersSize() const {
|
||||
return localHeaderSize();
|
||||
}
|
||||
|
||||
qint64 Packet::localHeaderSize() const {
|
||||
return localHeaderSize(_type);
|
||||
}
|
||||
|
||||
Packet::Packet(PacketType::Value type, qint64 size) :
|
||||
_type(type),
|
||||
_packetSize(localHeaderSize(_type) + size),
|
||||
_packet(new char(_packetSize)),
|
||||
_payloadStart(_packet.get() + localHeaderSize(_type)),
|
||||
_capacity(size) {
|
||||
// Sanity check
|
||||
Q_ASSERT(size <= maxPayloadSize(type));
|
||||
|
||||
// copy packet type and version in header
|
||||
setPacketTypeAndVersion(type);
|
||||
|
||||
// Set control bit and sequence number to 0 if necessary
|
||||
if (SEQUENCE_NUMBERED_PACKETS.contains(type)) {
|
||||
setSequenceNumber(0);
|
||||
}
|
||||
}
|
||||
|
||||
Packet::Packet(const Packet& other) {
|
||||
*this = other;
|
||||
}
|
||||
|
||||
Packet& Packet::operator=(const Packet& other) {
|
||||
_packetSize = other._packetSize;
|
||||
_packet = std::unique_ptr<char>(new char(_packetSize));
|
||||
memcpy(_packet.get(), other._packet.get(), _packetSize);
|
||||
|
||||
_payloadStart = _packet.get() + (other._payloadStart - other._packet.get());
|
||||
_position = other._position;
|
||||
_capacity = other._capacity;
|
||||
|
||||
_sizeUsed = other._sizeUsed;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Packet::Packet(Packet&& other) {
|
||||
*this = std::move(other);
|
||||
}
|
||||
|
||||
Packet& Packet::operator=(Packet&& other) {
|
||||
_packetSize = other._packetSize;
|
||||
_packet = std::move(other._packet);
|
||||
|
||||
_payloadStart = other._payloadStart;
|
||||
_position = other._position;
|
||||
_capacity = other._capacity;
|
||||
|
||||
_sizeUsed = other._sizeUsed;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PacketType::Value Packet::getPacketType() const {
|
||||
return (PacketType::Value)arithmeticCodingValueFromBuffer(_packet.get());
|
||||
}
|
||||
|
||||
PacketVersion Packet::getPacketTypeVersion() const {
|
||||
return *reinterpret_cast<PacketVersion*>(_packet.get() + numBytesForArithmeticCodedPacketType(_type));
|
||||
}
|
||||
|
||||
Packet::SequenceNumber Packet::getSequenceNumber() const {
|
||||
if (SEQUENCE_NUMBERED_PACKETS.contains(_type)) {
|
||||
SequenceNumber seqNum = *reinterpret_cast<SequenceNumber*>(_packet.get() +
|
||||
numBytesForArithmeticCodedPacketType(_type) +
|
||||
sizeof(PacketVersion));
|
||||
return seqNum & ~(1 << 15); // remove control bit
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool Packet::isControlPacket() const {
|
||||
if (SEQUENCE_NUMBERED_PACKETS.contains(_type)) {
|
||||
SequenceNumber seqNum = *reinterpret_cast<SequenceNumber*>(_packet.get() +
|
||||
numBytesForArithmeticCodedPacketType(_type) +
|
||||
sizeof(PacketVersion));
|
||||
return seqNum & (1 << 15); // Only keep control bit
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Packet::setPacketTypeAndVersion(PacketType::Value type) {
|
||||
// Pack the packet type
|
||||
auto offset = packArithmeticallyCodedValue(type, _packet.get());
|
||||
|
||||
// Pack the packet version
|
||||
auto version { versionForPacketType(type) };
|
||||
memcpy(_packet.get() + offset, &version, sizeof(version));
|
||||
}
|
||||
|
||||
void Packet::setSequenceNumber(SequenceNumber seqNum) {
|
||||
// Here we are overriding the control bit to 0.
|
||||
// But that is not an issue since we should only ever set the seqNum
|
||||
// for data packets going out
|
||||
memcpy(_packet.get() + numBytesForArithmeticCodedPacketType(_type) + sizeof(PacketVersion),
|
||||
&seqNum, sizeof(seqNum));
|
||||
}
|
||||
|
||||
bool Packet::seek(qint64 pos) {
|
||||
bool valid = (pos >= 0) && (pos < size());
|
||||
if (valid) {
|
||||
_position = pos;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
static const qint64 PACKET_WRITE_ERROR = -1;
|
||||
qint64 Packet::writeData(const char* data, qint64 maxSize) {
|
||||
// make sure we have the space required to write this block
|
||||
if (maxSize <= bytesAvailable()) {
|
||||
qint64 currentPos = pos();
|
||||
|
||||
// good to go - write the data
|
||||
memcpy(_payloadStart + currentPos, data, maxSize);
|
||||
|
||||
// seek to the new position based on where our write just finished
|
||||
seek(currentPos + maxSize);
|
||||
|
||||
// keep track of _sizeUsed so we can just write the actual data when packet is about to be sent
|
||||
_sizeUsed = std::max(pos() + 1, _sizeUsed);
|
||||
|
||||
// return the number of bytes written
|
||||
return maxSize;
|
||||
} else {
|
||||
// not enough space left for this write - return an error
|
||||
return PACKET_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
qint64 Packet::readData(char* dest, qint64 maxSize) {
|
||||
// we're either reading what is left from the current position or what was asked to be read
|
||||
qint64 numBytesToRead = std::min(bytesAvailable(), maxSize);
|
||||
|
||||
if (numBytesToRead > 0) {
|
||||
int currentPosition = pos();
|
||||
|
||||
// read out the data
|
||||
memcpy(dest, _payloadStart + currentPosition, numBytesToRead);
|
||||
|
||||
// seek to the end of the read
|
||||
seek(currentPosition + numBytesToRead);
|
||||
}
|
||||
|
||||
return numBytesToRead;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// Packet.h
|
||||
//
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Clement on 7/2/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
|
@ -14,18 +14,72 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
class QByteArray;
|
||||
#include <QIODevice>
|
||||
|
||||
class Packet {
|
||||
std::unique_ptr<Packet> makePacket();
|
||||
QByteArray payload();
|
||||
#include "PacketHeaders.h"
|
||||
|
||||
class Packet : public QIODevice {
|
||||
public:
|
||||
using SequenceNumber = uint16_t;
|
||||
|
||||
static std::unique_ptr<Packet> create(PacketType::Value type, int64_t size = -1);
|
||||
|
||||
static qint64 localHeaderSize(PacketType::Value type);
|
||||
static qint64 maxPayloadSize(PacketType::Value type);
|
||||
|
||||
virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers
|
||||
virtual qint64 localHeaderSize() const; // Current level's header size
|
||||
|
||||
// Payload direct access, use responsibly!
|
||||
char* getPayload() { return _payloadStart; }
|
||||
const char* getPayload() const { return _payloadStart; }
|
||||
|
||||
qint64 getSizeWithHeader() const { return localHeaderSize() + getSizeUsed(); }
|
||||
qint64 getSizeUsed() const { return _sizeUsed; }
|
||||
void setSizeUsed(qint64 sizeUsed) { _sizeUsed = sizeUsed; }
|
||||
|
||||
// Header readers
|
||||
PacketType::Value getPacketType() const;
|
||||
PacketVersion getPacketTypeVersion() const;
|
||||
SequenceNumber getSequenceNumber() const;
|
||||
bool isControlPacket() const;
|
||||
|
||||
// QIODevice virtual functions
|
||||
// WARNING: Those methods all refer to the payload ONLY and NOT the entire packet
|
||||
virtual bool atEnd() const { return _position == _capacity; }
|
||||
virtual qint64 bytesAvailable() const { return size() - pos(); }
|
||||
virtual bool canReadLine() const { return false; }
|
||||
virtual bool isSequential() const { return false; }
|
||||
virtual qint64 pos() const { return _position; }
|
||||
virtual bool reset() { return seek(0); }
|
||||
virtual bool seek(qint64 pos);
|
||||
virtual qint64 size() const { return _capacity; }
|
||||
|
||||
protected:
|
||||
Packet();
|
||||
Packet(const Packet&) = delete;
|
||||
Packet(Packet&&) = delete;
|
||||
Packet& operator=(const Packet&) = delete;
|
||||
Packet& operator=(Packet&&) = delete;
|
||||
Packet(PacketType::Value type, int64_t size);
|
||||
Packet(const Packet& other);
|
||||
Packet& operator=(const Packet& other);
|
||||
Packet(Packet&& other);
|
||||
Packet& operator=(Packet&& other);
|
||||
|
||||
// QIODevice virtual functions
|
||||
virtual qint64 writeData(const char* data, qint64 maxSize);
|
||||
virtual qint64 readData(char* data, qint64 maxSize);
|
||||
|
||||
// Header writers
|
||||
void setPacketTypeAndVersion(PacketType::Value type);
|
||||
void setSequenceNumber(SequenceNumber seqNum);
|
||||
|
||||
PacketType::Value _type;
|
||||
|
||||
qint64 _packetSize = 0; // Total size of the allocated memory
|
||||
std::unique_ptr<char> _packet; // Allocated memory
|
||||
|
||||
char* _payloadStart = nullptr; // Start of the payload
|
||||
qint64 _position = 0; // Current position in the payload
|
||||
qint64 _capacity = 0; // Total capacity of the payload
|
||||
|
||||
qint64 _sizeUsed = 0; // How much of the payload is actually used
|
||||
};
|
||||
|
||||
#endif // hifi_Packet_h
|
|
@ -118,6 +118,7 @@ int numBytesForPacketHeader(const QByteArray& packet);
|
|||
int numBytesForPacketHeader(const char* packet);
|
||||
int numBytesForArithmeticCodedPacketType(PacketType::Value packetType);
|
||||
int numBytesForPacketHeaderGivenPacketType(PacketType::Value packetType);
|
||||
int packArithmeticallyCodedValue(int value, char* destination);
|
||||
|
||||
QUuid uuidFromPacketHeader(const QByteArray& packet);
|
||||
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
//
|
||||
// PacketPayload.cpp
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Stephen Birarda on 07/06/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 "PacketPayload.h"
|
||||
|
||||
PacketPayload::PacketPayload(char* data, qint64 capacity) :
|
||||
_data(data)
|
||||
_capacity(capacity)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const int PACKET_READ_ERROR = -1;
|
||||
|
||||
qint64 PacketPayload::writeData(const char* data, qint64 maxSize) {
|
||||
|
||||
qint64 currentPos = pos();
|
||||
|
||||
// make sure we have the space required to write this block
|
||||
qint64 bytesAvailable = _capacity - currentPos;
|
||||
|
||||
if (bytesAvailable < srcBytes) {
|
||||
// good to go - write the data
|
||||
memcpy(_data + currentPos, src, srcBytes);
|
||||
|
||||
// seek to the new position based on where our write just finished
|
||||
seek(currentPos + srcBytes);
|
||||
|
||||
// keep track of _maxWritten so we can just write the actual data when packet is about to be sent
|
||||
_size = std::max(pos() + 1, _maxWritten);
|
||||
|
||||
// return the number of bytes written
|
||||
return srcBytes;
|
||||
} else {
|
||||
// not enough space left for this write - return an error
|
||||
return PACKET_WRITE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
const qint64 PACKET_READ_ERROR = -1;
|
||||
|
||||
qint64 PacketPayload::readData(char* dest, qint64 maxSize) {
|
||||
|
||||
int currentPosition = pos();
|
||||
|
||||
// we're either reading what is left from the current position or what was asked to be read
|
||||
qint64 numBytesToRead = std::min(_maxSize - currentPosition, maxSize);
|
||||
|
||||
if (numBytesToRead > 0) {
|
||||
// read out the data
|
||||
memcpy(dest, _data + currentPosition, numBytesToRead);
|
||||
|
||||
// seek to the end of the read
|
||||
seek(_data + currentPosition + numBytesToRead);
|
||||
}
|
||||
|
||||
return numBytesToRead;
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// PacketPayload.h
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Stephen Birarda on 07/06/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
|
||||
//
|
||||
|
||||
#ifndef hifi_PacketPayload_h
|
||||
#define hifi_PacketPayload_h
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QIODevice>
|
||||
|
||||
class PacketPayload : public QIODevice {
|
||||
public:
|
||||
PacketPayload(char* data, qint64 capacity);
|
||||
|
||||
qint64 getSizeUsed() const { return _sizeUsed; }
|
||||
void setSizeUsed(qint64 sizeUsed) { _sizeUsed = sizeUsed; }
|
||||
|
||||
virtual qint64 size() const { return _capacity; }
|
||||
virtual bool isSequential() const { return false; }
|
||||
|
||||
const char* constData() const { return _data; }
|
||||
protected:
|
||||
qint64 writeData(const char* data, qint64 maxSize);
|
||||
qint64 readData(char* data, qint64 maxSize);
|
||||
|
||||
private:
|
||||
char* _data;
|
||||
qint64 _sizeUsed = 0;
|
||||
qint64 _capacity = 0;
|
||||
};
|
||||
|
||||
#endif // hifi_PacketPayload_h
|
Loading…
Reference in a new issue