Ejemplo n.º 1
0
qint64 LimitedNodeList::writeUnverifiedDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode,
        const HifiSockAddr& overridenSockAddr) {
    if (destinationNode) {
        // if we don't have an ovveriden address, assume they want to send to the node's active socket
        const HifiSockAddr* destinationSockAddr = &overridenSockAddr;
        if (overridenSockAddr.isNull()) {
            if (destinationNode->getActiveSocket()) {
                // use the node's active socket as the destination socket
                destinationSockAddr = destinationNode->getActiveSocket();
            } else {
                // we don't have a socket to send to, return 0
                return 0;
            }
        }

        PacketType packetType = packetTypeForPacket(datagram);

        // optionally peform sequence number replacement in the header
        if (SEQUENCE_NUMBERED_PACKETS.contains(packetType)) {

            QByteArray datagramCopy = datagram;

            PacketSequenceNumber sequenceNumber = getNextSequenceNumberForPacket(destinationNode->getUUID(), packetType);
            replaceSequenceNumberInPacket(datagramCopy, sequenceNumber, packetType);

            // send the datagram with sequence number replaced in header
            return writeDatagram(datagramCopy, *destinationSockAddr);
        } else {
            return writeDatagram(datagram, *destinationSockAddr);
        }
    }

    // didn't have a destinationNode to send to, return 0
    return 0;
}
Ejemplo n.º 2
0
void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) {
    
    // send the ping packet to the local and public sockets for this node
    QByteArray localPingPacket = constructPingPacket(PingType::Local);
    writeDatagram(localPingPacket, node, node->getLocalSocket());
    
    QByteArray publicPingPacket = constructPingPacket(PingType::Public);
    writeDatagram(publicPingPacket, node, node->getPublicSocket());
    
    if (!node->getSymmetricSocket().isNull()) {
        QByteArray symmetricPingPacket = constructPingPacket(PingType::Symmetric);
        writeDatagram(symmetricPingPacket, node, node->getSymmetricSocket());
    }
}
Ejemplo n.º 3
0
void AutoDiscovery::sendRequest()
{
	writeDatagram(m_requestDatagram, QHostAddress::Broadcast, DISCOVERY_PORT);

	if(++m_requestCounter == DISCOVERY_ATTEMPTS)
		m_requestTimer->stop();
}
Ejemplo n.º 4
0
qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size,
                                         QNearFieldTarget *target, quint8 port)
{
    Q_UNUSED(target);
    Q_UNUSED(port);

    return writeDatagram(data, size);
}
Ejemplo n.º 5
0
qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram,
                                         QNearFieldTarget *target, quint8 port)
{
    Q_UNUSED(datagram);
    Q_UNUSED(target);
    Q_UNUSED(port);

    return writeDatagram(datagram.constData(), datagram.size()-1);
}
Ejemplo n.º 6
0
void AutoDiscovery::sendReply()
{
	writeDatagram(m_replyDatagram, m_replyAddress, m_replyPort);

	if(++m_replyCounter == DISCOVERY_ATTEMPTS)
	{
		m_replyCounter = 0;
		m_replyTimer->stop();
	}
}
Ejemplo n.º 7
0
void Server::sendMessage(QByteArray datagram)
{
    /* QDataStream out(&datagram, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_4);
    out << this->toPlainText().right(1);*/
    //writeDatagram(datagram, host_adress, port);

    writeDatagram(datagram.data(), datagram.size(),
                             QHostAddress("255.255.255.255"), 45454);
    qDebug() << "writeDatagram";
    emit  massageSended(datagram);
}
Ejemplo n.º 8
0
unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeSet& destinationNodeTypes) {
    unsigned n = 0;

    foreach (const SharedNodePointer& node, getNodeHash()) {
        // only send to the NodeTypes we are asked to send to.
        if (destinationNodeTypes.contains(node->getType())) {
            writeDatagram(packet, node);
            ++n;
        }
    }

    return n;
}
Ejemplo n.º 9
0
void QamUdpSocket::sockWrite(const QByteArray& data, quint16 port )
{
	if ( m_distAddr.isNull() ) {
		emit sockInfo("unknown host..." ) ;
		return ;
	}
	if ( port == 0 ) port = m_distPort ;
	writeDatagram( data.data(), data.size(), m_distAddr, port ) ;

	QString s = QString("SEND local port %1 ").arg( localPort() ) ;
	s += QString("to %1:%2").arg( m_distAddr.toString() ).arg( port ) ;
	emit sockInfo( s ) ;
}
Ejemplo n.º 10
0
void PeerInformationSocket::transmitPLoc()
{
  if (m_packetBuffer && m_packetBufferLen > 0)
    {
      QHostAddress addr(CITP_PINF_MULTICAST_IP);
      qint64 ret = writeDatagram((const char*)m_packetBuffer, m_packetBufferLen, 
				 addr, CITP_PINF_MULTICAST_PORT);
      if (-1 == ret)
	{
	  qDebug() << "Failed to send multicast packet:" << error();
	}
    }
}
Ejemplo n.º 11
0
qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram,
                                      const SharedNodePointer& destinationNode,
                                      const HifiSockAddr& overridenSockAddr) {
    if (destinationNode) {
        PacketType packetType = packetTypeForPacket(datagram);

        if (NON_VERIFIED_PACKETS.contains(packetType)) {
            return writeUnverifiedDatagram(datagram, destinationNode, overridenSockAddr);
        }

        // if we don't have an overridden address, assume they want to send to the node's active socket
        const HifiSockAddr* destinationSockAddr = &overridenSockAddr;
        if (overridenSockAddr.isNull()) {
            if (destinationNode->getActiveSocket()) {
                // use the node's active socket as the destination socket
                destinationSockAddr = destinationNode->getActiveSocket();
            } else {
                // we don't have a socket to send to, return 0
                return 0;
            }
        }

        QByteArray datagramCopy = datagram;

        // if we're here and the connection secret is null, debug out - this could be a problem
        if (destinationNode->getConnectionSecret().isNull()) {
            qDebug() << "LimitedNodeList::writeDatagram called for verified datagram with null connection secret for"
                     << "destination node" << destinationNode->getUUID() << " - this is either not secure or will cause"
                     << "this packet to be unverifiable on the receiving side.";
        }

        // perform replacement of hash and optionally also sequence number in the header
        if (SEQUENCE_NUMBERED_PACKETS.contains(packetType)) {
            PacketSequenceNumber sequenceNumber = getNextSequenceNumberForPacket(destinationNode->getUUID(), packetType);
            replaceHashAndSequenceNumberInPacket(datagramCopy, destinationNode->getConnectionSecret(),
                                                 sequenceNumber, packetType);
        } else {
            replaceHashInPacket(datagramCopy, destinationNode->getConnectionSecret(), packetType);
        }

        emit dataSent(destinationNode->getType(), datagram.size());
        auto bytesWritten = writeDatagram(datagramCopy, *destinationSockAddr);
        // Keep track of per-destination-node bandwidth
        destinationNode->recordBytesSent(bytesWritten);
        return bytesWritten;
    }

    // didn't have a destinationNode to send to, return 0
    return 0;
}
Ejemplo n.º 12
0
bool UDPSocket::sendDatagram(const QByteArray &data, const QHostAddress &targetAddress, quint16 targetPort, QString *errorString){
    //qWarning()<<"UDPSocket::sendDatagram(...)-targetAddress:"<<targetAddress.toString()<<" targetPort:"<<targetPort;

    qint64 size = writeDatagram(data, targetAddress, targetPort);
    if(errorString){
        *errorString = this->errorString();
    }

    if(size == -1){
        qCritical()<<QString("UDP Datagram Sent Failed! Target Address:%1, Port:%2, %3").arg(targetAddress.toString()).arg(targetPort).arg(this->errorString());
        return false;
    }

    return (size == data.size())?true:false;;

}
Ejemplo n.º 13
0
void AudioDataSocket::sendData()
{

    char buf[512];
    forever
    {
        auddev->read_data((short*)buf, sizeof(buf));
        writeDatagram(buf, sizeof(buf), *addr, port);
        if(stop_sending)
        {
           break;
        }
//        fprintf(stderr, "send to port %d from %d", peerPort(), localPort());
    }
    stopped = true;
}
Ejemplo n.º 14
0
qint64 LimitedNodeList::writePacket(const NLPacket& packet, const HifiSockAddr& destinationSockAddr,
                                    const QUuid& connectionSecret) {
    if (!NON_SOURCED_PACKETS.contains(packet.getType())) {
        const_cast<NLPacket&>(packet).writeSourceID(getSessionUUID());
    }
    
    if (!connectionSecret.isNull()
        && !NON_SOURCED_PACKETS.contains(packet.getType())
        && !NON_VERIFIED_PACKETS.contains(packet.getType())) {
        const_cast<NLPacket&>(packet).writeVerificationHash(packet.payloadHashWithConnectionUUID(connectionSecret));
    }

    emit dataSent(NodeType::Unassigned, packet.getDataSize());
    
    return writeDatagram(QByteArray::fromRawData(packet.getData(), packet.getDataSize()), destinationSockAddr);
}
Ejemplo n.º 15
0
    void timerEvent(QTimerEvent *event)
    {
        static int n = 0;
        switch (type) {
        case ConnectedClient:
            write(QByteArray::number(n++));
            break;
        case UnconnectedClient:
            writeDatagram(QByteArray::number(n++), peerAddress, peerPort);
            break;
        default:
            break;
        }

        QUdpSocket::timerEvent(event);
    }
Ejemplo n.º 16
0
void ChatRoomBroadCastSocket::writeToSocket(MessageType type, QString message)
{
    QByteArray data;
    QDataStream stream(&data, QIODevice::WriteOnly);
    auto address = getIP();

    stream << type << userName_ << identifier_;
    if (type == NEWPARTICIPANT) {
        stream << address;
    } else if (type == MESSAGE) {
        stream << address << message;
    } else if (type == PRIVATECHAT) {
        stream << address << message;
    }

    writeDatagram(data, data.length(), QHostAddress::Broadcast, kListenPort);
}
Ejemplo n.º 17
0
void Discovery::findBridges()
{
    m_timeout->stop();
    m_reportedBridges.clear();

    QString b("M-SEARCH * HTTP/1.1\r\n"
              "HOST: 239.255.255.250:1900\r\n"
              "MAN: \"ssdp:discover\"\r\n"
              "MX: %1\r\n"
              "ST: libhue:idl\r\n");
    b.arg(DISCOVERY_TIMEOUT);

//    qDebug() << "writing datagram" << b;
    m_timeout->start(DISCOVERY_TIMEOUT * 1000);
    if (writeDatagram(b.toUtf8(), QHostAddress("239.255.255.250"), 1900) < 0) {
        emit error();
    }
}
Ejemplo n.º 18
0
qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const SharedNodePointer& destinationNode,
                               const HifiSockAddr& overridenSockAddr) {
    if (destinationNode) {
        // if we don't have an ovveriden address, assume they want to send to the node's active socket
        const HifiSockAddr* destinationSockAddr = &overridenSockAddr;
        if (overridenSockAddr.isNull()) {
            if (destinationNode->getActiveSocket()) {
                // use the node's active socket as the destination socket
                destinationSockAddr = destinationNode->getActiveSocket();
            } else {
                // we don't have a socket to send to, return 0
                return 0;
            }
        }
        
        return writeDatagram(datagram, *destinationSockAddr, destinationNode->getConnectionSecret());
    }
    
    // didn't have a destinationNode to send to, return 0
    return 0;
}
Ejemplo n.º 19
0
/*! This method will be called to send the SSDP message \a data to the UPnP multicast.*/
void UpnpDiscovery::sendToMulticast(const QByteArray &data)
{
    writeDatagram(data, m_host, m_port);
}
Ejemplo n.º 20
0
qint64 ServerPool::writeDatagram(const QByteArray &datagram,
                                 const QHostAddress &addr, quint16 port)
{
    return writeDatagram(datagram.data(), datagram.size(), addr, port);
}
Ejemplo n.º 21
0
void NodeList::sendDomainServerCheckIn() {
    if (_publicSockAddr.isNull() && !_hasCompletedInitialSTUNFailure) {
        // we don't know our public socket and we need to send it to the domain server
        // send a STUN request to figure it out
        sendSTUNRequest();
    } else if (_domainHandler.getIP().isNull() && _domainHandler.requiresICE()) {
        handleICEConnectionToDomainServer();
    } else if (!_domainHandler.getIP().isNull()) {
        
        bool isUsingDTLS = false;
        
        PacketType domainPacketType = !_domainHandler.isConnected()
            ? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest;
        
        if (!_domainHandler.isConnected()) {
            qDebug() << "Sending connect request to domain-server at" << _domainHandler.getHostname();
        }
        
        // construct the DS check in packet
        QUuid packetUUID = _sessionUUID;
        
        if (domainPacketType == PacketTypeDomainConnectRequest) {
            if (!_domainHandler.getAssignmentUUID().isNull()) {
                // this is a connect request and we're an assigned node
                // so set our packetUUID as the assignment UUID
                packetUUID = _domainHandler.getAssignmentUUID();
            } else if (_domainHandler.requiresICE()) {
                // this is a connect request and we're an interface client
                // that used ice to discover the DS
                // so send our ICE client UUID with the connect request
                packetUUID = _domainHandler.getICEClientID();
            }
        }
        
        QByteArray domainServerPacket = byteArrayWithPopulatedHeader(domainPacketType, packetUUID);
        QDataStream packetStream(&domainServerPacket, QIODevice::Append);
        
        // pack our data to send to the domain-server
        packetStream << _ownerType << _publicSockAddr << _localSockAddr << _nodeTypesOfInterest.toList();
        
        
        // if this is a connect request, and we can present a username signature, send it along
        if (!_domainHandler.isConnected()) {
            DataServerAccountInfo& accountInfo = AccountManager::getInstance().getAccountInfo();
            packetStream << accountInfo.getUsername();
            
            const QByteArray& usernameSignature = AccountManager::getInstance().getAccountInfo().getUsernameSignature();
            
            if (!usernameSignature.isEmpty()) {
                qDebug() << "Including username signature in domain connect request.";
                packetStream << usernameSignature;
            }
        }
        
        if (!isUsingDTLS) {
            writeDatagram(domainServerPacket, _domainHandler.getSockAddr(), QUuid());
        }
        
        const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5;
        static unsigned int numDomainCheckins = 0;
        
        // send a STUN request every Nth domain server check in so we update our public socket, if required
        if (numDomainCheckins++ % NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST == 0) {
            sendSTUNRequest();
        }
        
        if (_numNoReplyDomainCheckIns >= MAX_SILENT_DOMAIN_SERVER_CHECK_INS) {
            // we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS
            // so emit our signal that says that
            emit limitOfSilentDomainCheckInsReached();
        }
        
        // increment the count of un-replied check-ins
        _numNoReplyDomainCheckIns++;
    }
}
Ejemplo n.º 22
0
void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) {
    switch (packetTypeForPacket(packet)) {
        case PacketTypeDomainList: {
            processDomainServerList(packet);
            break;
        }
        case PacketTypeDomainServerRequireDTLS: {
            _domainHandler.parseDTLSRequirementPacket(packet);
            break;
        }
        case PacketTypeIceServerHeartbeatResponse: {
            _domainHandler.processICEResponsePacket(packet);
            break;
        }
        case PacketTypePing: {
            // send back a reply
            SharedNodePointer matchingNode = sendingNodeForPacket(packet);
            if (matchingNode) {
                matchingNode->setLastHeardMicrostamp(usecTimestampNow());
                QByteArray replyPacket = constructPingReplyPacket(packet);
                writeDatagram(replyPacket, matchingNode, senderSockAddr);
                
                // If we don't have a symmetric socket for this node and this socket doesn't match
                // what we have for public and local then set it as the symmetric.
                // This allows a server on a reachable port to communicate with nodes on symmetric NATs
                if (matchingNode->getSymmetricSocket().isNull()) {
                    if (senderSockAddr != matchingNode->getLocalSocket() && senderSockAddr != matchingNode->getPublicSocket()) {
                        matchingNode->setSymmetricSocket(senderSockAddr);
                    }
                }
            }
            
            break;
        }
        case PacketTypePingReply: {
            SharedNodePointer sendingNode = sendingNodeForPacket(packet);
            
            if (sendingNode) {
                sendingNode->setLastHeardMicrostamp(usecTimestampNow());
                
                // activate the appropriate socket for this node, if not yet updated
                activateSocketFromNodeCommunication(packet, sendingNode);
                
                // set the ping time for this node for stat collection
                timePingReply(packet, sendingNode);
            }
            
            break;
        }
        case PacketTypeUnverifiedPing: {
            // send back a reply
            QByteArray replyPacket = constructPingReplyPacket(packet, _domainHandler.getICEClientID());
            writeUnverifiedDatagram(replyPacket, senderSockAddr);
            break;
        }
        case PacketTypeUnverifiedPingReply: {
            qDebug() << "Received reply from domain-server on" << senderSockAddr;
            
            // for now we're unsafely assuming this came back from the domain
            if (senderSockAddr == _domainHandler.getICEPeer().getLocalSocket()) {
                qDebug() << "Connecting to domain using local socket";
                _domainHandler.activateICELocalSocket();
            } else if (senderSockAddr == _domainHandler.getICEPeer().getPublicSocket()) {
                qDebug() << "Conecting to domain using public socket";
                _domainHandler.activateICEPublicSocket();
            } else {
                qDebug() << "Reply does not match either local or public socket for domain. Will not connect.";
            }
        }
        case PacketTypeStunResponse: {
            // a STUN packet begins with 00, we've checked the second zero with packetVersionMatch
            // pass it along so it can be processed into our public address and port
            processSTUNResponse(packet);
            break;
        }
        default:
            LimitedNodeList::processNodeData(senderSockAddr, packet);
            break;
    }
}
Ejemplo n.º 23
0
qint64 LimitedNodeList::writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode,
                                      const HifiSockAddr& overridenSockAddr) {
    return writeDatagram(QByteArray(data, size), destinationNode, overridenSockAddr);
}
Ejemplo n.º 24
0
qint64 LimitedNodeList::writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr) {
    return writeDatagram(datagram, destinationSockAddr);
}
Ejemplo n.º 25
0
void ScriptEngine::run() {
    // TODO: can we add a short circuit for _stoppingAllScripts here? What does it mean to not start running if
    // we're in the process of stopping?

    if (!_isInitialized) {
        init();
    }
    _isRunning = true;
    _isFinished = false;
    emit runningStateChanged();

    QScriptValue result = evaluate(_scriptContents);

    QElapsedTimer startTime;
    startTime.start();

    int thisFrame = 0;

    auto nodeList = DependencyManager::get<NodeList>();
    auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();

    qint64 lastUpdate = usecTimestampNow();

    while (!_isFinished) {
        int usecToSleep = (thisFrame++ * SCRIPT_DATA_CALLBACK_USECS) - startTime.nsecsElapsed() / 1000; // nsec to usec
        if (usecToSleep > 0) {
            usleep(usecToSleep);
        }

        if (_isFinished) {
            break;
        }

        QCoreApplication::processEvents();

        if (_isFinished) {
            break;
        }

        if (!_isFinished && entityScriptingInterface->getEntityPacketSender()->serversExist()) {
            // release the queue of edit entity messages.
            entityScriptingInterface->getEntityPacketSender()->releaseQueuedMessages();

            // since we're in non-threaded mode, call process so that the packets are sent
            if (!entityScriptingInterface->getEntityPacketSender()->isThreaded()) {
                entityScriptingInterface->getEntityPacketSender()->process();
            }
        }

        if (!_isFinished && _isAvatar && _avatarData) {

            const int SCRIPT_AUDIO_BUFFER_SAMPLES = floor(((SCRIPT_DATA_CALLBACK_USECS * AudioConstants::SAMPLE_RATE)
                                                           / (1000 * 1000)) + 0.5);
            const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t);

            QByteArray avatarPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarData);
            avatarPacket.append(_avatarData->toByteArray());

            nodeList->broadcastToNodes(avatarPacket, NodeSet() << NodeType::AvatarMixer);

            if (_isListeningToAudioStream || _avatarSound) {
                // if we have an avatar audio stream then send it out to our audio-mixer
                bool silentFrame = true;

                int16_t numAvailableSamples = SCRIPT_AUDIO_BUFFER_SAMPLES;
                const int16_t* nextSoundOutput = NULL;

                if (_avatarSound) {

                    const QByteArray& soundByteArray = _avatarSound->getByteArray();
                    nextSoundOutput = reinterpret_cast<const int16_t*>(soundByteArray.data()
                                                                       + _numAvatarSoundSentBytes);

                    int numAvailableBytes = (soundByteArray.size() - _numAvatarSoundSentBytes) > SCRIPT_AUDIO_BUFFER_BYTES
                        ? SCRIPT_AUDIO_BUFFER_BYTES
                        : soundByteArray.size() - _numAvatarSoundSentBytes;
                    numAvailableSamples = numAvailableBytes / sizeof(int16_t);


                    // check if the all of the _numAvatarAudioBufferSamples to be sent are silence
                    for (int i = 0; i < numAvailableSamples; ++i) {
                        if (nextSoundOutput[i] != 0) {
                            silentFrame = false;
                            break;
                        }
                    }

                    _numAvatarSoundSentBytes += numAvailableBytes;
                    if (_numAvatarSoundSentBytes == soundByteArray.size()) {
                        // we're done with this sound object - so set our pointer back to NULL
                        // and our sent bytes back to zero
                        _avatarSound = NULL;
                        _numAvatarSoundSentBytes = 0;
                    }
                }
                
                QByteArray audioPacket = byteArrayWithPopulatedHeader(silentFrame
                                                                      ? PacketTypeSilentAudioFrame
                                                                      : PacketTypeMicrophoneAudioNoEcho);

                QDataStream packetStream(&audioPacket, QIODevice::Append);

                // pack a placeholder value for sequence number for now, will be packed when destination node is known
                int numPreSequenceNumberBytes = audioPacket.size();
                packetStream << (quint16) 0;

                if (silentFrame) {
                    if (!_isListeningToAudioStream) {
                        // if we have a silent frame and we're not listening then just send nothing and break out of here
                        break;
                    }

                    // write the number of silent samples so the audio-mixer can uphold timing
                    packetStream.writeRawData(reinterpret_cast<const char*>(&SCRIPT_AUDIO_BUFFER_SAMPLES), sizeof(int16_t));

                    // use the orientation and position of this avatar for the source of this audio
                    packetStream.writeRawData(reinterpret_cast<const char*>(&_avatarData->getPosition()), sizeof(glm::vec3));
                    glm::quat headOrientation = _avatarData->getHeadOrientation();
                    packetStream.writeRawData(reinterpret_cast<const char*>(&headOrientation), sizeof(glm::quat));

                } else if (nextSoundOutput) {
                    // assume scripted avatar audio is mono and set channel flag to zero
                    packetStream << (quint8)0;

                    // use the orientation and position of this avatar for the source of this audio
                    packetStream.writeRawData(reinterpret_cast<const char*>(&_avatarData->getPosition()), sizeof(glm::vec3));
                    glm::quat headOrientation = _avatarData->getHeadOrientation();
                    packetStream.writeRawData(reinterpret_cast<const char*>(&headOrientation), sizeof(glm::quat));

                    // write the raw audio data
                    packetStream.writeRawData(reinterpret_cast<const char*>(nextSoundOutput), numAvailableSamples * sizeof(int16_t));
                }
                
                // write audio packet to AudioMixer nodes
                auto nodeList = DependencyManager::get<NodeList>();
                nodeList->eachNode([this, &nodeList, &audioPacket, &numPreSequenceNumberBytes](const SharedNodePointer& node){
                    // only send to nodes of type AudioMixer
                    if (node->getType() == NodeType::AudioMixer) {
                        // pack sequence number
                        quint16 sequence = _outgoingScriptAudioSequenceNumbers[node->getUUID()]++;
                        memcpy(audioPacket.data() + numPreSequenceNumberBytes, &sequence, sizeof(quint16));
                        
                        // send audio packet
                        nodeList->writeDatagram(audioPacket, node);
                    }
                });
            }
        }

        qint64 now = usecTimestampNow();
        float deltaTime = (float) (now - lastUpdate) / (float) USECS_PER_SECOND;

        if (hasUncaughtException()) {
            int line = uncaughtExceptionLineNumber();
            qCDebug(scriptengine) << "Uncaught exception at (" << _fileNameString << ") line" << line << ":" << uncaughtException().toString();
            emit errorMessage("Uncaught exception at (" + _fileNameString + ") line" + QString::number(line) + ":" + uncaughtException().toString());
            clearExceptions();
        }

        if (!_isFinished) {
            emit update(deltaTime);
        }
        lastUpdate = now;
        
    }

    stopAllTimers(); // make sure all our timers are stopped if the script is ending
    emit scriptEnding();

    // kill the avatar identity timer
    delete _avatarIdentityTimer;

    if (entityScriptingInterface->getEntityPacketSender()->serversExist()) {
        // release the queue of edit entity messages.
        entityScriptingInterface->getEntityPacketSender()->releaseQueuedMessages();

        // since we're in non-threaded mode, call process so that the packets are sent
        if (!entityScriptingInterface->getEntityPacketSender()->isThreaded()) {
            entityScriptingInterface->getEntityPacketSender()->process();
        }
    }

    // If we were on a thread, then wait till it's done
    if (thread()) {
        thread()->quit();
    }

    emit finished(_fileNameString);

    _isRunning = false;
    emit runningStateChanged();

    emit doneRunning();

    _doneRunningThisScript = true;
}
Ejemplo n.º 26
0
void AudioInjector::injectToMixer() {
    if (_currentSendPosition < 0 ||
        _currentSendPosition >= _audioData.size()) {
        _currentSendPosition = 0;
    }

    auto nodeList = DependencyManager::get<NodeList>();

    // make sure we actually have samples downloaded to inject
    if (_audioData.size()) {

        // setup the packet for injected audio
        QByteArray injectAudioPacket = nodeList->byteArrayWithPopulatedHeader(PacketTypeInjectAudio);
        QDataStream packetStream(&injectAudioPacket, QIODevice::Append);

        // pack some placeholder sequence number for now
        int numPreSequenceNumberBytes = injectAudioPacket.size();
        packetStream << (quint16)0;

        // pack stream identifier (a generated UUID)
        packetStream << QUuid::createUuid();

        // pack the stereo/mono type of the stream
        packetStream << _options.stereo;

        // pack the flag for loopback
        uchar loopbackFlag = (uchar) true;
        packetStream << loopbackFlag;

        // pack the position for injected audio
        int positionOptionOffset = injectAudioPacket.size();
        packetStream.writeRawData(reinterpret_cast<const char*>(&_options.position),
                                  sizeof(_options.position));

        // pack our orientation for injected audio
        int orientationOptionOffset = injectAudioPacket.size();
        packetStream.writeRawData(reinterpret_cast<const char*>(&_options.orientation),
                                  sizeof(_options.orientation));

        // pack zero for radius
        float radius = 0;
        packetStream << radius;

        // pack 255 for attenuation byte
        int volumeOptionOffset = injectAudioPacket.size();
        quint8 volume = MAX_INJECTOR_VOLUME * _options.volume;
        packetStream << volume;

        packetStream << _options.ignorePenumbra;

        QElapsedTimer timer;
        timer.start();
        int nextFrame = 0;

        int numPreAudioDataBytes = injectAudioPacket.size();
        bool shouldLoop = _options.loop;

        // loop to send off our audio in NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL byte chunks
        quint16 outgoingInjectedAudioSequenceNumber = 0;
        while (_currentSendPosition < _audioData.size() && !_shouldStop) {

            int bytesToCopy = std::min(((_options.stereo) ? 2 : 1) * AudioConstants::NETWORK_FRAME_BYTES_PER_CHANNEL,
                                       _audioData.size() - _currentSendPosition);

            //  Measure the loudness of this frame
            _loudness = 0.0f;
            for (int i = 0; i < bytesToCopy; i += sizeof(int16_t)) {
                _loudness += abs(*reinterpret_cast<int16_t*>(_audioData.data() + _currentSendPosition + i)) /
                (AudioConstants::MAX_SAMPLE_VALUE / 2.0f);
            }
            _loudness /= (float)(bytesToCopy / sizeof(int16_t));

            memcpy(injectAudioPacket.data() + positionOptionOffset,
                   &_options.position,
                   sizeof(_options.position));
            memcpy(injectAudioPacket.data() + orientationOptionOffset,
                   &_options.orientation,
                   sizeof(_options.orientation));
            volume = MAX_INJECTOR_VOLUME * _options.volume;
            memcpy(injectAudioPacket.data() + volumeOptionOffset, &volume, sizeof(volume));

            // resize the QByteArray to the right size
            injectAudioPacket.resize(numPreAudioDataBytes + bytesToCopy);

            // pack the sequence number
            memcpy(injectAudioPacket.data() + numPreSequenceNumberBytes,
                   &outgoingInjectedAudioSequenceNumber, sizeof(quint16));

            // copy the next NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL bytes to the packet
            memcpy(injectAudioPacket.data() + numPreAudioDataBytes,
                   _audioData.data() + _currentSendPosition, bytesToCopy);

            // grab our audio mixer from the NodeList, if it exists
            SharedNodePointer audioMixer = nodeList->soloNodeOfType(NodeType::AudioMixer);

            // send off this audio packet
            nodeList->writeDatagram(injectAudioPacket, audioMixer);
            outgoingInjectedAudioSequenceNumber++;

            _currentSendPosition += bytesToCopy;

            // send two packets before the first sleep so the mixer can start playback right away

            if (_currentSendPosition != bytesToCopy && _currentSendPosition < _audioData.size()) {

                // process events in case we have been told to stop and be deleted
                QCoreApplication::processEvents();

                if (_shouldStop) {
                    break;
                }

                // not the first packet and not done
                // sleep for the appropriate time
                int usecToSleep = (++nextFrame * AudioConstants::NETWORK_FRAME_USECS) - timer.nsecsElapsed() / 1000;

                if (usecToSleep > 0) {
                    usleep(usecToSleep);
                }
            }

            if (shouldLoop && _currentSendPosition >= _audioData.size()) {
                _currentSendPosition = 0;
            }
        }
    }

    setIsFinished(true);
}
Ejemplo n.º 27
0
qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram)
{
    return writeDatagram(datagram.constData(), datagram.size());
}
Ejemplo n.º 28
0
void Broadcast::sendBroadcast()
{
    QByteArray datagram = "MULTITALK_5387132";
    writeDatagram(datagram.data(),datagram.size(),QHostAddress::Broadcast,3554);
    qDebug()<<"broadcast message sent";
}
Ejemplo n.º 29
0
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    QKeyEvent *kevent;
    QMouseEvent *mevent;
    QString position;

    static bool interior = false;

    UNUSED_PARAMETER(obj);

    switch (event->type()) {
    case QEvent::MouseMove:
        mevent = static_cast<QMouseEvent *>(event);

        interior = frameGeometry().contains(mevent->globalPos());

        if (m_mouseAcquired) {
            position = QString::number(mevent->globalX()) + "," + QString::number(mevent->globalY());
            ui->statusBar->showMessage("Mouse move " + position);

            writeDatagram(DFBINPUT_MOUSE_MOTION, 0, mevent->globalX(), mevent->globalY());
        }
        break;
    case QEvent::KeyPress:
        kevent = static_cast<QKeyEvent *>(event);
        if (m_mouseAcquired) {
            // Forward the event to the MainWindow
            if (kevent->modifiers() & Qt::ControlModifier)
                return false;

            ui->statusBar->showMessage("Key press " + kevent->text());

            if (kevent->text().length() > 0)
                writeDatagram(DFBINPUT_KEYPRESS, kevent->text().at(0).toAscii(), 0, 0);
        }
        break;
    case QEvent::MouseButtonPress:
        if (m_mouseAcquired) {
            mevent = static_cast<QMouseEvent *>(event);

            position = QString::number(mevent->globalX()) + "," + QString::number(mevent->globalY());
            ui->statusBar->showMessage("Mouse click at " + position);

            writeDatagram(DFBINPUT_MOUSE_CLICK, mevent->button() == Qt::LeftButton ? 1 :
                                                (mevent->button() == Qt::RightButton ? 2 : 0),
                          mevent->globalX(), mevent->globalY());
        }
        break;
    case QEvent::MouseButtonDblClick:
        if (m_mouseAcquired) {
            mevent = static_cast<QMouseEvent *>(event);

            position = QString::number(mevent->globalX()) + "," + QString::number(mevent->globalY());
            ui->statusBar->showMessage("Mouse double-click at " + position);

            writeDatagram(DFBINPUT_MOUSE_DBLCLICK, mevent->button() == Qt::LeftButton ? 1 :
                                                   (mevent->button() == Qt::RightButton ? 2 : 0),
                          mevent->globalX(), mevent->globalY());
        }
        break;
    case QEvent::Leave:
        if (m_mouseAcquired && interior)
            grabMouse();
        break;
    default:
        return false;
    }

    return true;
}
Ejemplo n.º 30
0
void MySocket::myWrite(const QString &str)
{
    writeDatagram(str.toAscii().data(),str.length(),clientIP,clientPort);
}