/*
*
* Code derived and adapted from the Jitsi client side STUN framework.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.restcomm.media.stun.messages.attributes.general;
import org.restcomm.media.stun.StunException;
import org.restcomm.media.stun.messages.attributes.StunAttribute;
/**
* This class is used to represent the PRIORITY attribute used for ICE
* processing.
*
* This attribute is not in the original specification of STUN It is added as an
* extension to STUN to be used for ICE implementations
*
* PRIORITY attribute contains a 32 bit priority value. It is used in STUN
* binding requests sent from ICE-Agents to their peers.
*/
public class PriorityAttribute extends StunAttribute {
private static final String NAME = "PRIORITY";
private static final char DATA_LENGTH = 4;
/**
* The priority value specified in the attribute.
*
* An integer should be enough to store this value, but long is used, since
* candidate and candidate-pair classes use long to store priority values
*/
private long priority;
public PriorityAttribute() {
super(StunAttribute.PRIORITY);
this.priority = 0;
}
public long getPriority() {
return priority;
}
public void setPriority(long priority) {
// Priority must be between 1 and (2^31 - 1)
if (priority <= 0 || priority > 0x7FFFFFFFL) {
throw new IllegalArgumentException(
"Priority must be between 0 and (2^31 - 1)");
}
this.priority = priority;
}
@Override
public char getDataLength() {
return DATA_LENGTH;
}
@Override
public String getName() {
return NAME;
}
@Override
public boolean equals(Object other) {
if (other == null || !(other instanceof PriorityAttribute)) {
return false;
}
if (other == this) {
return true;
}
PriorityAttribute att = (PriorityAttribute) other;
if (att.getAttributeType() != this.getAttributeType()
|| att.getDataLength() != this.getDataLength()
|| (att.priority != this.priority)) {
return false;
}
return true;
}
@Override
public byte[] encode() {
char type = getAttributeType();
byte[] binValue = new byte[HEADER_LENGTH + DATA_LENGTH];
// Type
binValue[0] = (byte) (type >> 8);
binValue[1] = (byte) (type & 0x00FF);
// Length
binValue[2] = (byte) (getDataLength() >> 8);
binValue[3] = (byte) (getDataLength() & 0x00FF);
// Priority
binValue[4] = (byte) ((priority & 0xFF000000L) >> 24);
binValue[5] = (byte) ((priority & 0x00FF0000L) >> 16);
binValue[6] = (byte) ((priority & 0x0000FF00L) >> 8);
binValue[7] = (byte) (priority & 0x000000FFL);
return binValue;
}
@Override
protected void decodeAttributeBody(byte[] data, char offset, char length)
throws StunException {
long[] values = new long[4];
// Reading in the network byte order (Big-Endian)
values[0] = (long) ((data[offset++] & 0xff) << 24);
values[1] = (long) ((data[offset++] & 0xff) << 16);
values[2] = (long) ((data[offset++] & 0xff) << 8);
values[3] = (long) (data[offset++] & 0xff);
// reconstructing the priority value
this.priority = values[0] | values[1] | values[2] | values[3];
}
}