Defined and implemented Operation Set Basic Instant Messaging Transport

for querying protocol implementation for operational boundaries.

* Defined the Operation Set for querying transport operation.
* Also implemented the Operation Set in IRC protocol support.
* OTR plugin has been modified to take advantage of the newly defined
Operation Set and queries the protocol for input on building
fragmentation instructions. In case the protocol does not implement the
Operation Set, then it will fall back to OTR defaults.
cefexperiments
Danny van Heumen 11 years ago
parent f970c50c8e
commit 2254995ee3

@ -59,6 +59,12 @@ public class IrcStack
* </pre>
*/
/**
* 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

@ -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;
}
}

@ -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 =

@ -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)
{
// :<nick>!<user>@<host> PRIVMSG <targetnick> :<message>
//
// 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);
}
}

@ -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

@ -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.
*
* <p>
* If there is no limit to the message size, please use constant
* {@link #UNLIMITED}.
* </p>
*
* @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.
*
* <p>
* If there is no limit to the number of messages, please use constant
* {@link #UNLIMITED}.
* </p>
*
* @param contact the contact to which the messages are sent
* @return returns the maximum number of messages to send
*/
int numberOfMessages(Contact contact);
}
Loading…
Cancel
Save