stun/src/main/java/de/javawi/jstun/attribute/MessageAttribute.java
/*
* This file is part of JSTUN.
*
* Copyright (c) 2005 Thomas King <king@t-king.de> - All rights
* reserved.
*
* This software is licensed under either the GNU Public License (GPL),
* or the Apache 2.0 license. Copies of both license agreements are
* included in this distribution.
*/
package de.javawi.jstun.attribute;
import de.javawi.jstun.util.Utility;
import de.javawi.jstun.util.UtilityException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class MessageAttribute implements MessageAttributeInterface {
private static final Logger LOGGER = LoggerFactory.getLogger(MessageAttribute.class);
MessageAttributeType type;
public MessageAttribute() {}
public MessageAttribute(MessageAttributeType type) {
setType(type);
}
public void setType(MessageAttributeType type) {
this.type = type;
}
public MessageAttribute.MessageAttributeType getType() {
return type;
}
public static int typeToInteger(MessageAttributeType type) {
if (type == MessageAttributeType.MappedAddress) {
return MAPPEDADDRESS;
}
if (type == MessageAttributeType.ResponseAddress) {
return RESPONSEADDRESS;
}
if (type == MessageAttributeType.ChangeRequest) {
return CHANGEREQUEST;
}
if (type == MessageAttributeType.SourceAddress) {
return SOURCEADDRESS;
}
if (type == MessageAttributeType.ChangedAddress) {
return CHANGEDADDRESS;
}
if (type == MessageAttributeType.Username) {
return USERNAME;
}
if (type == MessageAttributeType.Password) {
return PASSWORD;
}
if (type == MessageAttributeType.MessageIntegrity) {
return MESSAGEINTEGRITY;
}
if (type == MessageAttributeType.ErrorCode) {
return ERRORCODE;
}
if (type == MessageAttributeType.UnknownAttribute) {
return UNKNOWNATTRIBUTE;
}
if (type == MessageAttributeType.ReflectedFrom) {
return REFLECTEDFROM;
}
if (type == MessageAttributeType.ConnectionRequestBinding) {
return CONNECTIONREQUESTBINDING;
}
if (type == MessageAttributeType.BindingChange) {
return BINDINGCHANGE;
}
if (type == MessageAttributeType.Dummy) {
return DUMMY;
}
return -1;
}
public static MessageAttributeType intToType(long type) {
if (type == MAPPEDADDRESS) {
return MessageAttributeType.MappedAddress;
}
if (type == RESPONSEADDRESS) {
return MessageAttributeType.ResponseAddress;
}
if (type == CHANGEREQUEST) {
return MessageAttributeType.ChangeRequest;
}
if (type == SOURCEADDRESS) {
return MessageAttributeType.SourceAddress;
}
if (type == CHANGEDADDRESS) {
return MessageAttributeType.ChangedAddress;
}
if (type == USERNAME) {
return MessageAttributeType.Username;
}
if (type == PASSWORD) {
return MessageAttributeType.Password;
}
if (type == MESSAGEINTEGRITY) {
return MessageAttributeType.MessageIntegrity;
}
if (type == ERRORCODE) {
return MessageAttributeType.ErrorCode;
}
if (type == UNKNOWNATTRIBUTE) {
return MessageAttributeType.UnknownAttribute;
}
if (type == REFLECTEDFROM) {
return MessageAttributeType.ReflectedFrom;
}
if (type == CONNECTIONREQUESTBINDING) {
return MessageAttributeType.ConnectionRequestBinding;
}
if (type == BINDINGCHANGE) {
return MessageAttributeType.BindingChange;
}
if (type == DUMMY) {
return MessageAttributeType.Dummy;
}
return null;
}
public abstract byte[] getBytes() throws UtilityException;
/**
* Abstract public MessageAttribute parse(byte[] data) throws MessageAttributeParsingException;.
*/
public int getLength() throws UtilityException {
return getBytes().length;
}
public static MessageAttribute parseCommonHeader(byte[] data)
throws MessageAttributeParsingException {
try {
byte[] typeArray = new byte[2];
System.arraycopy(data, 0, typeArray, 0, 2);
int type = Utility.twoBytesToInteger(typeArray);
byte[] lengthArray = new byte[2];
System.arraycopy(data, 2, lengthArray, 0, 2);
int lengthValue = Utility.twoBytesToInteger(lengthArray);
byte[] valueArray = new byte[lengthValue];
System.arraycopy(data, 4, valueArray, 0, lengthValue);
MessageAttribute ma;
switch (type) {
case MAPPEDADDRESS:
ma = MappedAddress.parse(valueArray);
break;
case RESPONSEADDRESS:
ma = ResponseAddress.parse(valueArray);
break;
case CHANGEREQUEST:
ma = ChangeRequest.parse(valueArray);
break;
case SOURCEADDRESS:
ma = SourceAddress.parse(valueArray);
break;
case CHANGEDADDRESS:
ma = ChangedAddress.parse(valueArray);
break;
case USERNAME:
ma = Username.parse(valueArray);
break;
case PASSWORD:
ma = Password.parse(valueArray);
break;
case MESSAGEINTEGRITY:
ma = MessageIntegrity.parse(valueArray);
break;
case ERRORCODE:
ma = ErrorCode.parse(valueArray);
break;
case UNKNOWNATTRIBUTE:
ma = UnknownAttribute.parse(valueArray);
break;
case REFLECTEDFROM:
ma = ReflectedFrom.parse(valueArray);
break;
case CONNECTIONREQUESTBINDING:
ma = ConnectionRequestBinding.parse(valueArray);
break;
case BINDINGCHANGE:
ma = BindingChange.parse(valueArray);
break;
default:
if (type <= 0x7fff) {
throw new UnknownMessageAttributeException(
"Unkown mandatory message attribute", intToType(type));
} else {
LOGGER.debug("MessageAttribute with type " + type + " unkown.");
ma = Dummy.parse(valueArray);
break;
}
}
return ma;
} catch (UtilityException ue) {
throw new MessageAttributeParsingException("Parsing error");
}
}
}