Example #1
0
// This method is called when the edit packet layer has determined that it has a fully formed packet destined for
// a known nodeID.
void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned char* buffer, ssize_t length) {
    NodeList* nodeList = NodeList::getInstance();

    foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
        // only send to the NodeTypes that are getMyNodeType()
        if (node->getType() == getMyNodeType() &&
            ((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) {
            if (node->getActiveSocket()) {
                queuePacketForSending(node, QByteArray(reinterpret_cast<char*>(buffer), length));

                // debugging output...
                bool wantDebugging = false;
                if (wantDebugging) {
                    int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<char*>(buffer));
                    unsigned short int sequence = (*((unsigned short int*)(buffer + numBytesPacketHeader)));
                    quint64 createdAt = (*((quint64*)(buffer + numBytesPacketHeader + sizeof(sequence))));
                    quint64 queuedAt = usecTimestampNow();
                    quint64 transitTime = queuedAt - createdAt;

                    qDebug() << "OctreeEditPacketSender::queuePacketToNode() queued " << buffer[0] <<
                            " - command to node bytes=" << length <<
                            " sequence=" << sequence <<
                            " transitTimeSoFar=" << transitTime << " usecs";
                }
            }
        }
    }
}
Example #2
0
void OctreeEditPacketSender::processNackPacket(const QByteArray& packet) {
    // parse sending node from packet, retrieve packet history for that node
    QUuid sendingNodeUUID = uuidFromPacketHeader(packet);
    
    // if packet history doesn't exist for the sender node (somehow), bail
    if (!_sentPacketHistories.contains(sendingNodeUUID)) {
        return;
    }
    const SentPacketHistory& sentPacketHistory = _sentPacketHistories.value(sendingNodeUUID);

    int numBytesPacketHeader = numBytesForPacketHeader(packet);
    const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(packet.data()) + numBytesPacketHeader;

    // read number of sequence numbers
    uint16_t numSequenceNumbers = (*(uint16_t*)dataAt);
    dataAt += sizeof(uint16_t);
    
    // read sequence numbers and queue packets for resend
    for (int i = 0; i < numSequenceNumbers; i++) {
        unsigned short int sequenceNumber = (*(unsigned short int*)dataAt);
        dataAt += sizeof(unsigned short int);

        // retrieve packet from history
        const QByteArray* packet = sentPacketHistory.getPacket(sequenceNumber);
        if (packet) {
            const SharedNodePointer& node = DependencyManager::get<NodeList>()->nodeWithUUID(sendingNodeUUID);
            queuePacketForSending(node, *packet);
        }
    }
}
Example #3
0
// This method is called when the edit packet layer has determined that it has a fully formed packet destined for
// a known nodeID.
void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned char* buffer,
                                               size_t length, qint64 satoshiCost) {

    bool wantDebug = false;
    DependencyManager::get<NodeList>()->eachNode([&](const SharedNodePointer& node){
        // only send to the NodeTypes that are getMyNodeType()
        if (node->getType() == getMyNodeType()
            && ((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))
            && node->getActiveSocket()) {
            
            // pack sequence number
            int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<char*>(buffer));
            unsigned char* sequenceAt = buffer + numBytesPacketHeader;
            quint16 sequence = _outgoingSequenceNumbers[nodeUUID]++;
            memcpy(sequenceAt, &sequence, sizeof(quint16));
            
            // send packet
            QByteArray packet(reinterpret_cast<const char*>(buffer), length);
            
            queuePacketForSending(node, packet);
            
            if (hasDestinationWalletUUID() && satoshiCost > 0) {
                // if we have a destination wallet UUID and a cost associated with this packet, signal that it
                // needs to be sent
                emit octreePaymentRequired(satoshiCost, nodeUUID, _destinationWalletUUID);
            }
            
            // add packet to history
            _sentPacketHistories[nodeUUID].packetSent(sequence, packet);
            
            // debugging output...
            if (wantDebug) {
                int numBytesPacketHeader = numBytesForPacketHeader(reinterpret_cast<const char*>(buffer));
                unsigned short int sequence = (*((unsigned short int*)(buffer + numBytesPacketHeader)));
                quint64 createdAt = (*((quint64*)(buffer + numBytesPacketHeader + sizeof(sequence))));
                quint64 queuedAt = usecTimestampNow();
                quint64 transitTime = queuedAt - createdAt;
                
                qDebug() << "OctreeEditPacketSender::queuePacketToNode() queued " << buffer[0] <<
                " - command to node bytes=" << length <<
                " satoshiCost=" << satoshiCost <<
                " sequence=" << sequence <<
                " transitTimeSoFar=" << transitTime << " usecs";
            }
        }
    });
}
// This method is called when the edit packet layer has determined that it has a fully formed packet destined for
// a known nodeID. However, we also want to handle the case where the 
void VoxelEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned char* buffer, ssize_t length) {
    NodeList* nodeList = NodeList::getInstance();
    for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
        // only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER
        if (node->getType() == NODE_TYPE_VOXEL_SERVER &&
            ((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) {
            if (nodeList->getNodeActiveSocketOrPing(&(*node))) {
                sockaddr* nodeAddress = node->getActiveSocket();
                queuePacketForSending(*nodeAddress, buffer, length);
                
                // debugging output...
                bool wantDebugging = false;
                if (wantDebugging) {
                    int numBytesPacketHeader = numBytesForPacketHeader(buffer);
                    unsigned short int sequence = (*((unsigned short int*)(buffer + numBytesPacketHeader)));
                    uint64_t createdAt = (*((uint64_t*)(buffer + numBytesPacketHeader + sizeof(sequence))));
                    uint64_t queuedAt = usecTimestampNow();
                    uint64_t transitTime = queuedAt - createdAt;

                    const char* messageName;
                    switch (buffer[0]) {
                        case PACKET_TYPE_SET_VOXEL: 
                            messageName = "PACKET_TYPE_SET_VOXEL"; 
                            break;
                        case PACKET_TYPE_SET_VOXEL_DESTRUCTIVE: 
                            messageName = "PACKET_TYPE_SET_VOXEL_DESTRUCTIVE"; 
                            break;
                        case PACKET_TYPE_ERASE_VOXEL: 
                            messageName = "PACKET_TYPE_ERASE_VOXEL"; 
                            break;
                    }
                    printf("VoxelEditPacketSender::queuePacketToNode() queued %s - command to node bytes=%ld sequence=%d transitTimeSoFar=%llu usecs\n",
                        messageName, length, sequence, transitTime);
                }                
            }
        }
    }
}