overte/libraries/shared/src/Assignment.cpp
2013-09-12 16:18:53 -07:00

144 lines
No EOL
4.5 KiB
C++

//
// Assignment.cpp
// hifi
//
// Created by Stephen Birarda on 8/22/13.
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
//
#include "PacketHeaders.h"
#include "SharedUtil.h"
#include "Assignment.h"
const char IPv4_ADDRESS_DESIGNATOR = 4;
const char IPv6_ADDRESS_DESIGNATOR = 6;
const int NUM_BYTES_RFC4122_UUID = 16;
Assignment::Assignment(Assignment::Command command, Assignment::Type type, Assignment::Location location) :
_command(command),
_type(type),
_location(location),
_attachedPublicSocket(NULL),
_attachedLocalSocket(NULL)
{
// set the create time on this assignment
gettimeofday(&_time, NULL);
if (_command == Assignment::CreateCommand) {
// this is a newly created assignment, generate a random UUID
_uuid = QUuid::createUuid();
}
}
Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
_location(GlobalLocation),
_attachedPublicSocket(NULL),
_attachedLocalSocket(NULL)
{
// set the create time on this assignment
gettimeofday(&_time, NULL);
int numBytesRead = 0;
if (dataBuffer[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
_command = Assignment::RequestCommand;
} else if (dataBuffer[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
_command = Assignment::CreateCommand;
} else if (dataBuffer[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT) {
_command = Assignment::DeployCommand;
}
numBytesRead += numBytesForPacketHeader(dataBuffer);
if (dataBuffer[0] != PACKET_TYPE_REQUEST_ASSIGNMENT) {
// read the GUID for this assignment
_uuid = QUuid::fromRfc4122(QByteArray((const char*) dataBuffer + numBytesRead, NUM_BYTES_RFC4122_UUID));
numBytesRead += NUM_BYTES_RFC4122_UUID;
}
memcpy(&_type, dataBuffer + numBytesRead, sizeof(Assignment::Type));
numBytesRead += sizeof(Assignment::Type);
if (numBytes > numBytesRead) {
sockaddr* newSocket = NULL;
if (dataBuffer[numBytesRead++] == IPv4_ADDRESS_DESIGNATOR) {
// IPv4 address
newSocket = (sockaddr*) new sockaddr_in;
unpackSocket(dataBuffer + numBytesRead, newSocket);
} else {
// IPv6 address, or bad designator
qDebug("Received a socket that cannot be unpacked!\n");
}
if (_command == Assignment::CreateCommand) {
delete _attachedLocalSocket;
_attachedLocalSocket = newSocket;
} else {
delete _attachedPublicSocket;
_attachedPublicSocket = newSocket;
}
}
}
Assignment::~Assignment() {
delete _attachedPublicSocket;
delete _attachedLocalSocket;
}
void Assignment::setAttachedPublicSocket(const sockaddr* attachedPublicSocket) {
if (_attachedPublicSocket) {
// delete the old socket if it exists
delete _attachedPublicSocket;
_attachedPublicSocket = NULL;
}
if (attachedPublicSocket) {
copySocketToEmptySocketPointer(&_attachedPublicSocket, attachedPublicSocket);
}
}
void Assignment::setAttachedLocalSocket(const sockaddr* attachedLocalSocket) {
if (_attachedLocalSocket) {
// delete the old socket if it exists
delete _attachedLocalSocket;
_attachedLocalSocket = NULL;
}
if (attachedLocalSocket) {
copySocketToEmptySocketPointer(&_attachedLocalSocket, attachedLocalSocket);
}
}
int Assignment::packToBuffer(unsigned char* buffer) {
int numPackedBytes = 0;
// pack the UUID for this assignment, if this is an assignment create or deploy
if (_command != Assignment::RequestCommand) {
memcpy(buffer, _uuid.toRfc4122().constData(), NUM_BYTES_RFC4122_UUID);
numPackedBytes += NUM_BYTES_RFC4122_UUID;
}
memcpy(buffer + numPackedBytes, &_type, sizeof(_type));
numPackedBytes += sizeof(_type);
if (_attachedPublicSocket || _attachedLocalSocket) {
sockaddr* socketToPack = (_attachedPublicSocket) ? _attachedPublicSocket : _attachedLocalSocket;
// we have a socket to pack, add the designator
buffer[numPackedBytes++] = (socketToPack->sa_family == AF_INET)
? IPv4_ADDRESS_DESIGNATOR : IPv6_ADDRESS_DESIGNATOR;
numPackedBytes += packSocket(buffer + numPackedBytes, socketToPack);
}
return numPackedBytes;
}
QDebug operator<<(QDebug debug, const Assignment &assignment) {
debug << "T:" << assignment.getType();
return debug.nospace();
}