mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 09:43:25 +02:00
fix networking compile for android setsockopt
This commit is contained in:
parent
3f1545008d
commit
7d7cba4dd2
1 changed files with 53 additions and 49 deletions
|
@ -11,6 +11,10 @@
|
|||
|
||||
#include "Socket.h"
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#include <QtCore/QThread>
|
||||
|
||||
#include <LogHandler.h>
|
||||
|
@ -30,10 +34,10 @@ Socket::Socket(QObject* parent) :
|
|||
_synTimer(new QTimer(this))
|
||||
{
|
||||
connect(&_udpSocket, &QUdpSocket::readyRead, this, &Socket::readPendingDatagrams);
|
||||
|
||||
|
||||
// make sure our synchronization method is called every SYN interval
|
||||
connect(_synTimer, &QTimer::timeout, this, &Socket::rateControlSync);
|
||||
|
||||
|
||||
// start our timer for the synchronization time interval
|
||||
_synTimer->start(_synInterval);
|
||||
|
||||
|
@ -60,7 +64,7 @@ void Socket::bind(const QHostAddress& address, quint16 port) {
|
|||
|
||||
void Socket::rebind() {
|
||||
quint16 oldPort = _udpSocket.localPort();
|
||||
|
||||
|
||||
_udpSocket.close();
|
||||
bind(QHostAddress::AnyIPv4, oldPort);
|
||||
}
|
||||
|
@ -69,26 +73,26 @@ void Socket::setSystemBufferSizes() {
|
|||
for (int i = 0; i < 2; i++) {
|
||||
QAbstractSocket::SocketOption bufferOpt;
|
||||
QString bufferTypeString;
|
||||
|
||||
|
||||
int numBytes = 0;
|
||||
|
||||
|
||||
if (i == 0) {
|
||||
bufferOpt = QAbstractSocket::SendBufferSizeSocketOption;
|
||||
numBytes = udt::UDP_SEND_BUFFER_SIZE_BYTES;
|
||||
bufferTypeString = "send";
|
||||
|
||||
|
||||
} else {
|
||||
bufferOpt = QAbstractSocket::ReceiveBufferSizeSocketOption;
|
||||
numBytes = udt::UDP_RECEIVE_BUFFER_SIZE_BYTES;
|
||||
bufferTypeString = "receive";
|
||||
}
|
||||
|
||||
|
||||
int oldBufferSize = _udpSocket.socketOption(bufferOpt).toInt();
|
||||
|
||||
|
||||
if (oldBufferSize < numBytes) {
|
||||
_udpSocket.setSocketOption(bufferOpt, QVariant(numBytes));
|
||||
int newBufferSize = _udpSocket.socketOption(bufferOpt).toInt();
|
||||
|
||||
|
||||
qCDebug(networking) << "Changed socket" << bufferTypeString << "buffer size from" << oldBufferSize << "to"
|
||||
<< newBufferSize << "bytes";
|
||||
} else {
|
||||
|
@ -101,29 +105,29 @@ void Socket::setSystemBufferSizes() {
|
|||
|
||||
qint64 Socket::writeBasePacket(const udt::BasePacket& packet, const HifiSockAddr &sockAddr) {
|
||||
// Since this is a base packet we have no way to know if this is reliable or not - we just fire it off
|
||||
|
||||
|
||||
// this should not be called with an instance of Packet
|
||||
Q_ASSERT_X(!dynamic_cast<const Packet*>(&packet),
|
||||
"Socket::writeBasePacket", "Cannot send a Packet/NLPacket via writeBasePacket");
|
||||
|
||||
|
||||
return writeDatagram(packet.getData(), packet.getDataSize(), sockAddr);
|
||||
}
|
||||
|
||||
qint64 Socket::writePacket(const Packet& packet, const HifiSockAddr& sockAddr) {
|
||||
Q_ASSERT_X(!packet.isReliable(), "Socket::writePacket", "Cannot send a reliable packet unreliably");
|
||||
|
||||
|
||||
// write the correct sequence number to the Packet here
|
||||
packet.writeSequenceNumber(++_unreliableSequenceNumbers[sockAddr]);
|
||||
|
||||
|
||||
return writeDatagram(packet.getData(), packet.getDataSize(), sockAddr);
|
||||
}
|
||||
|
||||
qint64 Socket::writePacket(std::unique_ptr<Packet> packet, const HifiSockAddr& sockAddr) {
|
||||
|
||||
|
||||
if (packet->isReliable()) {
|
||||
// hand this packet off to writeReliablePacket
|
||||
// because Qt can't invoke with the unique_ptr we have to release it here and re-construct in writeReliablePacket
|
||||
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "writeReliablePacket", Qt::QueuedConnection,
|
||||
Q_ARG(Packet*, packet.release()),
|
||||
|
@ -131,10 +135,10 @@ qint64 Socket::writePacket(std::unique_ptr<Packet> packet, const HifiSockAddr& s
|
|||
} else {
|
||||
writeReliablePacket(packet.release(), sockAddr);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return writePacket(*packet, sockAddr);
|
||||
}
|
||||
|
||||
|
@ -142,7 +146,7 @@ qint64 Socket::writePacketList(std::unique_ptr<PacketList> packetList, const Hif
|
|||
if (packetList->isReliable()) {
|
||||
// hand this packetList off to writeReliablePacketList
|
||||
// because Qt can't invoke with the unique_ptr we have to release it here and re-construct in writeReliablePacketList
|
||||
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
auto ptr = packetList.release();
|
||||
QMetaObject::invokeMethod(this, "writeReliablePacketList", Qt::AutoConnection,
|
||||
|
@ -151,7 +155,7 @@ qint64 Socket::writePacketList(std::unique_ptr<PacketList> packetList, const Hif
|
|||
} else {
|
||||
writeReliablePacketList(packetList.release(), sockAddr);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -177,18 +181,18 @@ qint64 Socket::writeDatagram(const char* data, qint64 size, const HifiSockAddr&
|
|||
}
|
||||
|
||||
qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& sockAddr) {
|
||||
|
||||
|
||||
qint64 bytesWritten = _udpSocket.writeDatagram(datagram, sockAddr.getAddress(), sockAddr.getPort());
|
||||
|
||||
|
||||
if (bytesWritten < 0) {
|
||||
// when saturating a link this isn't an uncommon message - suppress it so it doesn't bomb the debug
|
||||
static const QString WRITE_ERROR_REGEX = "Socket::writeDatagram QAbstractSocket::NetworkError - Unable to send a message";
|
||||
static QString repeatedMessage
|
||||
= LogHandler::getInstance().addRepeatedMessageRegex(WRITE_ERROR_REGEX);
|
||||
|
||||
|
||||
qCDebug(networking) << "Socket::writeDatagram" << _udpSocket.error() << "-" << qPrintable(_udpSocket.errorString());
|
||||
}
|
||||
|
||||
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
|
@ -199,17 +203,17 @@ Connection& Socket::findOrCreateConnection(const HifiSockAddr& sockAddr) {
|
|||
auto congestionControl = _ccFactory->create();
|
||||
congestionControl->setMaxBandwidth(_maxBandwidth);
|
||||
auto connection = std::unique_ptr<Connection>(new Connection(this, sockAddr, std::move(congestionControl)));
|
||||
|
||||
|
||||
// we queue the connection to cleanup connection in case it asks for it during its own rate control sync
|
||||
QObject::connect(connection.get(), &Connection::connectionInactive, this, &Socket::cleanupConnection);
|
||||
|
||||
|
||||
#ifdef UDT_CONNECTION_DEBUG
|
||||
qCDebug(networking) << "Creating new connection to" << sockAddr;
|
||||
#endif
|
||||
|
||||
|
||||
it = _connectionsHash.insert(it, std::make_pair(sockAddr, std::move(connection)));
|
||||
}
|
||||
|
||||
|
||||
return *it->second;
|
||||
}
|
||||
|
||||
|
@ -228,7 +232,7 @@ void Socket::clearConnections() {
|
|||
|
||||
void Socket::cleanupConnection(HifiSockAddr sockAddr) {
|
||||
auto numErased = _connectionsHash.erase(sockAddr);
|
||||
|
||||
|
||||
if (numErased > 0) {
|
||||
#ifdef UDT_CONNECTION_DEBUG
|
||||
qCDebug(networking) << "Socket::cleanupConnection called for UDT connection to" << sockAddr;
|
||||
|
@ -253,10 +257,10 @@ void Socket::readPendingDatagrams() {
|
|||
while ((packetSizeWithHeader = _udpSocket.pendingDatagramSize()) != -1) {
|
||||
// setup a HifiSockAddr to read into
|
||||
HifiSockAddr senderSockAddr;
|
||||
|
||||
|
||||
// setup a buffer to read the packet into
|
||||
auto buffer = std::unique_ptr<char[]>(new char[packetSizeWithHeader]);
|
||||
|
||||
|
||||
// pull the datagram
|
||||
auto sizeRead = _udpSocket.readDatagram(buffer.get(), packetSizeWithHeader,
|
||||
senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer());
|
||||
|
@ -266,34 +270,34 @@ void Socket::readPendingDatagrams() {
|
|||
// on windows even if there's not a packet available)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
auto it = _unfilteredHandlers.find(senderSockAddr);
|
||||
|
||||
|
||||
if (it != _unfilteredHandlers.end()) {
|
||||
// we have a registered unfiltered handler for this HifiSockAddr - call that and return
|
||||
if (it->second) {
|
||||
auto basePacket = BasePacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr);
|
||||
it->second(std::move(basePacket));
|
||||
}
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// check if this was a control packet or a data packet
|
||||
bool isControlPacket = *reinterpret_cast<uint32_t*>(buffer.get()) & CONTROL_BIT_MASK;
|
||||
|
||||
|
||||
if (isControlPacket) {
|
||||
// setup a control packet from the data we just read
|
||||
auto controlPacket = ControlPacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr);
|
||||
|
||||
|
||||
// move this control packet to the matching connection
|
||||
auto& connection = findOrCreateConnection(senderSockAddr);
|
||||
connection.processControl(move(controlPacket));
|
||||
|
||||
|
||||
} else {
|
||||
// setup a Packet from the data we just read
|
||||
auto packet = Packet::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr);
|
||||
|
||||
|
||||
// call our verification operator to see if this packet is verified
|
||||
if (!_packetFilterOperator || _packetFilterOperator(*packet)) {
|
||||
if (packet->isReliable()) {
|
||||
|
@ -328,27 +332,27 @@ void Socket::connectToSendSignal(const HifiSockAddr& destinationAddr, QObject* r
|
|||
}
|
||||
|
||||
void Socket::rateControlSync() {
|
||||
|
||||
|
||||
// enumerate our list of connections and ask each of them to send off periodic ACK packet for rate control
|
||||
|
||||
|
||||
// the way we do this is a little funny looking - we need to avoid the case where we call sync and
|
||||
// (because of our Qt direct connection to the Connection's signal that it has been deactivated)
|
||||
// an iterator on _connectionsHash would be invalidated by our own call to cleanupConnection
|
||||
|
||||
|
||||
// collect the sockets for all connections in a vector
|
||||
|
||||
|
||||
std::vector<HifiSockAddr> sockAddrVector;
|
||||
sockAddrVector.reserve(_connectionsHash.size());
|
||||
|
||||
|
||||
for (auto& connection : _connectionsHash) {
|
||||
sockAddrVector.emplace_back(connection.first);
|
||||
}
|
||||
|
||||
|
||||
// enumerate that vector of HifiSockAddr objects
|
||||
for (auto& sockAddr : sockAddrVector) {
|
||||
// pull out the respective connection via a quick find on the unordered_map
|
||||
auto it = _connectionsHash.find(sockAddr);
|
||||
|
||||
|
||||
if (it != _connectionsHash.end()) {
|
||||
// if the connection is erased while calling sync since we are re-using the iterator that was invalidated
|
||||
// we're good to go
|
||||
|
@ -356,7 +360,7 @@ void Socket::rateControlSync() {
|
|||
connection->sync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (_synTimer->interval() != _synInterval) {
|
||||
// if the _synTimer interval doesn't match the current _synInterval (changes when the CC factory is changed)
|
||||
// then restart it now with the right interval
|
||||
|
@ -367,7 +371,7 @@ void Socket::rateControlSync() {
|
|||
void Socket::setCongestionControlFactory(std::unique_ptr<CongestionControlVirtualFactory> ccFactory) {
|
||||
// swap the current unique_ptr for the new factory
|
||||
_ccFactory.swap(ccFactory);
|
||||
|
||||
|
||||
// update the _synInterval to the value from the factory
|
||||
_synInterval = _ccFactory->synInterval();
|
||||
}
|
||||
|
@ -402,10 +406,10 @@ Socket::StatsVector Socket::sampleStatsForAllConnections() {
|
|||
}
|
||||
|
||||
|
||||
std::vector<HifiSockAddr> Socket::getConnectionSockAddrs() {
|
||||
std::vector<HifiSockAddr> Socket::getConnectionSockAddrs() {
|
||||
std::vector<HifiSockAddr> addr;
|
||||
addr.reserve(_connectionsHash.size());
|
||||
|
||||
|
||||
for (const auto& connectionPair : _connectionsHash) {
|
||||
addr.push_back(connectionPair.first);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue