diff --git a/src/main/java/org/opencord/aaa/PortBasedRadiusCommunicator.java b/src/main/java/org/opencord/aaa/PortBasedRadiusCommunicator.java
new file mode 100755
index 0000000..6e256b7
--- /dev/null
+++ b/src/main/java/org/opencord/aaa/PortBasedRadiusCommunicator.java
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.opencord.aaa;
+
+import org.onlab.packet.ARP;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.RADIUS;
+import org.onlab.packet.TpPort;
+import org.onlab.packet.UDP;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipListener;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketService;
+
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.opencord.sadis.SubscriberAndDeviceInformationService;
+
+import org.slf4j.Logger;
+
+import com.google.common.collect.Maps;
+
+import static org.onosproject.net.packet.PacketPriority.CONTROL;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Handles communication with the RADIUS server through ports
+ * of the SDN switches.
+ */
+public class PortBasedRadiusCommunicator implements RadiusCommunicator {
+
+    // for verbose output
+    private final Logger log = getLogger(getClass());
+
+    // our unique identifier
+    private ApplicationId appId;
+
+    // to receive Packet-in events that we'll respond to
+    PacketService packetService;
+
+    DeviceService deviceService;
+
+    MastershipService mastershipService;
+
+    SubscriberAndDeviceInformationService subsService;
+
+    // to store local mapping of IP Address and Serial No of Device
+    private Map<Ip4Address, String> ipToSnMap;
+
+    // connect points to the RADIUS server
+    Set<ConnectPoint> radiusConnectPoints;
+
+    // Parsed RADIUS server addresses
+    protected InetAddress radiusIpAddress;
+
+    // RADIUS server TCP port number
+    protected short radiusServerPort;
+
+    protected String radiusMacAddress;
+
+    // NAS IP address
+    protected InetAddress nasIpAddress;
+
+    protected String nasMacAddress;
+
+    // RADIUS server Vlan ID
+    private short radiusVlanID;
+
+    // RADIUS p-bit
+    private byte radiusPBit;
+
+    PacketCustomizer pktCustomizer;
+    AaaManager aaaManager;
+
+    ConnectPoint radiusServerConnectPoint = null;
+
+    InnerMastershipListener changeListener = new InnerMastershipListener();
+    InnerDeviceListener deviceListener = new InnerDeviceListener();
+
+    PortBasedRadiusCommunicator(ApplicationId appId, PacketService pktService,
+                                MastershipService masService, DeviceService devService,
+                                SubscriberAndDeviceInformationService subsService,
+                                PacketCustomizer pktCustomizer, AaaManager aaaManager) {
+        this.appId = appId;
+        this.packetService = pktService;
+        this.mastershipService = masService;
+        this.deviceService = devService;
+        this.subsService = subsService;
+        this.pktCustomizer = pktCustomizer;
+        this.aaaManager = aaaManager;
+
+        ipToSnMap = Maps.newConcurrentMap();
+        mastershipService.addListener(changeListener);
+        deviceService.addListener(deviceListener);
+
+        log.error("Created PortBased");
+    }
+
+    private void initializeLocalState() {
+        synchronized (this) {
+            radiusServerConnectPoint = null;
+            if (radiusConnectPoints != null) {
+                // find a connect point through a device for which we are master
+                for (ConnectPoint cp: radiusConnectPoints) {
+                    if (mastershipService.isLocalMaster(cp.deviceId())) {
+                        if (deviceService.isAvailable(cp.deviceId())) {
+                            radiusServerConnectPoint = cp;
+                        }
+                        log.warn("RADIUS connectPoint selected is {}", cp);
+                        break;
+                    }
+                }
+            }
+
+            log.warn("RADIUS connectPoint in initializeLocalState is {}", radiusServerConnectPoint);
+
+            if (radiusServerConnectPoint == null) {
+                log.error("Master of none, can't send radius Message to server");
+            }
+        }
+    }
+
+    @Override
+    public void initializeLocalState(AaaConfig newCfg) {
+        if (newCfg.nasIp() != null) {
+            nasIpAddress = newCfg.nasIp();
+        }
+        if (newCfg.radiusIp() != null) {
+            radiusIpAddress = newCfg.radiusIp();
+        }
+        if (newCfg.radiusMac() != null) {
+            radiusMacAddress = newCfg.radiusMac();
+        }
+        if (newCfg.nasMac() != null) {
+            nasMacAddress = newCfg.nasMac();
+        }
+
+        radiusServerPort = newCfg.radiusServerUdpPort();
+        radiusVlanID = newCfg.radiusServerVlanId();
+        radiusPBit = newCfg.radiusServerPBit();
+
+        radiusConnectPoints = newCfg.radiusServerConnectPoints();
+
+        initializeLocalState();
+    }
+
+    @Override
+    public void clearLocalState() {}
+
+    @Override
+    public void deactivate() {
+        mastershipService.removeListener(changeListener);
+        deviceService.removeListener(deviceListener);
+    }
+
+    @Override
+    public void requestIntercepts() {
+        TrafficSelector.Builder selectorArpServer = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_ARP);
+        packetService.requestPackets(selectorArpServer.build(), CONTROL, appId);
+
+        TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPProtocol(IPv4.PROTOCOL_UDP)
+                .matchUdpSrc(TpPort.tpPort(radiusServerPort));
+        packetService.requestPackets(selectorServer.build(), CONTROL, appId);
+    }
+
+    @Override
+    public void withdrawIntercepts() {
+        TrafficSelector.Builder selectorArpServer = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_ARP);
+        packetService.cancelPackets(selectorArpServer.build(), CONTROL, appId);
+
+        TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
+                .matchEthType(Ethernet.TYPE_IPV4)
+                .matchIPProtocol(IPv4.PROTOCOL_UDP)
+                .matchUdpSrc(TpPort.tpPort(radiusServerPort));
+        packetService.cancelPackets(selectorServer.build(), CONTROL, appId);
+    }
+
+    @Override
+    public void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
+        // create the packet
+        Ethernet ethReply = new Ethernet();
+        ethReply.setSourceMACAddress(nasMacAddress);
+        ethReply.setDestinationMACAddress(radiusMacAddress);
+        ethReply.setEtherType(Ethernet.TYPE_IPV4);
+        ethReply.setVlanID(radiusVlanID);
+        ethReply.setPriorityCode(radiusPBit);
+
+        IPv4 ipv4Packet = new IPv4();
+        ipv4Packet.setTtl((byte) 64);
+        ipv4Packet.setSourceAddress(Ip4Address.
+                valueOf(nasIpAddress).toInt());
+        ipv4Packet.setDestinationAddress(Ip4Address.
+                valueOf(radiusIpAddress).toInt());
+
+        UDP udpPacket = new UDP();
+        udpPacket.setSourcePort(radiusServerPort);
+        udpPacket.setDestinationPort(radiusServerPort);
+
+        udpPacket.setPayload(radiusPacket);
+        ipv4Packet.setPayload(udpPacket);
+        ethReply.setPayload(ipv4Packet);
+
+        // store the IP address and SN of the device, later to be used
+        // for ARP responses
+        String serialNo = deviceService.getDevice(inPkt.
+                receivedFrom().deviceId()).serialNumber();
+
+        SubscriberAndDeviceInformation deviceInfo = subsService.get(serialNo);
+
+        if (deviceInfo == null) {
+            log.error("No Device found with SN {}", serialNo);
+            return;
+        }
+        ipToSnMap.put(deviceInfo.ipAddress(), serialNo);
+
+        // send the message out
+        sendFromRadiusServerPort(pktCustomizer.
+                customizeEthernetIPHeaders(ethReply, inPkt));
+    }
+
+    /**
+     * Sends packet to the RADIUS server using one of the switch ports.
+     *
+     * @param packet Ethernet packet to be sent
+     */
+    private void sendFromRadiusServerPort(Ethernet packet) {
+        if (radiusServerConnectPoint != null) {
+            log.trace("AAA Manager sending Ethernet packet = {}", packet);
+            TrafficTreatment t = DefaultTrafficTreatment.builder()
+                    .setOutput(radiusServerConnectPoint.port()).build();
+            OutboundPacket o = new DefaultOutboundPacket(
+                    radiusServerConnectPoint.deviceId(), t, ByteBuffer.wrap(packet.serialize()));
+            packetService.emit(o);
+        } else {
+            log.error("Unable to send RADIUS packet, connectPoint is null");
+        }
+    }
+
+    @Override
+    public void handlePacketFromServer(PacketContext context) {
+        // Extract the original Ethernet frame from the packet information
+        InboundPacket pkt = context.inPacket();
+        Ethernet ethPkt = pkt.parsed();
+        if (ethPkt == null) {
+            return;
+        }
+
+        // identify if incoming packet
+        switch (EthType.EtherType.lookup(ethPkt.getEtherType())) {
+            case ARP:
+                handleArpPacketFromServer(context);
+                break;
+            case IPV4:
+                handleIPv4PacketFromServer(context);
+                break;
+            default:
+                log.debug("Skipping Ethernet packet type {}",
+                        EthType.EtherType.lookup(ethPkt.getEtherType()));
+        }
+    }
+
+    /**
+     * Handles ARP packets from RADIUS server.
+     *
+     * @param context Context for the packet
+     */
+    private void handleArpPacketFromServer(PacketContext context) {
+        // Extract the original Ethernet frame from the packet information
+        InboundPacket pkt = context.inPacket();
+        Ethernet ethPkt = pkt.parsed();
+        if (ethPkt == null) {
+            return;
+        }
+
+        ARP arpPacket = (ARP) ethPkt.getPayload();
+
+        Ip4Address targetAddress = Ip4Address.valueOf(arpPacket.
+                getTargetProtocolAddress());
+
+        String serialNo = ipToSnMap.get(targetAddress);
+        if (serialNo == null) {
+            log.info("No mapping found for ARP reply, target address {}",
+                    targetAddress);
+            return;
+        }
+        MacAddress senderMac = subsService.get(serialNo).hardwareIdentifier();
+        if (senderMac == null) {
+            log.error("ARP resolution, MAC address not found for SN {}", serialNo);
+            return;
+        }
+
+        ARP arpReply = (ARP) arpPacket.clone();
+        arpReply.setOpCode(ARP.OP_REPLY);
+        arpReply.setTargetProtocolAddress(arpPacket.getSenderProtocolAddress());
+        arpReply.setTargetHardwareAddress(arpPacket.getSenderHardwareAddress());
+        arpReply.setSenderProtocolAddress(arpPacket.getTargetProtocolAddress());
+        arpReply.setSenderHardwareAddress(senderMac.toBytes());
+
+        log.debug("AAA Manager: Query for ARP of IP : {}", arpPacket.getTargetProtocolAddress());
+
+        // Ethernet Frame.
+        Ethernet ethReply = new Ethernet();
+        ethReply.setSourceMACAddress(senderMac);
+        ethReply.setDestinationMACAddress(ethPkt.getSourceMAC());
+        ethReply.setEtherType(Ethernet.TYPE_ARP);
+        ethReply.setVlanID(radiusVlanID);
+        ethReply.setPriorityCode(ethPkt.getPriorityCode());
+
+        ethReply.setPayload(arpReply);
+        sendFromRadiusServerPort(ethReply);
+    }
+
+    /**
+     * Handles IP packets from RADIUS server.
+     *
+     * @param context Context for the packet
+     */
+    private void handleIPv4PacketFromServer(PacketContext context) {
+        // Extract the original Ethernet frame from the packet information
+        InboundPacket pkt = context.inPacket();
+        Ethernet ethPkt = pkt.parsed();
+        if (ethPkt == null) {
+            return;
+        }
+
+        IPv4 ipv4Packet = (IPv4) ethPkt.getPayload();
+
+        if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) {
+            UDP udpPacket = (UDP) ipv4Packet.getPayload();
+
+            if (udpPacket.getSourcePort() == radiusServerPort) {
+                //This packet is RADIUS packet from the server.
+                RADIUS radiusMsg;
+                try {
+                    radiusMsg =
+                            RADIUS.deserializer()
+                                    .deserialize(udpPacket.serialize(),
+                                            8,
+                                            udpPacket.getLength() - 8);
+                    try {
+                        aaaManager.handleRadiusPacket(radiusMsg);
+                    }  catch (StateMachineException sme) {
+                        log.error("Illegal state machine operation", sme);
+                    }
+                } catch (DeserializationException dex) {
+                    log.error("Cannot deserialize packet", dex);
+                }
+            }
+        }
+    }
+
+    /**
+     * Handles Mastership changes for the devices which connect
+     * to the RADIUS server.
+     */
+    private class InnerMastershipListener implements MastershipListener {
+        @Override
+        public void event(MastershipEvent event) {
+            if (radiusServerConnectPoint != null &&
+                    radiusServerConnectPoint.deviceId().
+                            equals(event.subject())) {
+                log.trace("Mastership Event recevived for {}", event.subject());
+                // mastership of the device for our connect point has changed
+                // reselect
+                initializeLocalState();
+            }
+        }
+    }
+
+    /**
+     * Handles Device status change for the devices which connect
+     * to the RADIUS server.
+     */
+    private class InnerDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            log.trace("Device Event recevived for {} event {}", event.subject(), event.type());
+            if (radiusServerConnectPoint == null) {
+                switch (event.type()) {
+                    case DEVICE_ADDED:
+                    case DEVICE_AVAILABILITY_CHANGED:
+                        // some device is available check if we can get one
+                        initializeLocalState();
+                        break;
+                    default:
+                        break;
+                }
+                return;
+            }
+            if (radiusServerConnectPoint.deviceId().
+                    equals(event.subject().id())) {
+                switch (event.type()) {
+                    case DEVICE_AVAILABILITY_CHANGED:
+                    case DEVICE_REMOVED:
+                    case DEVICE_SUSPENDED:
+                        // state of our device has changed, check if we need
+                        // to re-select
+                        initializeLocalState();
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+}
