diff --git a/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java b/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java index 22aab66c8..231f8a98b 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/IrcStack.java @@ -59,6 +59,12 @@ public class IrcStack * */ + /** + * Maximum message size for IRC messages given the spec specifies a buffer + * of 512 bytes. The command ending (CRLF) takes up 2 bytes. + */ + private static final int IRC_PROTOCOL_MAXIMUM_MESSAGE_SIZE = 510; + /** * Clean-up delay. The clean up task clears any remaining chat room list * cache. Since there's no pointing in timing it exactly, delay the clean up @@ -1186,6 +1192,20 @@ private static ChatRoomMemberRole convertMemberMode(final char modeSymbol) return Mode.bySymbol(modeSymbol).getRole(); } + /** + * Calculate maximum message size that can be transmitted. + * + * @param contact receiving contact + * @return returns maximum message size + */ + public int calculateMaximumMessageSize(final Contact contact) + { + final String identity = getIdentityString(); + return IRC_PROTOCOL_MAXIMUM_MESSAGE_SIZE + - (":" + identity + " PRIVMSG " + contact.getAddress() + " :") + .length(); + } + /** * A listener for server-level messages (any messages that are related to * the server, the connection, that are not related to any chatroom in diff --git a/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java index 613026327..07e4308e1 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/OperationSetBasicInstantMessagingIrcImpl.java @@ -1,6 +1,6 @@ /* * Jitsi, the OpenSource Java VoIP and Instant Messaging client. - * + * * Distributable under LGPL license. See terms of license at gnu.org. */ package net.java.sip.communicator.impl.protocol.irc; @@ -17,11 +17,13 @@ */ public class OperationSetBasicInstantMessagingIrcImpl extends AbstractOperationSetBasicInstantMessaging + implements OperationSetBasicInstantMessagingTransport { /** * Logger. */ - private static final Logger LOGGER = Logger.getLogger(OperationSetBasicInstantMessagingIrcImpl.class); + private static final Logger LOGGER = Logger + .getLogger(OperationSetBasicInstantMessagingIrcImpl.class); /** * IRC protocol provider service. @@ -171,7 +173,8 @@ public boolean isContentTypeSupported(final String contentType) * @param from the sender */ @Override - protected void fireMessageReceived(final Message message, final Contact from) + protected void fireMessageReceived(final Message message, + final Contact from) { super.fireMessageReceived(message, from); } @@ -201,4 +204,29 @@ protected void fireMessageDeliveryFailed(final Message message, { super.fireMessageDeliveryFailed(message, to, errorCode); } + + /** + * Calculate the maximum message size for IRC messages. + * + * @param contact the contact receiving the message + * @return returns the size the message can be at maximum to receive a + * complete message. + */ + @Override + public int maximumMessageSize(final Contact contact) + { + return this.provider.getIrcStack().calculateMaximumMessageSize(contact); + } + + /** + * Calculate number of messages allowed to send over IRC. + * + * @param contact contact receiving the messages + * @return returns number of messages that can be received at maximum + */ + @Override + public int numberOfMessages(final Contact contact) + { + return OperationSetBasicInstantMessagingTransport.UNLIMITED; + } } diff --git a/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java b/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java index e8a37417a..bd6cf841b 100644 --- a/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/irc/ProtocolProviderServiceIrcImpl.java @@ -122,8 +122,13 @@ protected void initialize(final String userID, final AccountID accountID) this.instantMessaging = new OperationSetBasicInstantMessagingIrcImpl(this); + // Register basic instant messaging support. addSupportedOperationSet(OperationSetBasicInstantMessaging.class, this.instantMessaging); + // Register basic instant messaging transport support. + addSupportedOperationSet( + OperationSetBasicInstantMessagingTransport.class, + this.instantMessaging); //Initialize persistent presence persistentPresence = diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java b/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java index f14c2ec7f..b7e184a53 100644 --- a/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java +++ b/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java @@ -14,7 +14,6 @@ import net.java.otr4j.*; import net.java.otr4j.crypto.*; import net.java.otr4j.session.*; -import net.java.sip.communicator.impl.protocol.irc.*; import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact; import net.java.sip.communicator.plugin.otr.authdialog.*; import net.java.sip.communicator.service.browserlauncher.*; @@ -431,33 +430,43 @@ public FragmenterInstructions getFragmenterInstructions( final SessionID sessionID) { final OtrContact otrContact = getOtrContact(sessionID); - // FIXME Change this into querying an Operation Set that provides - // Instant Message medium/transport information that we can use to - // determine fragmentation parameters. - if (ProtocolNames.IRC.equals(otrContact.contact - .getProtocolProvider().getProtocolName())) + final OperationSetBasicInstantMessagingTransport transport = + otrContact.contact.getProtocolProvider().getOperationSet( + OperationSetBasicInstantMessagingTransport.class); + if (transport == null) { - // :!@ PRIVMSG : - // - // Example: - // :ircotrtest!~ircotrtes@77-175-185-165.FTTH.ispfabriek.nl - // PRIVMSG test12345abc : - final String identity = - ((ProtocolProviderServiceIrcImpl) otrContact.contact - .getProtocolProvider()).getIrcStack() - .getIdentityString(); - final int size = - 510 - (":" + identity + " PRIVMSG " - + otrContact.contact.getAddress() + " :").length(); - return new FragmenterInstructions( - FragmenterInstructions.UNLIMITED, size); + // There is no operation set for querying transport parameters. + // Assuming transport capabilities are unlimited. + if (logger.isDebugEnabled()) + { + logger.debug("No implementation of " + + "BasicInstantMessagingTransport available. Assuming " + + "OTR defaults for OTR fragmentation instructions."); + } + return null; } - else + int messageSize = transport.maximumMessageSize(otrContact.contact); + if (messageSize + == OperationSetBasicInstantMessagingTransport.UNLIMITED) + { + messageSize = FragmenterInstructions.UNLIMITED; + } + int numberOfMessages = + transport.numberOfMessages(otrContact.contact); + if (numberOfMessages + == OperationSetBasicInstantMessagingTransport.UNLIMITED) + { + numberOfMessages = FragmenterInstructions.UNLIMITED; + } + if (logger.isDebugEnabled()) { - return new FragmenterInstructions( - FragmenterInstructions.UNLIMITED, - FragmenterInstructions.UNLIMITED); + logger.debug("OTR fragmentation instructions for sending a " + + "message to " + otrContact.contact.getDisplayName() + + " (" + otrContact.contact.getAddress() + + "). Maximum number of " + "messages: " + numberOfMessages + + ", maximum message size: " + messageSize); } + return new FragmenterInstructions(numberOfMessages, messageSize); } } diff --git a/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf b/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf index 0dbc56537..07807d412 100644 --- a/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf +++ b/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf @@ -33,5 +33,4 @@ Import-Package: org.osgi.framework, org.bouncycastle.crypto.modes, org.bouncycastle.util, org.bouncycastle.util.encoders, - net.java.sip.communicator.service.msghistory, - net.java.sip.communicator.impl.protocol.irc + net.java.sip.communicator.service.msghistory diff --git a/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessagingTransport.java b/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessagingTransport.java new file mode 100644 index 000000000..cb9526658 --- /dev/null +++ b/src/net/java/sip/communicator/service/protocol/OperationSetBasicInstantMessagingTransport.java @@ -0,0 +1,51 @@ +package net.java.sip.communicator.service.protocol; + +/** + * Provides additional information on the transport on which Basic Instant + * Messaging communication is built. + * + * This interface defines methods that provide information on the transport + * facilities that are used by the Basic Instant Messaging protocol + * implementation. Methods can be used to query the transport channel for + * information such as maximum message sizes and allowed number of consecutive + * messages. + * + * @author Danny van Heumen + */ +public interface OperationSetBasicInstantMessagingTransport + extends OperationSetBasicInstantMessaging +{ + /** + * Constant value indicating unlimited size or number. + */ + int UNLIMITED = -1; + + /** + * Compute the maximum message size for a messaging being sent to the + * provided contact. + * + *

+ * If there is no limit to the message size, please use constant + * {@link #UNLIMITED}. + *

+ * + * @param contact the contact to which the message will be sent + * @return returns the maximum size of the message or UNLIMITED if there is + * no limit + */ + int maximumMessageSize(Contact contact); + + /** + * Compute the maximum number of consecutive messages allowed to be sent to + * this contact. + * + *

+ * If there is no limit to the number of messages, please use constant + * {@link #UNLIMITED}. + *

+ * + * @param contact the contact to which the messages are sent + * @return returns the maximum number of messages to send + */ + int numberOfMessages(Contact contact); +}