Search in sources :

Example 1 with RawMessage

use of com.biglybt.core.networkmanager.RawMessage in project BiglyBT by BiglySoftware.

the class OutgoingMessageQueueImpl method addMessage.

/**
 * Add a message to the message queue.
 * NOTE: Allows for manual listener notification at some later time,
 * using doListenerNotifications(), instead of notifying immediately
 * from within this method.  This is useful if you want to invoke
 * listeners outside of some greater synchronised block to avoid
 * deadlock.
 * @param message message to add
 * @param manual_listener_notify true for manual notification, false for automatic
 */
@Override
public void addMessage(Message message, boolean manual_listener_notify) {
    // do message add notifications
    boolean allowed = true;
    ArrayList list_ref = listeners;
    for (int i = 0; i < list_ref.size(); i++) {
        MessageQueueListener listener = (MessageQueueListener) list_ref.get(i);
        allowed = allowed && listener.messageAdded(message);
    }
    if (!allowed) {
        // message.destroy();  //TODO destroy????
        return;
    }
    RawMessage[] rmesgs = stream_encoder.encodeMessage(message);
    if (destroyed) {
        // queue is shutdown, drop any added messages
        for (int i = 0; i < rmesgs.length; i++) {
            rmesgs[i].destroy();
        }
        return;
    }
    for (int i = 0; i < rmesgs.length; i++) {
        RawMessage rmesg = rmesgs[i];
        removeMessagesOfType(rmesg.messagesToRemove(), manual_listener_notify);
        try {
            queue_mon.enter();
            int pos = 0;
            for (Iterator<RawMessage> it = queue.iterator(); it.hasNext(); ) {
                RawMessage msg = it.next();
                if (rmesg.getPriority() > msg.getPriority() && msg.getRawData()[0].position(DirectByteBuffer.SS_NET) == 0) {
                    // but don't insert in front of a half-sent message
                    break;
                }
                pos++;
            }
            if (rmesg.isNoDelay()) {
                urgent_message = rmesg;
            }
            queue.add(pos, rmesg);
            DirectByteBuffer[] payload = rmesg.getRawData();
            int remaining = 0;
            for (int j = 0; j < payload.length; j++) {
                remaining += payload[j].remaining(DirectByteBuffer.SS_NET);
            }
            total_size += remaining;
            if (rmesg.getType() == Message.TYPE_DATA_PAYLOAD) {
                total_data_size += remaining;
            }
        } finally {
            queue_mon.exit();
        }
        if (manual_listener_notify) {
            // register listener event for later, manual notification
            NotificationItem item = new NotificationItem(NotificationItem.MESSAGE_ADDED);
            item.message = rmesg;
            try {
                delayed_notifications_mon.enter();
                delayed_notifications.add(item);
            } finally {
                delayed_notifications_mon.exit();
            }
        } else {
            // do listener notification now
            ArrayList listeners_ref = listeners;
            for (int j = 0; j < listeners_ref.size(); j++) {
                MessageQueueListener listener = (MessageQueueListener) listeners_ref.get(j);
                listener.messageQueued(rmesg.getBaseMessage());
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) RawMessage(com.biglybt.core.networkmanager.RawMessage) DirectByteBuffer(com.biglybt.core.util.DirectByteBuffer)

Example 2 with RawMessage

use of com.biglybt.core.networkmanager.RawMessage in project BiglyBT by BiglySoftware.

the class HTTPMessageEncoder method encodeMessage.

@Override
public RawMessage[] encodeMessage(Message message) {
    String id = message.getID();
    // System.out.println( "encodeMessage: " + message.getID());
    RawMessage raw_message = null;
    if (id.equals(BTMessage.ID_BT_HANDSHAKE)) {
        raw_message = http_connection.encodeHandShake(message);
    } else if (id.equals(BTMessage.ID_BT_CHOKE)) {
        raw_message = http_connection.encodeChoke();
    } else if (id.equals(BTMessage.ID_BT_UNCHOKE)) {
        raw_message = http_connection.encodeUnchoke();
    } else if (id.equals(BTMessage.ID_BT_BITFIELD)) {
        raw_message = http_connection.encodeBitField();
    } else if (id.equals(BTMessage.ID_BT_PIECE)) {
        return (http_connection.encodePiece(message));
    } else if (id.equals(HTTPMessage.MSG_ID)) {
        raw_message = ((HTTPMessage) message).encode(message);
    }
    if (raw_message == null) {
        raw_message = http_connection.getEmptyRawMessage(message);
    }
    return (new RawMessage[] { raw_message });
}
Also used : RawMessage(com.biglybt.core.networkmanager.RawMessage)

Example 3 with RawMessage

use of com.biglybt.core.networkmanager.RawMessage in project BiglyBT by BiglySoftware.

the class BTMessageFactory method createBTRawMessage.

/**
 * Create the proper BT raw message from the given base message.
 * @param base_message to create from
 * @return BT raw message
 */
public static RawMessage createBTRawMessage(Message base_message) {
    if (base_message instanceof RawMessage) {
        // used for handshake and keep-alive messages
        return (RawMessage) base_message;
    }
    LegacyData ld = (LegacyData) legacy_data.get(base_message.getID());
    if (ld == null) {
        Debug.out("legacy message type id not found for [" + base_message.getID() + "]");
        // message id type not found
        return null;
    }
    DirectByteBuffer[] payload = base_message.getData();
    int payload_size = 0;
    for (int i = 0; i < payload.length; i++) {
        payload_size += payload[i].remaining(DirectByteBuffer.SS_MSG);
    }
    DirectByteBuffer header = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_MSG_BT_HEADER, 5);
    header.putInt(DirectByteBuffer.SS_MSG, 1 + payload_size);
    header.put(DirectByteBuffer.SS_MSG, ld.bt_id);
    header.flip(DirectByteBuffer.SS_MSG);
    DirectByteBuffer[] raw_buffs = new DirectByteBuffer[payload.length + 1];
    raw_buffs[0] = header;
    System.arraycopy(payload, 0, raw_buffs, 1, payload.length);
    return new RawMessageImpl(base_message, raw_buffs, ld.priority, ld.is_no_delay, ld.to_remove);
}
Also used : RawMessageImpl(com.biglybt.core.networkmanager.impl.RawMessageImpl) RawMessage(com.biglybt.core.networkmanager.RawMessage) DirectByteBuffer(com.biglybt.core.util.DirectByteBuffer)

Example 4 with RawMessage

use of com.biglybt.core.networkmanager.RawMessage in project BiglyBT by BiglySoftware.

the class GenericMessageEncoder method encodeMessage.

@Override
public RawMessage[] encodeMessage(Message _message) {
    GenericMessage message = (GenericMessage) _message;
    DirectByteBuffer payload = message.getPayload();
    if (message.isAlreadyEncoded()) {
        return (new RawMessage[] { new RawMessageImpl(message, new DirectByteBuffer[] { payload }, RawMessage.PRIORITY_NORMAL, // send immediately
        true, new Message[0]) });
    } else {
        DirectByteBuffer header = DirectByteBufferPool.getBuffer(DirectByteBuffer.AL_EXTERNAL, 4);
        header.putInt(DirectByteBuffer.SS_MSG, payload.remaining(DirectByteBuffer.SS_MSG));
        header.flip(DirectByteBuffer.SS_MSG);
        return (new RawMessage[] { new RawMessageImpl(message, new DirectByteBuffer[] { header, payload }, RawMessage.PRIORITY_NORMAL, // send immediately
        true, new Message[0]) });
    }
}
Also used : RawMessageImpl(com.biglybt.core.networkmanager.impl.RawMessageImpl) RawMessage(com.biglybt.core.networkmanager.RawMessage) Message(com.biglybt.core.peermanager.messaging.Message) DirectByteBuffer(com.biglybt.core.util.DirectByteBuffer)

Example 5 with RawMessage

use of com.biglybt.core.networkmanager.RawMessage in project BiglyBT by BiglySoftware.

the class HTTPNetworkConnection method encodePiece.

protected RawMessage[] encodePiece(Message message) {
    last_http_activity_time = SystemTime.getCurrentTime();
    BTPiece piece = (BTPiece) message;
    List<pendingRequest> ready_requests = new ArrayList<>();
    boolean found = false;
    synchronized (outstanding_requests) {
        if (destroyed) {
            return (new RawMessage[] { getEmptyRawMessage(message) });
        }
        for (int i = 0; i < outstanding_requests.size(); i++) {
            pendingRequest req = outstanding_requests.get(i);
            if (req.getPieceNumber() == piece.getPieceNumber() && req.getStart() == piece.getPieceOffset() && req.getLength() == piece.getPieceData().remaining(DirectByteBuffer.SS_NET)) {
                if (req.getBTPiece() == null) {
                    req.setBTPiece(piece);
                    found = true;
                    if (i == 0) {
                        Iterator<pendingRequest> it = outstanding_requests.iterator();
                        while (it.hasNext()) {
                            pendingRequest r = it.next();
                            BTPiece btp = r.getBTPiece();
                            if (btp == null) {
                                break;
                            }
                            it.remove();
                            ready_requests.add(r);
                        }
                    }
                    break;
                }
            }
        }
    }
    if (!found) {
        Debug.out("request not matched");
        return (new RawMessage[] { getEmptyRawMessage(message) });
    }
    if (ready_requests.size() == 0) {
        return (new RawMessage[] { getEmptyRawMessage(message) });
    }
    try {
        submitBTRequests();
    } catch (IOException e) {
    }
    pendingRequest req = (pendingRequest) ready_requests.get(0);
    DirectByteBuffer[] buffers;
    httpRequest http_request = req.getHTTPRequest();
    RawMessage[] raw_messages = new RawMessage[ready_requests.size()];
    for (int i = 0; i < raw_messages.length; i++) {
        buffers = new DirectByteBuffer[2];
        if (!http_request.hasSentFirstReply()) {
            http_request.setSentFirstReply();
            String header = encodeHeader(http_request);
            buffers[0] = new DirectByteBuffer(ByteBuffer.wrap(header.getBytes()));
        } else {
            // we have to do this as core code assumes buffer entry 0 is protocol
            buffers[0] = new DirectByteBuffer(ByteBuffer.allocate(0));
        }
        req = (pendingRequest) ready_requests.get(i);
        BTPiece this_piece = req.getBTPiece();
        int piece_number = this_piece.getPieceNumber();
        if (!piece_map.get(piece_number)) {
            // kinda crappy as it triggers on first block of piece, however better
            // than nothing
            piece_map.set(piece_number);
            decoder.addMessage(new BTHave(piece_number, (byte) 1));
        }
        buffers[1] = this_piece.getPieceData();
        req.logQueued();
        if (request_listeners != null) {
            Iterator<requestListener> it = request_listeners.iterator();
            while (it.hasNext()) {
                ((requestListener) it.next()).requestComplete(req);
            }
        }
        raw_messages[i] = new RawMessageImpl(this_piece, buffers, RawMessage.PRIORITY_HIGH, true, new Message[0]);
    }
    return (raw_messages);
}
Also used : RawMessageImpl(com.biglybt.core.networkmanager.impl.RawMessageImpl) RawMessage(com.biglybt.core.networkmanager.RawMessage) Message(com.biglybt.core.peermanager.messaging.Message) IOException(java.io.IOException) RawMessage(com.biglybt.core.networkmanager.RawMessage)

Aggregations

RawMessage (com.biglybt.core.networkmanager.RawMessage)10 DirectByteBuffer (com.biglybt.core.util.DirectByteBuffer)6 ArrayList (java.util.ArrayList)5 RawMessageImpl (com.biglybt.core.networkmanager.impl.RawMessageImpl)3 Message (com.biglybt.core.peermanager.messaging.Message)2 IOException (java.io.IOException)2 WeakReference (java.lang.ref.WeakReference)1 ByteBuffer (java.nio.ByteBuffer)1 Iterator (java.util.Iterator)1