package edu.washington.cs.oneswarm.f2f.messaging.invitation;
import java.util.HashMap;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.DirectByteBuffer;
import org.gudy.azureus2.core3.util.DirectByteBufferPool;
import com.aelitis.azureus.core.networkmanager.RawMessage;
import com.aelitis.azureus.core.networkmanager.impl.RawMessageImpl;
import com.aelitis.azureus.core.peermanager.messaging.Message;
import com.aelitis.azureus.core.peermanager.messaging.MessageException;
import com.aelitis.azureus.core.peermanager.messaging.MessageManager;
import edu.washington.cs.oneswarm.f2f.messaging.invitation.OSF2FAuthRequest.AuthType;
public class OSF2FAuthMessageFatory {
private final static boolean NO_DELAY = true;
// private final static boolean DELAY_OK = false;
private static final String[] id_to_name = new String[OSF2FAuthMessage.LAST_ID + 1];
private static final HashMap<String, LegacyData> legacy_data = new HashMap<String, LegacyData>();
static {
legacy_data.put(OSF2FAuthMessage.ID_OSA_HANDSHAKE, new LegacyData(RawMessage.PRIORITY_HIGH,
NO_DELAY, null, OSF2FAuthMessage.SUBID_OSA_HANDSHAKE));
id_to_name[OSF2FAuthMessage.SUBID_OSA_HANDSHAKE] = OSF2FAuthMessage.ID_OSA_HANDSHAKE;
legacy_data.put(OSF2FAuthMessage.ID_OSA_AUTH_STATUS, new LegacyData(
RawMessage.PRIORITY_HIGH, NO_DELAY, null, OSF2FAuthMessage.SUBID_OSA_AUTH_STATUS));
id_to_name[OSF2FAuthMessage.SUBID_OSA_AUTH_STATUS] = OSF2FAuthMessage.ID_OSA_AUTH_STATUS;
legacy_data.put(OSF2FAuthMessage.ID_OSA_AUTH_REQUEST, new LegacyData(
RawMessage.PRIORITY_HIGH, NO_DELAY, null, OSF2FAuthMessage.SUBID_OSA_AUTH_REQUEST));
id_to_name[OSF2FAuthMessage.SUBID_OSA_AUTH_REQUEST] = OSF2FAuthMessage.ID_OSA_AUTH_REQUEST;
legacy_data.put(OSF2FAuthMessage.ID_OSA_RESPONSE, new LegacyData(RawMessage.PRIORITY_HIGH,
NO_DELAY, null, OSF2FAuthMessage.SUBID_OSA_RESPONSE));
id_to_name[OSF2FAuthMessage.SUBID_OSA_RESPONSE] = OSF2FAuthMessage.ID_OSA_RESPONSE;
}
/**
* Initialize the factory, i.e. register the messages with the message
* manager.
*/
public static void init() {
try {
MessageManager.getSingleton().registerMessageType(
new OSF2FAuthHandshake(OSF2FAuthMessage.CURRENT_VERSION, new byte[0]));
MessageManager.getSingleton().registerMessageType(
new OSF2FAuthStatus(OSF2FAuthMessage.CURRENT_VERSION, 0));
MessageManager.getSingleton().registerMessageType(
new OSF2FAuthRequest(OSF2FAuthMessage.CURRENT_VERSION,
OSF2FAuthRequest.AuthType.KEY, null));
MessageManager.getSingleton().registerMessageType(
new OSF2FAuthResponse(OSF2FAuthMessage.CURRENT_VERSION, AuthType.getFromID(0),
new byte[0]));
} catch (MessageException me) {
me.printStackTrace();
}
}
public static int getMessageType(DirectByteBuffer stream_payload) {
byte id = stream_payload.get(DirectByteBuffer.SS_MSG, 0);
System.err.println("decoding: id=" + id);
if (id == 83)
return Message.TYPE_PROTOCOL_PAYLOAD; // handshake
// message byte
// in position 4
// ("e" in
// OneSwarm)
if (id >= 0 && id < id_to_name.length) {
return MessageManager.getSingleton().lookupMessage(id_to_name[id]).getType();
}
// invalid, return whatever
return Message.TYPE_PROTOCOL_PAYLOAD;
}
/**
* Construct a new OSF2F message instance from the given message raw byte
* stream.
*
* @param stream_payload
* data
* @return decoded/deserialized BT message
* @throws MessageException
* if message creation failed NOTE: Does not auto-return given
* direct buffer on thrown exception.
*/
public static Message createOSF2FMessage(DirectByteBuffer stream_payload)
throws MessageException {
byte id = stream_payload.get(DirectByteBuffer.SS_MSG);
switch (id) {
case OSF2FAuthMessage.SUBID_OSA_HANDSHAKE:
return MessageManager.getSingleton().createMessage(
OSF2FAuthMessage.ID_OSA_HANDSHAKE_BYTES, stream_payload,
OSF2FAuthMessage.CURRENT_VERSION);
case OSF2FAuthMessage.SUBID_OSA_AUTH_REQUEST:
return MessageManager.getSingleton().createMessage(
OSF2FAuthMessage.ID_OSA_AUTH_REQUEST_BYTES, stream_payload,
OSF2FAuthMessage.CURRENT_VERSION);
case OSF2FAuthMessage.SUBID_OSA_AUTH_STATUS:
return MessageManager.getSingleton().createMessage(
OSF2FAuthMessage.ID_OSA_AUTH_STATUS_BYTES, stream_payload,
OSF2FAuthMessage.CURRENT_VERSION);
case OSF2FAuthMessage.SUBID_OSA_RESPONSE:
return MessageManager.getSingleton().createMessage(
OSF2FAuthMessage.ID_OSA_RESPONSE_BYTES, stream_payload,
OSF2FAuthMessage.CURRENT_VERSION);
default: {
System.out.println("Unknown OSF2F message id [" + id + "]");
throw new MessageException("Unknown OSF2F message id [" + id + "]");
}
}
}
/**
* Create the proper OSF2F raw message from the given base message.
*
* @param base_message
* to create from
* @return BT raw message
*/
public static RawMessage createOSF2FRawMessage(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() + "]");
return null; // message id type not found
}
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;
for (int i = 0; i < payload.length; i++) {
raw_buffs[i + 1] = payload[i];
}
return new RawMessageImpl(base_message, raw_buffs, ld.priority, ld.is_no_delay,
ld.to_remove);
}
protected static class LegacyData {
protected final int priority;
protected final boolean is_no_delay;
protected final Message[] to_remove;
protected final byte bt_id;
protected LegacyData(int prio, boolean no_delay, Message[] remove, byte btid) {
this.priority = prio;
this.is_no_delay = no_delay;
this.to_remove = remove;
this.bt_id = btid;
}
}
}