mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 08:45:16 +02:00
125 lines
4.4 KiB
C++
125 lines
4.4 KiB
C++
//
|
|
// PacketHeaders.cpp
|
|
// hifi
|
|
//
|
|
// Created by Stephen Birarda on 6/28/13.
|
|
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
|
//
|
|
|
|
#include <math.h>
|
|
|
|
#include <QtCore/QDebug>
|
|
|
|
#include "NodeList.h"
|
|
|
|
#include "PacketHeaders.h"
|
|
|
|
int arithmeticCodingValueFromBuffer(const char* checkValue) {
|
|
if (((uchar) *checkValue) < 255) {
|
|
return *checkValue;
|
|
} else {
|
|
return 255 + arithmeticCodingValueFromBuffer(checkValue + 1);
|
|
}
|
|
}
|
|
|
|
int numBytesArithmeticCodingFromBuffer(const char* checkValue) {
|
|
if (((uchar) *checkValue) < 255) {
|
|
return 1;
|
|
} else {
|
|
return 1 + numBytesArithmeticCodingFromBuffer(checkValue + 1);
|
|
}
|
|
}
|
|
|
|
int packArithmeticallyCodedValue(int value, char* destination) {
|
|
if (value < 255) {
|
|
// less than 255, just pack our value
|
|
destination[0] = (uchar) value;
|
|
return 1;
|
|
} else {
|
|
// pack 255 and then recursively pack on
|
|
destination[0] = 255;
|
|
return 1 + packArithmeticallyCodedValue(value - 255, destination + 1);
|
|
}
|
|
}
|
|
|
|
PacketVersion versionForPacketType(PacketType type) {
|
|
switch (type) {
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
QByteArray byteArrayWithPopluatedHeader(PacketType type, const QUuid& connectionUUID) {
|
|
QByteArray freshByteArray(MAX_PACKET_HEADER_BYTES, 0);
|
|
freshByteArray.resize(populatePacketHeader(freshByteArray, type, connectionUUID));
|
|
return freshByteArray;
|
|
}
|
|
|
|
int populatePacketHeader(QByteArray& packet, PacketType type, const QUuid& connectionUUID) {
|
|
if (packet.size() < numBytesForPacketHeaderGivenPacketType(type)) {
|
|
packet.resize(numBytesForPacketHeaderGivenPacketType(type));
|
|
}
|
|
|
|
return populatePacketHeader(packet.data(), type, connectionUUID);
|
|
}
|
|
|
|
int populatePacketHeader(char* packet, PacketType type, const QUuid& connectionUUID) {
|
|
int numTypeBytes = packArithmeticallyCodedValue(type, packet);
|
|
packet[numTypeBytes] = versionForPacketType(type);
|
|
|
|
QUuid packUUID = connectionUUID.isNull() ? NodeList::getInstance()->getOwnerUUID() : connectionUUID;
|
|
|
|
QByteArray rfcUUID = packUUID.toRfc4122();
|
|
memcpy(packet + numTypeBytes + sizeof(PacketVersion), rfcUUID.constData(), NUM_BYTES_RFC4122_UUID);
|
|
|
|
// return the number of bytes written for pointer pushing
|
|
return numTypeBytes + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID;
|
|
}
|
|
|
|
bool packetVersionMatch(const QByteArray& packet) {
|
|
// currently this just checks if the version in the packet matches our return from versionForPacketType
|
|
// may need to be expanded in the future for types and versions that take > than 1 byte
|
|
|
|
if (packet[1] == versionForPacketType(packetTypeForPacket(packet)) || packetTypeForPacket(packet) == PacketTypeStunResponse) {
|
|
return true;
|
|
} else {
|
|
PacketType mismatchType = packetTypeForPacket(packet);
|
|
int numPacketTypeBytes = arithmeticCodingValueFromBuffer(packet.data());
|
|
|
|
QUuid nodeUUID;
|
|
deconstructPacketHeader(packet, nodeUUID);
|
|
|
|
qDebug() << "Packet mismatch on" << packetTypeForPacket(packet) << "- Sender"
|
|
<< nodeUUID << "sent" << qPrintable(QString::number(packet[numPacketTypeBytes])) << "but"
|
|
<< qPrintable(QString::number(versionForPacketType(mismatchType))) << "expected.";
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int numBytesForPacketHeader(const QByteArray& packet) {
|
|
// returns the number of bytes used for the type, version, and UUID
|
|
return numBytesArithmeticCodingFromBuffer(packet.data()) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID;
|
|
}
|
|
|
|
int numBytesForPacketHeader(const char* packet) {
|
|
// returns the number of bytes used for the type, version, and UUID
|
|
return numBytesArithmeticCodingFromBuffer(packet) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID;
|
|
}
|
|
|
|
int numBytesForPacketHeaderGivenPacketType(PacketType type) {
|
|
return (int) ceilf((float)type / 255) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID;
|
|
}
|
|
|
|
void deconstructPacketHeader(const QByteArray& packet, QUuid& senderUUID) {
|
|
senderUUID = QUuid::fromRfc4122(packet.mid(numBytesArithmeticCodingFromBuffer(packet.data()) + sizeof(PacketVersion),
|
|
NUM_BYTES_RFC4122_UUID));
|
|
}
|
|
|
|
PacketType packetTypeForPacket(const QByteArray& packet) {
|
|
return (PacketType) arithmeticCodingValueFromBuffer(packet.data());
|
|
}
|
|
|
|
PacketType packetTypeForPacket(const char* packet) {
|
|
return (PacketType) arithmeticCodingValueFromBuffer(packet);
|
|
}
|