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; }
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()); } }
void AutoDiscovery::sendRequest() { writeDatagram(m_requestDatagram, QHostAddress::Broadcast, DISCOVERY_PORT); if(++m_requestCounter == DISCOVERY_ATTEMPTS) m_requestTimer->stop(); }
qint64 QLlcpSocketPrivate::writeDatagram(const char *data, qint64 size, QNearFieldTarget *target, quint8 port) { Q_UNUSED(target); Q_UNUSED(port); return writeDatagram(data, size); }
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); }
void AutoDiscovery::sendReply() { writeDatagram(m_replyDatagram, m_replyAddress, m_replyPort); if(++m_replyCounter == DISCOVERY_ATTEMPTS) { m_replyCounter = 0; m_replyTimer->stop(); } }
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); }
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; }
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 ) ; }
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(); } } }
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; }
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;; }
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; }
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); }
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); }
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); }
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(); } }
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; }
/*! 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); }
qint64 ServerPool::writeDatagram(const QByteArray &datagram, const QHostAddress &addr, quint16 port) { return writeDatagram(datagram.data(), datagram.size(), addr, port); }
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++; } }
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; } }
qint64 LimitedNodeList::writeDatagram(const char* data, qint64 size, const SharedNodePointer& destinationNode, const HifiSockAddr& overridenSockAddr) { return writeDatagram(QByteArray(data, size), destinationNode, overridenSockAddr); }
qint64 LimitedNodeList::writeUnverifiedDatagram(const QByteArray& datagram, const HifiSockAddr& destinationSockAddr) { return writeDatagram(datagram, destinationSockAddr); }
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; }
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); }
qint64 QLlcpSocketPrivate::writeDatagram(const QByteArray &datagram) { return writeDatagram(datagram.constData(), datagram.size()); }
void Broadcast::sendBroadcast() { QByteArray datagram = "MULTITALK_5387132"; writeDatagram(datagram.data(),datagram.size(),QHostAddress::Broadcast,3554); qDebug()<<"broadcast message sent"; }
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; }
void MySocket::myWrite(const QString &str) { writeDatagram(str.toAscii().data(),str.length(),clientIP,clientPort); }