serval-dna/java/org/servalproject/servaldna/MdpPacket.java

131 lines
2.9 KiB
Java

package org.servalproject.servaldna;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.DatagramChannel;
/**
* Created by jeremy on 17/02/14.
*/
public class MdpPacket {
private ByteBuffer buff;
public ByteBuffer payload;
private static final int MDP_MTU = 1400;
private static final int HEADER_LEN = 32+4+32+4+1+1+1;
public static final byte MDP_FLAG_NO_CRYPT = (1<<0);
public static final byte MDP_FLAG_NO_SIGN = (1<<1);
public static final byte MDP_FLAG_BIND = (1<<2);
public static final byte MDP_FLAG_CLOSE = (1<<3);
public static final byte MDP_FLAG_ERROR = (1<<4);
public static final int MDP_PORT_ECHO = 7;
public static final int MDP_PORT_DNALOOKUP = 10;
public static final int MDP_PORT_SERVICE_DISCOVERY = 11;
public MdpPacket(){
buff = ByteBuffer.allocate(MDP_MTU + HEADER_LEN);
buff.order(ByteOrder.nativeOrder());
buff.position(HEADER_LEN);
payload = buff.slice();
}
public MdpPacket prepareReply(){
MdpPacket reply = new MdpPacket();
buff.position(0);
buff.limit(HEADER_LEN);
reply.buff.position(0);
reply.buff.put(buff);
return reply;
}
public SubscriberId getLocalSid() throws AbstractId.InvalidBinaryException {
buff.position(0);
return new SubscriberId(buff);
}
public void setLocalSid(SubscriberId local_sid){
buff.position(0);
local_sid.toByteBuffer(buff);
}
public int getLocalPort(){
buff.position(32);
return buff.getInt();
}
public void setLocalPort(int local_port){
buff.position(32);
buff.putInt(local_port);
}
public SubscriberId getRemoteSid() throws AbstractId.InvalidBinaryException {
buff.position(32+4);
return new SubscriberId(buff);
}
public void setRemoteSid(SubscriberId local_sid){
buff.position(32+4);
local_sid.toByteBuffer(buff);
}
public int getRemotePort(){
buff.position(32+4+32);
return buff.getInt();
}
public void setRemotePort(int remote_port){
buff.position(32+4+32);
buff.putInt(remote_port);
}
public byte getFlags(){
buff.position(32+4+32+4);
return buff.get();
}
public void setFlags(byte flags){
buff.position(32+4+32+4);
buff.put(flags);
}
public byte getQOS(){
buff.position(32+4+32+4+1);
return buff.get();
}
public void setQOS(byte qos){
buff.position(32+4+32+4+1);
buff.put(qos);
}
public byte getTTL(){
buff.position(32+4+32+4+1+1);
return buff.get();
}
public void setTTL(byte ttl){
buff.position(32+4+32+4+1+1);
buff.put(ttl);
}
public void send(DatagramChannel channel) throws IOException {
buff.clear();
buff.limit(HEADER_LEN+payload.limit());
channel.write(buff);
}
public void receive(DatagramChannel channel) throws IOException {
buff.clear();
channel.read(buff);
buff.flip();
if (buff.remaining() < HEADER_LEN)
throw new MdpSocket.MdpError("Received packet is too short");
payload.position(0);
payload.limit(buff.limit() - HEADER_LEN);
}
}