refactoring of listmappingservice into Northbound (future REST) and Southbound (LISP...
[lispflowmapping.git] / mappingservice / southbound / src / main / java / org / opendaylight / lispflowmapping / southbound / lisp / LispSouthboundService.java
1 /*
2  * Copyright (c) 2013 Contextream, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.lispflowmapping.southbound.lisp;
10
11 import java.net.DatagramPacket;
12 import java.nio.ByteBuffer;
13
14 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapResolver;
15 import org.opendaylight.lispflowmapping.interfaces.lisp.IMapServer;
16 import org.opendaylight.lispflowmapping.southbound.lisp.exception.LispMalformedPacketException;
17 import org.opendaylight.lispflowmapping.southbound.lisp.network.PacketHeader;
18 import org.opendaylight.lispflowmapping.southbound.serializer.LispMessage;
19 import org.opendaylight.lispflowmapping.southbound.serializer.LispMessageEnum;
20 import org.opendaylight.lispflowmapping.southbound.serializer.MapNotifySerializer;
21 import org.opendaylight.lispflowmapping.southbound.serializer.MapRegisterSerializer;
22 import org.opendaylight.lispflowmapping.southbound.serializer.MapReplySerializer;
23 import org.opendaylight.lispflowmapping.southbound.serializer.MapRequestSerializer;
24 import org.opendaylight.lispflowmapping.southbound.util.ByteUtil;
25 import org.opendaylight.lispflowmapping.type.lisp.MapNotify;
26 import org.opendaylight.lispflowmapping.type.lisp.MapRegister;
27 import org.opendaylight.lispflowmapping.type.lisp.MapReply;
28 import org.opendaylight.lispflowmapping.type.lisp.MapRequest;
29
30 public class LispSouthboundService implements ILispSouthboundService{
31     private IMapResolver mapResolver;
32     private IMapServer mapServer;
33
34     public LispSouthboundService(IMapResolver mapResolver, IMapServer mapServer) {
35         this.mapResolver = mapResolver;
36         this.mapServer = mapServer;
37     }
38
39     public DatagramPacket handlePacket(DatagramPacket packet) {
40         ByteBuffer inBuffer = ByteBuffer.wrap(packet.getData(), 0, packet.getLength());
41         Object lispType = LispMessageEnum.valueOf((byte) (ByteUtil.getUnsignedByte(inBuffer, LispMessage.Pos.TYPE) >> 4));
42         if (lispType == LispMessageEnum.EncapsulatedControlMessage) {
43             return handleMapRequest(inBuffer);
44         } else {
45             if (lispType == LispMessageEnum.MapRegister) {
46                 return handleMapRegister(inBuffer);
47             } else {
48                 return null;
49             }
50         }
51     }
52
53     private DatagramPacket handleMapRequest(ByteBuffer inBuffer) {
54         int encapsulatedSourcePort = extractEncapsulatedSourcePort(inBuffer);
55         MapRequest request = MapRequestSerializer.getInstance().deserialize(inBuffer);
56         MapReply mapReply = mapResolver.handleMapRequest(request);
57         ByteBuffer outBuffer = MapReplySerializer.getInstance().serialize(mapReply);
58
59         DatagramPacket replyPacket = new DatagramPacket(outBuffer.array(), outBuffer.capacity());
60         replyPacket.setPort(encapsulatedSourcePort);
61         return replyPacket;
62     }
63
64     private int extractEncapsulatedSourcePort(ByteBuffer inBuffer) {
65         try {
66             inBuffer.position(PacketHeader.Length.LISP_ENCAPSULATION);
67             int ipType = (inBuffer.get() >> 4);
68             if (ipType == 4) {
69                 inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV4 - 1);
70             } else {
71                 inBuffer.position(inBuffer.position() + PacketHeader.Length.IPV6_NO_EXT - 1);
72             }
73
74             int encapsulatedSourcePort = inBuffer.getShort() & 0xFFFF;
75             inBuffer.position(inBuffer.position() + PacketHeader.Length.UDP - 2);
76             return encapsulatedSourcePort;
77         } catch (RuntimeException re) {
78             throw new LispMalformedPacketException("Couldn't deserialize Map-Request (len=" + inBuffer.capacity() + ")", re);
79         }
80     }
81
82     private DatagramPacket handleMapRegister(ByteBuffer inBuffer) {
83         MapRegister mapRegister = MapRegisterSerializer.getInstance().deserialize(inBuffer);
84         MapNotify mapNotify = mapServer.handleMapRegister(mapRegister);
85
86         if (mapNotify != null) {
87             ByteBuffer outBuffer = MapNotifySerializer.getInstance().serialize(mapNotify);
88             DatagramPacket notify = new DatagramPacket(outBuffer.array(), outBuffer.limit());
89             notify.setPort(LispMessage.PORT_NUM);
90             return notify;
91         } else {
92             return null;
93         }
94     }
95 }