diff --git a/app/app.xml b/app/app.xml
new file mode 100644
index 0000000..be7371b
--- /dev/null
+++ b/app/app.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2018-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.
+  -->
+<app name="org.opencord.aaa" origin="ON.Lab" version="${project.version}"
+     category="Traffic Steering" url="http://onosproject.org" title="AAA application for CORD"
+     featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
+     features="${project.artifactId}" apps="org.opencord.sadis">
+    <description>${project.description}</description>
+    <artifact>mvn:${project.groupId}/${project.artifactId}/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/aaa-api/${project.version}</artifact>
+</app>
diff --git a/app/features.xml b/app/features.xml
new file mode 100644
index 0000000..b90eba4
--- /dev/null
+++ b/app/features.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ Copyright 2018-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.
+  -->
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
+    <feature name="${project.artifactId}" version="${project.version}"
+             description="${project.description}">
+        <feature>onos-api</feature>
+        <bundle>mvn:${project.groupId}/aaa-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
+    </feature>
+</features>
diff --git a/app/pom.xml b/app/pom.xml
new file mode 100644
index 0000000..d9e5e64
--- /dev/null
+++ b/app/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2015-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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>aaa</artifactId>
+        <groupId>org.opencord</groupId>
+        <version>1.9.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>aaa-app</artifactId>
+
+    <packaging>bundle</packaging>
+    <description>AAA application for CORD</description>
+
+    <properties>
+        <onos.app.name>org.opencord.aaa</onos.app.name>
+        <onos.version>1.13.9-rc4</onos.version>
+        <onos.app.title>AAA App</onos.app.title>
+        <onos.app.category>Security</onos.app.category>
+        <onos.app.url>http://opencord.org</onos.app.url>
+        <onos.app.readme>802.1x authentication service.</onos.app.readme>
+        <onos.app.requires>
+            org.opencord.sadis
+        </onos.app.requires>
+        <sadis.api.version>3.1.0-SNAPSHOT</sadis.api.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opencord</groupId>
+            <artifactId>sadis-api</artifactId>
+            <version>${sadis.api.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opencord</groupId>
+            <artifactId>aaa-api</artifactId>
+            <version>1.9.0-SNAPSHOT</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+
+            <plugin>
+                <groupId>org.onosproject</groupId>
+                <artifactId>onos-maven-plugin</artifactId>
+                <version>1.11</version>
+            </plugin>
+        </plugins>
+    </build>
+
+
+</project>
\ No newline at end of file
diff --git a/app/src/main/java/org/opencord/aaa/impl/AaaManager.java b/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
new file mode 100755
index 0000000..3e75f17
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/AaaManager.java
@@ -0,0 +1,689 @@
+/*
+ * 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.impl;
+
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.Map;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.EAP;
+import org.onlab.packet.EAPOL;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.RADIUS;
+import org.onlab.packet.RADIUSAttribute;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.AbstractListenerManager;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+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.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.opencord.aaa.AaaConfig;
+import org.opencord.aaa.AuthenticationEvent;
+import org.opencord.aaa.AuthenticationEventListener;
+import org.opencord.aaa.AuthenticationService;
+import org.opencord.aaa.RadiusCommunicator;
+import org.opencord.aaa.StateMachineDelegate;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.osgi.service.component.annotations.Activate;
+import org.slf4j.Logger;
+
+/**
+ * AAA application for ONOS.
+ */
+@Service
+@Component(immediate = true)
+public class AaaManager
+        extends AbstractListenerManager<AuthenticationEvent, AuthenticationEventListener>
+        implements AuthenticationService {
+
+    private static final String APP_NAME = "org.opencord.aaa";
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry netCfgService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected SadisService sadisService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
+
+    private final DeviceListener deviceListener = new InternalDeviceListener();
+
+    // NAS IP address
+    protected InetAddress nasIpAddress;
+
+    // self MAC address
+    protected String nasMacAddress;
+
+    // Parsed RADIUS server addresses
+    protected InetAddress radiusIpAddress;
+
+    // MAC address of RADIUS server or net hop router
+    protected String radiusMacAddress;
+
+    // RADIUS server secret
+    protected String radiusSecret;
+
+    // bindings
+    protected CustomizationInfo customInfo;
+
+    // our application-specific event handler
+    private ReactivePacketProcessor processor = new ReactivePacketProcessor();
+
+    // our unique identifier
+    private ApplicationId appId;
+
+    // Setup specific customization/attributes on the RADIUS packets
+    PacketCustomizer pktCustomizer;
+
+    // packet customizer to use
+    private String customizer;
+
+    // Type of connection to use to communicate with Radius server, options are
+    // "socket" or "packet_out"
+    private String radiusConnectionType;
+
+    // Object for the specific type of communication with the RADIUS
+    // server, socket based or packet_out based
+    RadiusCommunicator impl = null;
+
+    // latest configuration
+    AaaConfig newCfg;
+
+    // Configuration properties factory
+    private final ConfigFactory factory =
+            new ConfigFactory<ApplicationId, AaaConfig>(APP_SUBJECT_FACTORY,
+                                                         AaaConfig.class,
+                                                         "AAA") {
+                @Override
+                public AaaConfig createConfig() {
+                    return new AaaConfig();
+                }
+            };
+
+    // Listener for config changes
+    private final InternalConfigListener cfgListener = new InternalConfigListener();
+
+    private StateMachineDelegate delegate = new InternalStateMachineDelegate();
+
+    /**
+     * Builds an EAPOL packet based on the given parameters.
+     *
+     * @param dstMac    destination MAC address
+     * @param srcMac    source MAC address
+     * @param vlan      vlan identifier
+     * @param eapolType EAPOL type
+     * @param eap       EAP payload
+     * @return Ethernet frame
+     */
+    private static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac,
+                                               short vlan, byte eapolType, EAP eap, byte priorityCode) {
+
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(dstMac.toBytes());
+        eth.setSourceMACAddress(srcMac.toBytes());
+        eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
+        if (vlan != Ethernet.VLAN_UNTAGGED) {
+            eth.setVlanID(vlan);
+            eth.setPriorityCode(priorityCode);
+        }
+        //eapol header
+        EAPOL eapol = new EAPOL();
+        eapol.setEapolType(eapolType);
+        eapol.setPacketLength(eap.getLength());
+
+        //eap part
+        eapol.setPayload(eap);
+
+        eth.setPayload(eapol);
+        eth.setPad(true);
+        return eth;
+    }
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(APP_NAME);
+        eventDispatcher.addSink(AuthenticationEvent.class, listenerRegistry);
+        netCfgService.addListener(cfgListener);
+        netCfgService.registerConfigFactory(factory);
+        subsService = sadisService.getSubscriberInfoService();
+        customInfo = new CustomizationInfo(subsService, deviceService);
+        cfgListener.reconfigureNetwork(netCfgService.getConfig(appId, AaaConfig.class));
+        log.info("Starting with config {} {}", this, newCfg);
+
+        configureRadiusCommunication();
+
+        // register our event handler
+        packetService.addProcessor(processor, PacketProcessor.director(2));
+
+
+        StateMachine.initializeMaps();
+        StateMachine.setDelegate(delegate);
+
+        impl.initializeLocalState(newCfg);
+
+        impl.requestIntercepts();
+
+        deviceService.addListener(deviceListener);
+
+        log.info("Started");
+    }
+
+
+    @Deactivate
+    public void deactivate() {
+        impl.withdrawIntercepts();
+        packetService.removeProcessor(processor);
+        netCfgService.removeListener(cfgListener);
+        StateMachine.unsetDelegate(delegate);
+        StateMachine.destroyMaps();
+        impl.deactivate();
+        deviceService.removeListener(deviceListener);
+        eventDispatcher.removeSink(AuthenticationEvent.class);
+        log.info("Stopped");
+    }
+
+    private void configureRadiusCommunication() {
+        if (radiusConnectionType.toLowerCase().equals("socket")) {
+            impl = new SocketBasedRadiusCommunicator(appId, packetService, this);
+        } else {
+            impl = new PortBasedRadiusCommunicator(appId, packetService, mastershipService,
+                    deviceService, subsService, pktCustomizer, this);
+        }
+    }
+
+    private void configurePacketCustomizer() {
+        switch (customizer.toLowerCase()) {
+            case "sample":
+                pktCustomizer = new SamplePacketCustomizer(customInfo);
+                log.info("Created SamplePacketCustomizer");
+                break;
+            case "att":
+                pktCustomizer = new AttPacketCustomizer(customInfo);
+                log.info("Created AttPacketCustomizer");
+                break;
+            default:
+                pktCustomizer = new PacketCustomizer(customInfo);
+                log.info("Created default PacketCustomizer");
+                break;
+        }
+    }
+
+    /**
+     * Send RADIUS packet to the RADIUS server.
+     *
+     * @param radiusPacket RADIUS packet to be sent to server.
+     * @param inPkt        Incoming EAPOL packet
+     */
+    protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
+        impl.sendRadiusPacket(radiusPacket, inPkt);
+    }
+
+    /**
+     * Handles RADIUS packets.
+     *
+     * @param radiusPacket RADIUS packet coming from the RADIUS server.
+     * @throws StateMachineException if an illegal state transition is triggered
+     * @throws DeserializationException if packet deserialization fails
+     */
+    public void handleRadiusPacket(RADIUS radiusPacket)
+            throws StateMachineException, DeserializationException {
+        if (log.isTraceEnabled()) {
+            log.trace("Received RADIUS packet {}", radiusPacket);
+        }
+        StateMachine stateMachine = StateMachine.lookupStateMachineById(radiusPacket.getIdentifier());
+        if (stateMachine == null) {
+            log.error("Invalid packet identifier {}, could not find corresponding "
+                    + "state machine ... exiting", radiusPacket.getIdentifier());
+            return;
+        }
+
+        EAP eapPayload;
+        Ethernet eth;
+
+        switch (radiusPacket.getCode()) {
+            case RADIUS.RADIUS_CODE_ACCESS_CHALLENGE:
+                log.debug("RADIUS packet: RADIUS_CODE_ACCESS_CHALLENGE");
+                RADIUSAttribute radiusAttrState = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE);
+                byte[] challengeState = null;
+                if (radiusAttrState != null) {
+                    challengeState = radiusAttrState.getValue();
+                }
+                eapPayload = radiusPacket.decapsulateMessage();
+                stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState);
+                eth = buildEapolResponse(stateMachine.supplicantAddress(),
+                        MacAddress.valueOf(nasMacAddress),
+                        stateMachine.vlanId(),
+                        EAPOL.EAPOL_PACKET,
+                        eapPayload, stateMachine.priorityCode());
+                log.debug("Send EAP challenge response to supplicant {}", stateMachine.supplicantAddress().toString());
+                sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+                break;
+            case RADIUS.RADIUS_CODE_ACCESS_ACCEPT:
+                log.debug("RADIUS packet: RADIUS_CODE_ACCESS_ACCEPT");
+                //send an EAPOL - Success to the supplicant.
+                byte[] eapMessageSuccess =
+                        radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue();
+                eapPayload = EAP.deserializer().deserialize(
+                        eapMessageSuccess, 0, eapMessageSuccess.length);
+                eth = buildEapolResponse(stateMachine.supplicantAddress(),
+                        MacAddress.valueOf(nasMacAddress),
+                        stateMachine.vlanId(),
+                        EAPOL.EAPOL_PACKET,
+                        eapPayload, stateMachine.priorityCode());
+                log.info("Send EAP success message to supplicant {}", stateMachine.supplicantAddress().toString());
+                sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+
+                stateMachine.authorizeAccess();
+
+                break;
+            case RADIUS.RADIUS_CODE_ACCESS_REJECT:
+                log.debug("RADIUS packet: RADIUS_CODE_ACCESS_REJECT");
+                //send an EAPOL - Failure to the supplicant.
+                byte[] eapMessageFailure;
+                eapPayload = new EAP();
+                RADIUSAttribute radiusAttrEap = radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE);
+                if (radiusAttrEap == null) {
+                    eapPayload.setCode(EAP.FAILURE);
+                    eapPayload.setIdentifier(stateMachine.challengeIdentifier());
+                    eapPayload.setLength(EAP.EAP_HDR_LEN_SUC_FAIL);
+                } else {
+                    eapMessageFailure = radiusAttrEap.getValue();
+                    eapPayload = EAP.deserializer().deserialize(
+                            eapMessageFailure, 0, eapMessageFailure.length);
+                }
+                eth = buildEapolResponse(stateMachine.supplicantAddress(),
+                        MacAddress.valueOf(nasMacAddress),
+                        stateMachine.vlanId(),
+                        EAPOL.EAPOL_PACKET,
+                        eapPayload, stateMachine.priorityCode());
+                log.warn("Send EAP failure message to supplicant {}", stateMachine.supplicantAddress().toString());
+                sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+                stateMachine.denyAccess();
+
+                break;
+            default:
+                log.warn("Unknown RADIUS message received with code: {}", radiusPacket.getCode());
+        }
+    }
+
+    /**
+     * Send the ethernet packet to the supplicant.
+     *
+     * @param ethernetPkt  the ethernet packet
+     * @param connectPoint the connect point to send out
+     */
+    private void sendPacketToSupplicant(Ethernet ethernetPkt, ConnectPoint connectPoint) {
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(connectPoint.port()).build();
+        OutboundPacket packet = new DefaultOutboundPacket(connectPoint.deviceId(),
+                                                          treatment, ByteBuffer.wrap(ethernetPkt.serialize()));
+        if (log.isTraceEnabled()) {
+            EAPOL eap = ((EAPOL) ethernetPkt.getPayload());
+            log.trace("Sending eapol payload {} enclosed in {} to supplicant at {}",
+                      eap, ethernetPkt, connectPoint);
+        }
+        packetService.emit(packet);
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+
+    // our handler defined as a private inner class
+
+    /**
+     * Packet processor responsible for forwarding packets along their paths.
+     */
+    private class ReactivePacketProcessor implements PacketProcessor {
+        @Override
+        public void process(PacketContext context) {
+
+            // Extract the original Ethernet frame from the packet information
+            InboundPacket pkt = context.inPacket();
+            Ethernet ethPkt = pkt.parsed();
+            if (ethPkt == null) {
+                return;
+            }
+
+            try {
+                // identify if incoming packet comes from supplicant (EAP) or RADIUS
+                switch (EthType.EtherType.lookup(ethPkt.getEtherType())) {
+                    case EAPOL:
+                        handleSupplicantPacket(context.inPacket());
+                        break;
+                    default:
+                        // any other packets let the specific implementation handle
+                        impl.handlePacketFromServer(context);
+                }
+            } catch (StateMachineException e) {
+                log.warn("Unable to process packet:", e);
+            }
+        }
+
+        /**
+         * Creates and initializes common fields of a RADIUS packet.
+         *
+         * @param stateMachine state machine for the request
+         * @param eapPacket  EAP packet
+         * @return RADIUS packet
+         */
+        private RADIUS getRadiusPayload(StateMachine stateMachine, byte identifier, EAP eapPacket) {
+            RADIUS radiusPayload =
+                    new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
+                               eapPacket.getIdentifier());
+
+            // set Request Authenticator in StateMachine
+            stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
+
+            radiusPayload.setIdentifier(identifier);
+            radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
+                                       stateMachine.username());
+
+            radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
+                    AaaManager.this.nasIpAddress.getAddress());
+
+            radiusPayload.encapsulateMessage(eapPacket);
+
+            return radiusPayload;
+        }
+
+        /**
+         * Handles PAE packets (supplicant).
+         *
+         * @param inPacket Ethernet packet coming from the supplicant
+         */
+        private void handleSupplicantPacket(InboundPacket inPacket) throws StateMachineException {
+            Ethernet ethPkt = inPacket.parsed();
+            // Where does it come from?
+            MacAddress srcMac = ethPkt.getSourceMAC();
+
+            DeviceId deviceId = inPacket.receivedFrom().deviceId();
+            PortNumber portNumber = inPacket.receivedFrom().port();
+            String sessionId = deviceId.toString() + portNumber.toString();
+            EAPOL eapol = (EAPOL) ethPkt.getPayload();
+            if (log.isTraceEnabled()) {
+                log.trace("Received EAPOL packet {} in enclosing packet {} from "
+                        + "dev/port: {}/{}", eapol, ethPkt, deviceId,
+                          portNumber);
+            }
+
+            StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(sessionId);
+            if (stateMachine == null) {
+                log.debug("Creating new state machine for sessionId: {} for "
+                                + "dev/port: {}/{}", sessionId, deviceId, portNumber);
+                stateMachine = new StateMachine(sessionId);
+            } else {
+                log.debug("Using existing state-machine for sessionId: {}", sessionId);
+            }
+
+
+            switch (eapol.getEapolType()) {
+                case EAPOL.EAPOL_START:
+                    log.debug("EAP packet: EAPOL_START");
+                    stateMachine.setSupplicantConnectpoint(inPacket.receivedFrom());
+                    stateMachine.start();
+
+                    //send an EAP Request/Identify to the supplicant
+                    EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.identifier(), EAP.ATTR_IDENTITY, null);
+                    if (ethPkt.getVlanID() != Ethernet.VLAN_UNTAGGED) {
+                       stateMachine.setPriorityCode(ethPkt.getPriorityCode());
+                    }
+                    Ethernet eth = buildEapolResponse(srcMac, MacAddress.valueOf(nasMacAddress),
+                                                      ethPkt.getVlanID(), EAPOL.EAPOL_PACKET,
+                                                      eapPayload, stateMachine.priorityCode());
+
+                    stateMachine.setSupplicantAddress(srcMac);
+                    stateMachine.setVlanId(ethPkt.getVlanID());
+
+                    log.debug("Getting EAP identity from supplicant {}", stateMachine.supplicantAddress().toString());
+                    sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+
+                    break;
+                case EAPOL.EAPOL_LOGOFF:
+                    log.debug("EAP packet: EAPOL_LOGOFF");
+                    if (stateMachine.state() == StateMachine.STATE_AUTHORIZED) {
+                        stateMachine.logoff();
+                    }
+
+                    break;
+                case EAPOL.EAPOL_PACKET:
+                    RADIUS radiusPayload;
+                    // check if this is a Response/Identify or  a Response/TLS
+                    EAP eapPacket = (EAP) eapol.getPayload();
+
+                    byte dataType = eapPacket.getDataType();
+                    switch (dataType) {
+
+                        case EAP.ATTR_IDENTITY:
+                            log.debug("EAP packet: EAPOL_PACKET ATTR_IDENTITY");
+                            // request id access to RADIUS
+                            stateMachine.setUsername(eapPacket.getData());
+
+                            radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket);
+                            radiusPayload = pktCustomizer.customizePacket(radiusPayload, inPacket);
+                            radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
+
+                            sendRadiusPacket(radiusPayload, inPacket);
+
+                            // change the state to "PENDING"
+                            stateMachine.requestAccess();
+                            break;
+                        case EAP.ATTR_MD5:
+                            log.debug("EAP packet: EAPOL_PACKET ATTR_MD5");
+                            // verify if the EAP identifier corresponds to the
+                            // challenge identifier from the client state
+                            // machine.
+                            if (eapPacket.getIdentifier() == stateMachine.challengeIdentifier()) {
+                                //send the RADIUS challenge response
+                                radiusPayload =
+                                        getRadiusPayload(stateMachine,
+                                                         stateMachine.identifier(),
+                                                         eapPacket);
+                                radiusPayload = pktCustomizer.customizePacket(radiusPayload, inPacket);
+
+                                if (stateMachine.challengeState() != null) {
+                                    radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
+                                            stateMachine.challengeState());
+                                }
+                                radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
+                                sendRadiusPacket(radiusPayload, inPacket);
+                            }
+                            break;
+                        case EAP.ATTR_TLS:
+                            log.debug("EAP packet: EAPOL_PACKET ATTR_TLS");
+                            // request id access to RADIUS
+                            radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket);
+                            radiusPayload = pktCustomizer.customizePacket(radiusPayload, inPacket);
+
+                            if (stateMachine.challengeState() != null) {
+                                radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
+                                        stateMachine.challengeState());
+                            }
+                            stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
+
+                            radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
+                            sendRadiusPacket(radiusPayload, inPacket);
+
+                            if (stateMachine.state() != StateMachine.STATE_PENDING) {
+                                stateMachine.requestAccess();
+                            }
+
+                            break;
+                        default:
+                            log.warn("Unknown EAP packet type");
+                            return;
+                    }
+                    break;
+                default:
+                    log.debug("Skipping EAPOL message {}", eapol.getEapolType());
+            }
+        }
+    }
+
+    /**
+     * Delegate allowing the StateMachine to notify us of events.
+     */
+    private class InternalStateMachineDelegate implements StateMachineDelegate {
+
+        @Override
+        public void notify(AuthenticationEvent authenticationEvent) {
+            log.info("Auth event {} for {}",
+                    authenticationEvent.type(), authenticationEvent.subject());
+            post(authenticationEvent);
+        }
+    }
+
+    /**
+     * Configuration Listener, handles change in configuration.
+     */
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        /**
+         * Reconfigures the AAA application according to the
+         * configuration parameters passed.
+         *
+         * @param cfg configuration object
+         */
+        private void reconfigureNetwork(AaaConfig cfg) {
+            log.info("Reconfiguring AaaConfig from config: {}", cfg);
+
+            if (cfg == null) {
+                newCfg = new AaaConfig();
+            } else {
+                newCfg = cfg;
+            }
+            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();
+            }
+            if (newCfg.radiusSecret() != null) {
+                radiusSecret = newCfg.radiusSecret();
+            }
+
+            boolean reconfigureCustomizer = false;
+            if (customizer == null || !customizer.equals(newCfg.radiusPktCustomizer())) {
+                customizer = newCfg.radiusPktCustomizer();
+                configurePacketCustomizer();
+                reconfigureCustomizer = true;
+            }
+
+            if (radiusConnectionType == null
+                    || reconfigureCustomizer
+                    || !radiusConnectionType.equals(newCfg.radiusConnectionType())) {
+                radiusConnectionType = newCfg.radiusConnectionType();
+                if (impl != null) {
+                    impl.withdrawIntercepts();
+                    impl.clearLocalState();
+                }
+                configureRadiusCommunication();
+                impl.initializeLocalState(newCfg);
+                impl.requestIntercepts();
+            } else if (impl != null) {
+                impl.clearLocalState();
+                impl.initializeLocalState(newCfg);
+            }
+        }
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+
+            if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
+                    event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
+                    event.configClass().equals(AaaConfig.class)) {
+
+                AaaConfig cfg = netCfgService.getConfig(appId, AaaConfig.class);
+                reconfigureNetwork(cfg);
+
+                log.info("Reconfigured: {}", cfg.toString());
+            }
+        }
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+
+            switch (event.type()) {
+                case PORT_REMOVED:
+                    DeviceId devId = event.subject().id();
+                    PortNumber portNumber = event.port().number();
+                    String sessionId = devId.toString() + portNumber.toString();
+
+                    Map<String, StateMachine> sessionIdMap = StateMachine.sessionIdMap();
+                    StateMachine removed = sessionIdMap.remove(sessionId);
+                    if (removed != null) {
+                        StateMachine.deleteStateMachineMapping(removed);
+                    }
+
+                    break;
+                default:
+                    return;
+            }
+        }
+    }
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/AaaResetDeviceCommand.java b/app/src/main/java/org/opencord/aaa/impl/AaaResetDeviceCommand.java
new file mode 100644
index 0000000..14b0fe1
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/AaaResetDeviceCommand.java
@@ -0,0 +1,39 @@
+/*
+ * 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.impl;
+
+import org.apache.karaf.shell.commands.Command;
+import org.apache.karaf.shell.commands.Argument;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onlab.packet.MacAddress;
+
+/**
+ * Removes a AAA state machine.
+ */
+@Command(scope = "onos", name = "aaa-reset-device",
+         description = "Resets the authentication state machine for a given device")
+public class AaaResetDeviceCommand extends AbstractShellCommand {
+    @Argument(index = 0, name = "mac", description = "MAC of device to reset authention state",
+              required = true, multiValued = true)
+    private String[] macs = null;
+
+    @Override
+    protected void execute() {
+        for (String mac : macs) {
+            StateMachine.deleteByMac(MacAddress.valueOf(mac));
+        }
+    }
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/AaaShowUsersCommand.java b/app/src/main/java/org/opencord/aaa/impl/AaaShowUsersCommand.java
new file mode 100644
index 0000000..ed117ac
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/AaaShowUsersCommand.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016-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.impl;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.device.DeviceService;
+
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+
+/**
+ * Shows the users in the aaa.
+ */
+@Command(scope = "onos", name = "aaa-users",
+        description = "Shows the aaa users")
+public class AaaShowUsersCommand extends AbstractShellCommand {
+    @Override
+    protected void execute() {
+        String[] state = {
+                "IDLE",
+                "STARTED",
+                "PENDING",
+                "AUTHORIZED",
+                "UNAUTHORIZED"
+        };
+
+        DeviceService devService = AbstractShellCommand.get(DeviceService.class);
+        SadisService sadisService =
+                AbstractShellCommand.get(SadisService.class);
+
+        for (StateMachine stateMachine : StateMachine.sessionIdMap().values()) {
+            String deviceId = stateMachine.supplicantConnectpoint().deviceId().toString();
+            String portNum = stateMachine.supplicantConnectpoint().port().toString();
+
+            String username = "UNKNOWN";
+            if (stateMachine.username() != null) {
+                username = new String(stateMachine.username());
+            }
+            String mac = "UNKNOWN";
+            if (stateMachine.supplicantAddress() != null) {
+                mac = stateMachine.supplicantAddress().toString();
+            }
+
+            String nasPortId = devService.getPort(stateMachine.supplicantConnectpoint()).
+                    annotations().value(AnnotationKeys.PORT_NAME);
+
+            String subsId = "UNKNOWN";
+            SubscriberAndDeviceInformation subscriber = sadisService.getSubscriberInfoService().get(nasPortId);
+            if (subscriber != null) {
+                subsId = subscriber.nasPortId();
+            }
+
+            print("UserName=%s,CurrentState=%s,DeviceId=%s,MAC=%s,PortNumber=%s,SubscriberId=%s",
+                  username, state[stateMachine.state()], deviceId, mac, portNum, subsId);
+        }
+    }
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/AttPacketCustomizer.java b/app/src/main/java/org/opencord/aaa/impl/AttPacketCustomizer.java
new file mode 100644
index 0000000..1c23684
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/AttPacketCustomizer.java
@@ -0,0 +1,33 @@
+/*
+ * 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.impl;
+
+/**
+ * AT&T specific RADIUS packet customization.
+ *
+ */
+public class AttPacketCustomizer extends SamplePacketCustomizer {
+
+    public AttPacketCustomizer(CustomizationInfo customInfo) {
+        super(customInfo);
+    }
+
+    @Override
+    protected boolean updateNasIp() {
+        return false;
+    }
+
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/CustomizationInfo.java b/app/src/main/java/org/opencord/aaa/impl/CustomizationInfo.java
new file mode 100755
index 0000000..9277056
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/CustomizationInfo.java
@@ -0,0 +1,45 @@
+/*
+ * 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.impl;
+
+import org.onosproject.net.device.DeviceService;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+
+/**
+ * Info required to do customization to packets.
+ */
+public class CustomizationInfo {
+
+    private DeviceService devService;
+
+    private BaseInformationService<SubscriberAndDeviceInformation> subscriberService;
+
+    public CustomizationInfo(BaseInformationService<SubscriberAndDeviceInformation> subsService,
+                             DeviceService devService) {
+        this.subscriberService = subsService;
+        this.devService = devService;
+    }
+
+    public DeviceService deviceService() {
+        return devService;
+    }
+
+    public BaseInformationService<SubscriberAndDeviceInformation> subscriberService() {
+        return subscriberService;
+    }
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/PacketCustomizer.java b/app/src/main/java/org/opencord/aaa/impl/PacketCustomizer.java
new file mode 100755
index 0000000..265edf7
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/PacketCustomizer.java
@@ -0,0 +1,60 @@
+/*
+ * 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.impl;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.RADIUS;
+
+import org.onosproject.net.packet.InboundPacket;
+
+/**
+ * Default RADIUS Packet Customization.
+ * Does not change the packet
+ *
+ * Subclasses should implement filling of attributes depending on specifics ofsetup/RADIUS server
+ */
+public class  PacketCustomizer {
+
+    protected CustomizationInfo customInfo;
+
+    public PacketCustomizer(CustomizationInfo info) {
+        this.customInfo = info;
+    }
+
+    /**
+     * Customize the packet as per specific Setup or RADIUS server requirements.
+     *
+     * @param inPkt RADIUS packet to be customized
+     * @param eapPacket Incoming packet containing EAP for which this the RADIUS message is being created
+     * @return Customized RADIUS packet
+     */
+    public RADIUS customizePacket(RADIUS inPkt, InboundPacket eapPacket) {
+        return inPkt;
+    }
+
+    /**
+     * Customize the Ethernet header as per specific Setup or RADIUS server requirements.
+     *
+     * @param inPkt Ethernet packet to be changed
+     * @param eapPacket Incoming packet containing EAP for which this the
+     *                  RADIUS message is being created
+     * @return Changed Ethernet packet
+     */
+    public Ethernet customizeEthernetIPHeaders(Ethernet inPkt,
+                                               InboundPacket eapPacket) {
+        return inPkt;
+    }
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/PortBasedRadiusCommunicator.java b/app/src/main/java/org/opencord/aaa/impl/PortBasedRadiusCommunicator.java
new file mode 100755
index 0000000..e1b8bb9
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/PortBasedRadiusCommunicator.java
@@ -0,0 +1,458 @@
+/*
+ * 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.impl;
+
+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.aaa.AaaConfig;
+import org.opencord.aaa.RadiusCommunicator;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+
+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;
+
+    BaseInformationService<SubscriberAndDeviceInformation> 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,
+                                BaseInformationService<SubscriberAndDeviceInformation> 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.info("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;
+                        }
+                        break;
+                    }
+                }
+            }
+
+            log.info("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() {
+        mastershipService.removeListener(changeListener);
+        deviceService.removeListener(deviceListener);
+    }
+
+    @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);
+
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+               selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort());
+               packetService.requestPackets(selector.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);
+
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort());
+        packetService.cancelPackets(selector.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.warn("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.warn("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;
+                }
+            }
+        }
+    }
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/SamplePacketCustomizer.java b/app/src/main/java/org/opencord/aaa/impl/SamplePacketCustomizer.java
new file mode 100755
index 0000000..d8dd486
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/SamplePacketCustomizer.java
@@ -0,0 +1,160 @@
+/*
+ * 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.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.nio.ByteBuffer;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.RADIUS;
+import org.onlab.packet.RADIUSAttribute;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Port;
+import org.onosproject.net.packet.InboundPacket;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+import org.slf4j.Logger;
+
+
+/**
+ * Sample RADIUS Packet Customization.
+ *
+ */
+public class  SamplePacketCustomizer extends PacketCustomizer {
+
+    private final Logger log = getLogger(getClass());
+
+    public SamplePacketCustomizer(CustomizationInfo customInfo) {
+        super(customInfo);
+    }
+
+    /**
+     * Determines if NAS IP Attribute should be updated or not.
+     *
+     * @return true if updating NAS IP is desired
+     */
+    protected boolean updateNasIp() {
+        return true;
+    }
+
+    /**
+     * Customize the packet as per specific Setup or RADIUS
+     * server requirements.
+     *
+     * @param inPkt RADIUS packet to be customized
+     * @param eapPacket Incoming packet containing EAP for which this the
+     *                  RADIUS message is being created
+     * @return Customized RADIUS packet
+     */
+    @Override
+    public RADIUS customizePacket(RADIUS inPkt, InboundPacket eapPacket) {
+        Port p = customInfo.deviceService().getPort(eapPacket.receivedFrom());
+
+        String id = p.annotations().value(AnnotationKeys.PORT_NAME);
+
+        log.info("Customizing packet Port received for {}", id);
+
+        SubscriberAndDeviceInformation subscriber = customInfo.
+                subscriberService().get(id);
+
+        if (subscriber == null) {
+            log.warn("No subscriber found with id {}", id);
+            return inPkt;
+        }
+
+        String nasPortId = subscriber.nasPortId();
+
+        Ethernet ethPkt = eapPacket.parsed();
+        MacAddress srcMac = ethPkt.getSourceMAC();
+
+        // Get the nasId from subscriber service using the Serial Number
+        String serialNo = customInfo.deviceService().getDevice(eapPacket.
+                receivedFrom().deviceId()).serialNumber();
+
+        log.info("SampleRadiusCustomizer serial = {}", serialNo);
+        SubscriberAndDeviceInformation deviceInfo = customInfo.
+                subscriberService().get(serialNo);
+
+        if (deviceInfo == null) {
+            log.warn("No Device found with SN {}", serialNo);
+            return inPkt;
+        }
+        String nodeName = deviceInfo.nasId();
+
+        log.info("Setting nasId={} nasPortId{}", nodeName, nasPortId);
+
+        if (updateNasIp()) {
+            inPkt.updateAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
+                                  deviceInfo.ipAddress().toOctets());
+        }
+
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_CALLING_STATION_ID,
+                srcMac.toBytes());
+
+        // Check value - 16 was used in PoC2, as per PoC3 TS value should be 15
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_PORT_TYPE,
+                ByteBuffer.allocate(4).putInt(15).array());
+
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_PORT,
+                ByteBuffer.allocate(4).putInt((int) p.number().toLong()).array());
+        // Check - If this is needed, worked with this value in PoC2
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_ACCT_SESSION_ID,
+                "023:27:46:00000".getBytes());
+
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_ID,
+                nodeName.getBytes());
+        inPkt.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_PORT_ID,
+                nasPortId.getBytes());
+
+        return inPkt;
+    }
+
+    /**
+     * Customize the Ethernet header as per specific Setup or RADIUS
+     * server requirements.
+     *
+     * @param inPkt Ethernet packet to be changed
+     * @param eapPacket Incoming packet containing EAP for which this the
+     *                  RADIUS message is being created
+     * @return Changed Ethernet packet
+     */
+    @Override
+    public Ethernet customizeEthernetIPHeaders(Ethernet inPkt,
+                                               InboundPacket eapPacket) {
+
+        String serialNo = customInfo.deviceService().getDevice(eapPacket.
+                receivedFrom().deviceId()).serialNumber();
+
+        log.info("SampleRadiusCustomzer customizer serial = {}", serialNo);
+        SubscriberAndDeviceInformation deviceInfo = customInfo.
+                subscriberService().get(serialNo);
+
+        if (deviceInfo == null) {
+            log.warn("No Device found with SN {}", serialNo);
+            return inPkt;
+        }
+
+        inPkt.setSourceMACAddress(deviceInfo.hardwareIdentifier());
+
+        IPv4 ipv4Packet = (IPv4) inPkt.getPayload();
+        ipv4Packet.setSourceAddress(deviceInfo.ipAddress().toString());
+        inPkt.setPayload(ipv4Packet);
+
+        return inPkt;
+    }
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/SocketBasedRadiusCommunicator.java b/app/src/main/java/org/opencord/aaa/impl/SocketBasedRadiusCommunicator.java
new file mode 100755
index 0000000..e2bce35
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/SocketBasedRadiusCommunicator.java
@@ -0,0 +1,210 @@
+/*
+ * 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.impl;
+
+import static org.onosproject.net.packet.PacketPriority.CONTROL;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.RADIUS;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketService;
+import org.opencord.aaa.AaaConfig;
+import org.opencord.aaa.RadiusCommunicator;
+import org.slf4j.Logger;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
+/**
+ * Handles Socket based communication with the RADIUS server.
+ */
+public class SocketBasedRadiusCommunicator 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;
+
+    // Socket used for UDP communications with RADIUS server
+    private DatagramSocket radiusSocket;
+
+    private String radiusHost;
+
+    // Parsed RADIUS server addresses
+    protected InetAddress radiusIpAddress;
+
+    // RADIUS server TCP port number
+    protected short radiusServerPort;
+
+    // Executor for RADIUS communication thread
+    private ExecutorService executor;
+
+    AaaManager aaaManager;
+
+    SocketBasedRadiusCommunicator(ApplicationId appId, PacketService pktService,
+                                  AaaManager aaaManager) {
+        this.appId = appId;
+        this.packetService = pktService;
+        this.aaaManager = aaaManager;
+    }
+
+    @Override
+    public void initializeLocalState(AaaConfig newCfg) {
+        if (newCfg.radiusIp() != null) {
+            radiusIpAddress = newCfg.radiusIp();
+        }
+        radiusServerPort = newCfg.radiusServerUdpPort();
+        radiusHost = newCfg.radiusHostName();
+
+        try {
+            radiusSocket = new DatagramSocket(null);
+            radiusSocket.setReuseAddress(true);
+            radiusSocket.bind(new InetSocketAddress(radiusServerPort));
+        } catch (Exception ex) {
+            log.error("Can't open RADIUS socket", ex);
+        }
+
+        log.info("Remote RADIUS Server: {}:{}", radiusIpAddress, radiusServerPort);
+
+        executor = Executors.newSingleThreadExecutor(
+                new ThreadFactoryBuilder()
+                        .setNameFormat("AAA-radius-%d").build());
+        executor.execute(radiusListener);
+    }
+
+    @Override
+    public void clearLocalState() {
+        radiusSocket.close();
+        executor.shutdownNow();
+    }
+
+    @Override
+    public void deactivate() {
+       clearLocalState();
+    }
+
+    @Override
+    public void requestIntercepts() {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort());
+        packetService.requestPackets(selector.build(), CONTROL, appId);
+    }
+
+    @Override
+    public void withdrawIntercepts() {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort());
+        packetService.cancelPackets(selector.build(), CONTROL, appId);
+    }
+
+    @Override
+    public void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
+        try {
+            final byte[] data = radiusPacket.serialize();
+            final DatagramSocket socket = radiusSocket;
+
+            try {
+                InetAddress address;
+                if (radiusHost != null) {
+                    address = InetAddress.getByName(radiusHost);
+                } else {
+                    address = radiusIpAddress;
+                }
+                DatagramPacket packet =
+                        new DatagramPacket(data, data.length, address, radiusServerPort);
+                if (log.isTraceEnabled()) {
+                    log.trace("Sending packet {} to Radius Server {}:{} using socket",
+                              radiusPacket, address, radiusServerPort);
+                }
+                socket.send(packet);
+            } catch (UnknownHostException uhe) {
+                log.warn("Unable to resolve host {}", radiusHost);
+            }
+        } catch (IOException e) {
+            log.info("Cannot send packet to RADIUS server", e);
+        }
+    }
+
+    @Override
+    public void handlePacketFromServer(PacketContext context) {
+        InboundPacket pkt = context.inPacket();
+        Ethernet ethPkt = pkt.parsed();
+        if (log.isTraceEnabled() && ethPkt.getEtherType() != Ethernet.TYPE_LLDP
+                && ethPkt.getEtherType() != Ethernet.TYPE_BSN) {
+            log.trace("Skipping Ethernet packet type {}",
+                      EthType.EtherType.lookup(ethPkt.getEtherType()));
+        }
+    }
+
+    class RadiusListener implements Runnable {
+
+        @Override
+        public void run() {
+            boolean done = false;
+            int packetNumber = 1;
+
+            log.info("UDP listener thread starting up");
+            RADIUS inboundRadiusPacket;
+            while (!done) {
+                try {
+                    byte[] packetBuffer = new byte[RADIUS.RADIUS_MAX_LENGTH];
+                    DatagramPacket inboundBasePacket =
+                            new DatagramPacket(packetBuffer, packetBuffer.length);
+                    DatagramSocket socket = radiusSocket;
+                    socket.receive(inboundBasePacket);
+                    log.debug("Packet #{} received", packetNumber++);
+                    try {
+                        inboundRadiusPacket =
+                                RADIUS.deserializer()
+                                        .deserialize(inboundBasePacket.getData(),
+                                                0,
+                                                inboundBasePacket.getLength());
+                        aaaManager.handleRadiusPacket(inboundRadiusPacket);
+                    } catch (DeserializationException dex) {
+                        log.error("Cannot deserialize packet", dex);
+                    } catch (StateMachineException sme) {
+                        log.error("Illegal state machine operation", sme);
+                    }
+
+                } catch (IOException e) {
+                    log.info("Socket was closed, exiting listener thread");
+                    done = true;
+                }
+            }
+        }
+    }
+
+    RadiusListener radiusListener = new RadiusListener();
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/StateMachine.java b/app/src/main/java/org/opencord/aaa/impl/StateMachine.java
new file mode 100644
index 0000000..f9e5f25
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/StateMachine.java
@@ -0,0 +1,572 @@
+/*
+ * 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.impl;
+
+import com.google.common.collect.Maps;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.ConnectPoint;
+import org.opencord.aaa.AuthenticationEvent;
+import org.opencord.aaa.StateMachineDelegate;
+import org.slf4j.Logger;
+
+import java.util.Map;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * AAA Finite State Machine.
+ */
+
+class StateMachine {
+    //INDEX to identify the state in the transition table
+    static final int STATE_IDLE = 0;
+    static final int STATE_STARTED = 1;
+    static final int STATE_PENDING = 2;
+    static final int STATE_AUTHORIZED = 3;
+    static final int STATE_UNAUTHORIZED = 4;
+
+    //INDEX to identify the transition in the transition table
+    static final int TRANSITION_START = 0; // --> started
+    static final int TRANSITION_REQUEST_ACCESS = 1;
+    static final int TRANSITION_AUTHORIZE_ACCESS = 2;
+    static final int TRANSITION_DENY_ACCESS = 3;
+    static final int TRANSITION_LOGOFF = 4;
+
+    private static int identifier = -1;
+    private byte challengeIdentifier;
+    private byte[] challengeState;
+    private byte[] username;
+    private byte[] requestAuthenticator;
+
+    // Supplicant connectivity info
+    private ConnectPoint supplicantConnectpoint;
+    private MacAddress supplicantAddress;
+    private short vlanId;
+    private byte priorityCode;
+
+    private String sessionId = null;
+
+    private final Logger log = getLogger(getClass());
+
+
+    private State[] states = {
+            new Idle(), new Started(), new Pending(), new Authorized(), new Unauthorized()
+    };
+
+
+    //State transition table
+    /*
+
+                state       IDLE    |   STARTED         |   PENDING         |   AUTHORIZED  |   UNAUTHORIZED
+             ////
+       input
+       ----------------------------------------------------------------------------------------------------
+
+       START                STARTED |   _               |   _               |   STARTED     |   STARTED
+
+       REQUEST_ACCESS       _       |   PENDING         |   _               |   _           |   _
+
+       AUTHORIZE_ACCESS     _       |   _               |   AUTHORIZED      |   _           |   _
+
+       DENY_ACCESS          _       |   -               |   UNAUTHORIZED    |   _           |   _
+
+       LOGOFF               _       |   _               |   _               |   IDLE        |   IDLE
+     */
+
+    private int[] idleTransition =
+            {STATE_STARTED, STATE_IDLE, STATE_IDLE, STATE_IDLE, STATE_IDLE};
+    private int[] startedTransition =
+            {STATE_STARTED, STATE_PENDING, STATE_STARTED, STATE_STARTED, STATE_STARTED};
+    private int[] pendingTransition =
+            {STATE_PENDING, STATE_PENDING, STATE_AUTHORIZED, STATE_UNAUTHORIZED, STATE_PENDING};
+    private int[] authorizedTransition =
+            {STATE_STARTED, STATE_AUTHORIZED, STATE_AUTHORIZED, STATE_AUTHORIZED, STATE_IDLE};
+    private int[] unauthorizedTransition =
+            {STATE_STARTED, STATE_UNAUTHORIZED, STATE_UNAUTHORIZED, STATE_UNAUTHORIZED, STATE_IDLE};
+
+    //THE TRANSITION TABLE
+    private int[][] transition =
+            {idleTransition, startedTransition, pendingTransition, authorizedTransition,
+                    unauthorizedTransition};
+
+    private int currentState = STATE_IDLE;
+
+    // Maps of state machines. Each state machine is represented by an
+    // unique identifier on the switch: dpid + port number
+    private static Map<String, StateMachine> sessionIdMap;
+    private static Map<Integer, StateMachine> identifierMap;
+
+    private static StateMachineDelegate delegate;
+
+    public static void initializeMaps() {
+        sessionIdMap = Maps.newConcurrentMap();
+        identifierMap = Maps.newConcurrentMap();
+        identifier = -1;
+    }
+
+    public static void destroyMaps() {
+        sessionIdMap = null;
+        identifierMap = null;
+    }
+
+    public static void setDelegate(StateMachineDelegate delegate) {
+        StateMachine.delegate = delegate;
+    }
+
+    public static void unsetDelegate(StateMachineDelegate delegate) {
+        if (StateMachine.delegate == delegate) {
+            StateMachine.delegate = null;
+        }
+    }
+
+    public static Map<String, StateMachine> sessionIdMap() {
+        return sessionIdMap;
+    }
+
+    public static StateMachine lookupStateMachineById(byte identifier) {
+        return identifierMap.get((int) identifier);
+    }
+
+    public static StateMachine lookupStateMachineBySessionId(String sessionId) {
+        return sessionIdMap.get(sessionId);
+    }
+
+    public static void deleteStateMachineMapping(StateMachine machine) {
+        identifierMap.entrySet().removeIf(e -> e.getValue().equals(machine));
+    }
+
+    /**
+     * Deletes authentication state machine records for a given MAC address.
+     * @param mac mac address of the suppliant who's state machine should be removed
+     */
+    public static void deleteByMac(MacAddress mac) {
+
+        // Walk the map from session IDs to state machines looking for a MAC match
+        for (Map.Entry<String, StateMachine> e : sessionIdMap.entrySet()) {
+
+            // If a MAC match is found then delete the entry from the session ID
+            // and identifier map as well as call delete identifier to clean up
+            // the identifier bit set.
+            if (e.getValue() != null && e.getValue().supplicantAddress != null &&
+                   e.getValue().supplicantAddress.equals(mac)) {
+                sessionIdMap.remove(e.getValue().sessionId);
+                if (e.getValue().identifier != -1) {
+                    deleteStateMachineMapping(e.getValue());
+                }
+                break;
+            }
+        }
+    }
+
+    /**
+     * Creates a new StateMachine with the given session ID.
+     *
+     * @param sessionId session Id represented by the switch dpid +  port number
+     */
+    public StateMachine(String sessionId) {
+        log.info("Creating a new state machine for {}", sessionId);
+        this.sessionId = sessionId;
+        sessionIdMap.put(sessionId, this);
+    }
+
+    /**
+     * Gets the connect point for the supplicant side.
+     *
+     * @return supplicant connect point
+     */
+    public ConnectPoint supplicantConnectpoint() {
+        return supplicantConnectpoint;
+    }
+
+    /**
+     * Sets the supplicant side connect point.
+     *
+     * @param supplicantConnectpoint supplicant select point.
+     */
+    public void setSupplicantConnectpoint(ConnectPoint supplicantConnectpoint) {
+        this.supplicantConnectpoint = supplicantConnectpoint;
+    }
+
+    /**
+     * Gets the MAC address of the supplicant.
+     *
+     * @return supplicant MAC address
+     */
+    public MacAddress supplicantAddress() {
+        return supplicantAddress;
+    }
+
+    /**
+     * Sets the supplicant MAC address.
+     *
+     * @param supplicantAddress new supplicant MAC address
+     */
+    public void setSupplicantAddress(MacAddress supplicantAddress) {
+        this.supplicantAddress = supplicantAddress;
+    }
+
+    /**
+     * Gets the client's Vlan ID.
+     *
+     * @return client vlan ID
+     */
+    public short vlanId() {
+        return vlanId;
+    }
+
+    /**
+     * Sets the client's vlan ID.
+     *
+     * @param vlanId new client vlan ID
+     */
+    public void setVlanId(short vlanId) {
+        this.vlanId = vlanId;
+    }
+
+    /**
+     * Gets the client's priority Code.
+     *
+     * @return client Priority code
+     */
+    public byte priorityCode() {
+        return priorityCode;
+    }
+
+    /**
+     * Sets the client's priority Code.
+     *
+     * @param priorityCode new client priority Code
+     */
+    public void setPriorityCode(byte priorityCode) {
+        this.priorityCode = priorityCode;
+    }
+
+    /**
+     * Gets the client id that is requesting for access.
+     *
+     * @return The client id.
+     */
+    public String sessionId() {
+        return this.sessionId;
+    }
+
+    /**
+     * Set the challenge identifier and the state issued by the RADIUS.
+     *
+     * @param challengeIdentifier The challenge identifier set into the EAP packet from the RADIUS message.
+     * @param challengeState      The challenge state from the RADIUS.
+     */
+    protected void setChallengeInfo(byte challengeIdentifier, byte[] challengeState) {
+        this.challengeIdentifier = challengeIdentifier;
+        this.challengeState = challengeState;
+    }
+
+    /**
+     * Set the challenge identifier issued by the RADIUS on the access challenge request.
+     *
+     * @param challengeIdentifier The challenge identifier set into the EAP packet from the RADIUS message.
+     */
+    protected void setChallengeIdentifier(byte challengeIdentifier) {
+        log.info("Set Challenge Identifier to {}", challengeIdentifier);
+        this.challengeIdentifier = challengeIdentifier;
+    }
+
+    /**
+     * Gets the challenge EAP identifier set by the RADIUS.
+     *
+     * @return The challenge EAP identifier.
+     */
+    protected byte challengeIdentifier() {
+        return this.challengeIdentifier;
+    }
+
+
+    /**
+     * Set the challenge state info issued by the RADIUS.
+     *
+     * @param challengeState The challenge state from the RADIUS.
+     */
+    protected void setChallengeState(byte[] challengeState) {
+        log.info("Set Challenge State");
+        this.challengeState = challengeState;
+    }
+
+    /**
+     * Gets the challenge state set by the RADIUS.
+     *
+     * @return The challenge state.
+     */
+    protected byte[] challengeState() {
+        return this.challengeState;
+    }
+
+    /**
+     * Set the username.
+     *
+     * @param username The username sent to the RADIUS upon access request.
+     */
+    protected void setUsername(byte[] username) {
+        this.username = username;
+    }
+
+    /**
+     * Gets the username.
+     *
+     * @return The requestAuthenticator.
+     */
+    protected byte[] requestAuthenticator() {
+        return this.requestAuthenticator;
+    }
+
+    /**
+     * Sets the authenticator.
+     *
+     * @param authenticator The username sent to the RADIUS upon access request.
+     */
+    protected void setRequestAuthenticator(byte[] authenticator) {
+        this.requestAuthenticator = authenticator;
+    }
+
+
+    /**
+     * Gets the username.
+     *
+     * @return The username.
+     */
+    protected byte[] username() {
+        return this.username;
+    }
+
+    /**
+     * Return the identifier of the state machine.
+     *
+     * @return The state machine identifier.
+     */
+    public synchronized byte identifier() {
+        identifier = (identifier + 1) % 255;
+        identifierMap.put(identifier, this);
+        return (byte) identifier;
+    }
+
+    /**
+     * Move to the next state.
+     *
+     * @param msg message
+     */
+    private void next(int msg) {
+        currentState = transition[currentState][msg];
+        log.info("Current State " + currentState);
+    }
+
+    /**
+     * Client has requested the start action to allow network access.
+     *
+     * @throws StateMachineException if authentication protocol is violated
+     */
+    public void start() throws StateMachineException {
+        states[currentState].start();
+
+        delegate.notify(new AuthenticationEvent(
+                AuthenticationEvent.Type.STARTED, supplicantConnectpoint));
+
+        //move to the next state
+        next(TRANSITION_START);
+        identifier = this.identifier();
+    }
+
+    /**
+     * An Identification information has been sent by the supplicant.
+     * Move to the next state if possible.
+     *
+     * @throws StateMachineException if authentication protocol is violated
+     */
+    public void requestAccess() throws StateMachineException {
+        states[currentState].requestAccess();
+
+        delegate.notify(new AuthenticationEvent(
+                AuthenticationEvent.Type.REQUESTED, supplicantConnectpoint));
+
+        //move to the next state
+        next(TRANSITION_REQUEST_ACCESS);
+    }
+
+    /**
+     * RADIUS has accepted the identification.
+     * Move to the next state if possible.
+     *
+     * @throws StateMachineException if authentication protocol is violated
+     */
+    public void authorizeAccess() throws StateMachineException {
+        states[currentState].radiusAccepted();
+        //move to the next state
+        next(TRANSITION_AUTHORIZE_ACCESS);
+
+        delegate.notify(new AuthenticationEvent(
+                AuthenticationEvent.Type.APPROVED, supplicantConnectpoint));
+
+        // Clear mapping
+        deleteStateMachineMapping(this);
+    }
+
+    /**
+     * RADIUS has denied the identification.
+     * Move to the next state if possible.
+     *
+     * @throws StateMachineException if authentication protocol is violated
+     */
+    public void denyAccess() throws StateMachineException {
+        states[currentState].radiusDenied();
+        //move to the next state
+        next(TRANSITION_DENY_ACCESS);
+
+        delegate.notify(new AuthenticationEvent(
+                AuthenticationEvent.Type.DENIED, supplicantConnectpoint));
+
+        // Clear mappings
+        deleteStateMachineMapping(this);
+    }
+
+    /**
+     * Logoff request has been requested.
+     * Move to the next state if possible.
+     *
+     * @throws StateMachineException if authentication protocol is violated
+     */
+    public void logoff() throws StateMachineException {
+        states[currentState].logoff();
+        //move to the next state
+        next(TRANSITION_LOGOFF);
+    }
+
+    /**
+     * Gets the current state.
+     *
+     * @return The current state. Could be STATE_IDLE, STATE_STARTED, STATE_PENDING, STATE_AUTHORIZED,
+     * STATE_UNAUTHORIZED.
+     */
+    public int state() {
+        return currentState;
+    }
+
+    @Override
+    public String toString() {
+        return ("sessionId: " + this.sessionId) + "\t" + ("identifier: " + this.identifier) + "\t" +
+                ("state: " + this.currentState);
+    }
+
+    abstract class State {
+        private final Logger log = getLogger(getClass());
+
+        private String name = "State";
+
+        public void start() throws StateMachineInvalidTransitionException {
+            log.warn("START transition from this state is not allowed.");
+        }
+
+        public void requestAccess() throws StateMachineInvalidTransitionException {
+            log.warn("REQUEST ACCESS transition from this state is not allowed.");
+        }
+
+        public void radiusAccepted() throws StateMachineInvalidTransitionException {
+            log.warn("AUTHORIZE ACCESS transition from this state is not allowed.");
+        }
+
+        public void radiusDenied() throws StateMachineInvalidTransitionException {
+            log.warn("DENY ACCESS transition from this state is not allowed.");
+        }
+
+        public void logoff() throws StateMachineInvalidTransitionException {
+            log.warn("LOGOFF transition from this state is not allowed.");
+        }
+    }
+
+    /**
+     * Idle state: supplicant is logged of from the network.
+     */
+    class Idle extends State {
+        private final Logger log = getLogger(getClass());
+        private String name = "IDLE_STATE";
+
+        public void start() {
+            log.info("Moving from IDLE state to STARTED state.");
+        }
+    }
+
+    /**
+     * Started state: supplicant has entered the network and informed the authenticator.
+     */
+    class Started extends State {
+        private final Logger log = getLogger(getClass());
+        private String name = "STARTED_STATE";
+
+        public void requestAccess() {
+            log.info("Moving from STARTED state to PENDING state.");
+        }
+    }
+
+    /**
+     * Pending state: supplicant has been identified by the authenticator but has not access yet.
+     */
+    class Pending extends State {
+        private final Logger log = getLogger(getClass());
+        private String name = "PENDING_STATE";
+
+        public void radiusAccepted() {
+            log.info("Moving from PENDING state to AUTHORIZED state.");
+        }
+
+        public void radiusDenied() {
+            log.info("Moving from PENDING state to UNAUTHORIZED state.");
+        }
+    }
+
+    /**
+     * Authorized state: supplicant port has been accepted, access is granted.
+     */
+    class Authorized extends State {
+        private final Logger log = getLogger(getClass());
+        private String name = "AUTHORIZED_STATE";
+
+        public void start() {
+            log.info("Moving from AUTHORIZED state to STARTED state.");
+        }
+
+        public void logoff() {
+
+            log.info("Moving from AUTHORIZED state to IDLE state.");
+        }
+    }
+
+    /**
+     * Unauthorized state: supplicant port has been rejected, access is denied.
+     */
+    class Unauthorized extends State {
+        private final Logger log = getLogger(getClass());
+        private String name = "UNAUTHORIZED_STATE";
+
+        public void start() {
+            log.info("Moving from UNAUTHORIZED state to STARTED state.");
+        }
+
+        public void logoff() {
+            log.info("Moving from UNAUTHORIZED state to IDLE state.");
+        }
+    }
+
+
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/StateMachineException.java b/app/src/main/java/org/opencord/aaa/impl/StateMachineException.java
new file mode 100644
index 0000000..6dd7bb4
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/StateMachineException.java
@@ -0,0 +1,27 @@
+/*
+ * 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.impl;
+
+/**
+ * Exception for the State Machine.
+ */
+class StateMachineException extends Exception {
+    public StateMachineException(String message) {
+        super(message);
+
+    }
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/StateMachineInvalidTransitionException.java b/app/src/main/java/org/opencord/aaa/impl/StateMachineInvalidTransitionException.java
new file mode 100644
index 0000000..6ccd3fc
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/StateMachineInvalidTransitionException.java
@@ -0,0 +1,26 @@
+/*
+ * 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.impl;
+
+/**
+ * Exception raised when the transition from one state to another is invalid.
+ */
+class StateMachineInvalidTransitionException extends StateMachineException {
+    public StateMachineInvalidTransitionException(String message) {
+        super(message);
+    }
+}
diff --git a/app/src/main/java/org/opencord/aaa/impl/package-info.java b/app/src/main/java/org/opencord/aaa/impl/package-info.java
new file mode 100644
index 0000000..7737b52
--- /dev/null
+++ b/app/src/main/java/org/opencord/aaa/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-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.
+ */
+
+/**
+ * AAA implmentation.
+ */
+package org.opencord.aaa.impl;
diff --git a/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..b83f750
--- /dev/null
+++ b/app/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright 2016-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.
+  -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.opencord.aaa.impl.AaaShowUsersCommand"/>
+        </command>
+        <command>
+            <action class="org.opencord.aaa.impl.AaaResetDeviceCommand"/>
+        </command>
+    </command-bundle>
+</blueprint>
diff --git a/app/src/test/java/org/opencord/aaa/impl/AaaIntegrationTest.java b/app/src/test/java/org/opencord/aaa/impl/AaaIntegrationTest.java
new file mode 100644
index 0000000..8ded2f8
--- /dev/null
+++ b/app/src/test/java/org/opencord/aaa/impl/AaaIntegrationTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2015-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.impl;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.packet.EAP;
+import org.onlab.packet.EAPOL;
+import org.onlab.packet.Ethernet;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.opencord.aaa.AaaConfig;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Set of tests of the ONOS application component. These use an existing RADIUS
+ * server and sends live packets over the network to it.
+ */
+@Ignore ("This should not be run as part of the standard build")
+public class AaaIntegrationTest extends AaaTestBase {
+
+    private AaaManager aaa;
+
+    /**
+     * Mocks the network config registry.
+     */
+    @SuppressWarnings("unchecked")
+    static final class TestNetworkConfigRegistry
+            extends NetworkConfigRegistryAdapter {
+        @Override
+        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+            return (C) new AaaConfig();
+        }
+    }
+
+    /**
+     * Sets up the services required by the AAA application.
+     */
+    @Before
+    public void setUp() {
+        aaa = new AaaManager();
+        aaa.netCfgService = new TestNetworkConfigRegistry();
+        aaa.coreService = new CoreServiceAdapter();
+        aaa.packetService = new MockPacketService();
+        aaa.activate();
+    }
+
+    /**
+     * Fetches the sent packet at the given index. The requested packet
+     * must be the last packet on the list.
+     *
+     * @param index index into sent packets array
+     * @return packet
+     */
+    private Ethernet fetchPacket(int index) {
+        for (int iteration = 0; iteration < 20; iteration++) {
+            if (savedPackets.size() > index) {
+                return (Ethernet) savedPackets.get(index);
+            } else {
+                try {
+                    Thread.sleep(250);
+                } catch (Exception ex) {
+                    return null;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Tests the authentication path through the AAA application by sending
+     * packets to the RADIUS server and checking the state machine
+     * transitions.
+     *
+     * @throws Exception when an unhandled error occurs
+     */
+    @Test
+    public void testAuthentication()  throws Exception {
+
+        //  (1) Supplicant start up
+
+        Ethernet startPacket = constructSupplicantStartPacket();
+        sendPacket(startPacket);
+
+        Ethernet responsePacket = fetchPacket(0);
+        assertThat(responsePacket, notNullValue());
+        checkRadiusPacket(aaa, responsePacket, EAP.REQUEST);
+
+        //  (2) Supplicant identify
+
+        Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
+        sendPacket(identifyPacket);
+
+        //  State machine should have been created by now
+
+        StateMachine stateMachine =
+                StateMachine.lookupStateMachineBySessionId(SESSION_ID);
+        assertThat(stateMachine, notNullValue());
+        assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
+
+        // (3) RADIUS MD5 challenge
+
+        Ethernet radiusChallengeMD5Packet = fetchPacket(1);
+        assertThat(radiusChallengeMD5Packet, notNullValue());
+        checkRadiusPacket(aaa, radiusChallengeMD5Packet, EAP.REQUEST);
+
+
+        // (4) Supplicant MD5 response
+
+        Ethernet md5RadiusPacket =
+                constructSupplicantIdentifyPacket(stateMachine,
+                                                  EAP.ATTR_MD5,
+                                                  stateMachine.challengeIdentifier(),
+                                                  radiusChallengeMD5Packet);
+        sendPacket(md5RadiusPacket);
+
+
+        // (5) RADIUS Success
+
+        Ethernet successRadiusPacket = fetchPacket(2);
+        assertThat(successRadiusPacket, notNullValue());
+        EAPOL successEapol = (EAPOL) successRadiusPacket.getPayload();
+        EAP successEap = (EAP) successEapol.getPayload();
+        assertThat(successEap.getCode(), is(EAP.SUCCESS));
+
+        //  State machine should be in authorized state
+
+        assertThat(stateMachine, notNullValue());
+        assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
+
+    }
+
+}
+
diff --git a/app/src/test/java/org/opencord/aaa/impl/AaaManagerTest.java b/app/src/test/java/org/opencord/aaa/impl/AaaManagerTest.java
new file mode 100644
index 0000000..8827c1a
--- /dev/null
+++ b/app/src/test/java/org/opencord/aaa/impl/AaaManagerTest.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2015-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.impl;
+
+import com.google.common.base.Charsets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.EAP;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.RADIUS;
+import org.onlab.packet.RADIUSAttribute;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.event.DefaultEventSinkRegistry;
+import org.onosproject.event.Event;
+import org.onosproject.event.EventDeliveryService;
+import org.onosproject.event.EventSink;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.NetworkConfigRegistryAdapter;
+import org.onosproject.net.packet.InboundPacket;
+import org.opencord.aaa.AaaConfig;
+
+import java.lang.reflect.Field;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import static com.google.common.base.Preconditions.checkState;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Set of tests of the ONOS application component.
+ */
+public class AaaManagerTest extends AaaTestBase {
+
+    static final String BAD_IP_ADDRESS = "198.51.100.0";
+
+    private AaaManager aaaManager;
+
+    class AaaManagerWithoutRadiusServer extends AaaManager {
+        protected void sendRadiusPacket(RADIUS radiusPacket, InboundPacket inPkt) {
+            savePacket(radiusPacket);
+        }
+    }
+
+    /**
+     * Mocks the AAAConfig class to force usage of an unroutable address for the
+     * RADIUS server.
+     */
+    static class MockAaaConfig extends AaaConfig {
+        @Override
+        public InetAddress radiusIp() {
+            try {
+                return InetAddress.getByName(BAD_IP_ADDRESS);
+            } catch (UnknownHostException ex) {
+                // can't happen
+                throw new IllegalStateException(ex);
+            }
+        }
+    }
+
+    /**
+     * Mocks the network config registry.
+     */
+    @SuppressWarnings("unchecked")
+    private static final class TestNetworkConfigRegistry
+            extends NetworkConfigRegistryAdapter {
+        @Override
+        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+            AaaConfig aaaConfig = new MockAaaConfig();
+            return (C) aaaConfig;
+        }
+    }
+
+    public static class TestEventDispatcher extends DefaultEventSinkRegistry
+            implements EventDeliveryService {
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public synchronized void post(Event event) {
+            EventSink sink = getSink(event.getClass());
+            checkState(sink != null, "No sink for event %s", event);
+            sink.process(event);
+        }
+
+        @Override
+        public void setDispatchTimeLimit(long millis) {
+        }
+
+        @Override
+        public long getDispatchTimeLimit() {
+            return 0;
+        }
+    }
+
+    /**
+     * Constructs an Ethernet packet containing a RADIUS challenge
+     * packet.
+     *
+     * @param challengeCode code to use in challenge packet
+     * @param challengeType type to use in challenge packet
+     * @return Ethernet packet
+     */
+    private RADIUS constructRadiusCodeAccessChallengePacket(byte challengeCode, byte challengeType) {
+
+        String challenge = "12345678901234567";
+
+        EAP eap = new EAP(challengeType, (byte) 1, challengeType,
+                          challenge.getBytes(Charsets.US_ASCII));
+        eap.setIdentifier((byte) 1);
+
+        RADIUS radius = new RADIUS();
+        radius.setCode(challengeCode);
+
+        radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
+                            challenge.getBytes(Charsets.US_ASCII));
+
+        radius.setPayload(eap);
+        radius.setAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE,
+                            eap.serialize());
+
+        return radius;
+    }
+
+    public static void injectEventDispatcher(Object manager, EventDeliveryService svc) {
+        Class mc = manager.getClass();
+        for (Field f : mc.getSuperclass().getDeclaredFields()) {
+            if (f.getType().equals(EventDeliveryService.class)) {
+                try {
+                    TestUtils.setField(manager, f.getName(), svc);
+                } catch (TestUtils.TestUtilsException e) {
+                    throw new IllegalArgumentException("Unable to inject reference", e);
+                }
+                break;
+            }
+        }
+    }
+
+    /**
+     * Sets up the services required by the AAA application.
+     */
+    @Before
+    public void setUp() {
+        aaaManager = new AaaManagerWithoutRadiusServer();
+        aaaManager.netCfgService = new TestNetworkConfigRegistry();
+        aaaManager.coreService = new CoreServiceAdapter();
+        aaaManager.packetService = new MockPacketService();
+        aaaManager.deviceService = new TestDeviceService();
+        aaaManager.sadisService = new MockSadisService();
+        TestUtils.setField(aaaManager, "eventDispatcher", new TestEventDispatcher());
+        aaaManager.activate();
+    }
+
+    /**
+     * Tears down the AAA application.
+     */
+    @After
+    public void tearDown() {
+        aaaManager.deactivate();
+    }
+
+    /**
+     * Extracts the RADIUS packet from a packet sent by the supplicant.
+     *
+     * @param radius RADIUS packet sent by the supplicant
+     * @throws DeserializationException if deserialization of the packet contents
+     *         fails.
+     */
+    private void checkRadiusPacketFromSupplicant(RADIUS radius)
+            throws DeserializationException {
+        assertThat(radius, notNullValue());
+
+        EAP eap = radius.decapsulateMessage();
+        assertThat(eap, notNullValue());
+    }
+
+    /**
+     * Fetches the sent packet at the given index. The requested packet
+     * must be the last packet on the list.
+     *
+     * @param index index into sent packets array
+     * @return packet
+     */
+    private BasePacket fetchPacket(int index) {
+        BasePacket packet = savedPackets.get(index);
+        assertThat(packet, notNullValue());
+        return packet;
+    }
+
+    /**
+     * Tests the authentication path through the AAA application.
+     *
+     * @throws DeserializationException if packed deserialization fails.
+     */
+    @Test
+    public void testAuthentication()  throws Exception {
+
+        //  (1) Supplicant start up
+
+        Ethernet startPacket = constructSupplicantStartPacket();
+        sendPacket(startPacket);
+
+        Ethernet responsePacket = (Ethernet) fetchPacket(0);
+        checkRadiusPacket(aaaManager, responsePacket, EAP.ATTR_IDENTITY);
+
+        //  (2) Supplicant identify
+
+        Ethernet identifyPacket = constructSupplicantIdentifyPacket(null, EAP.ATTR_IDENTITY, (byte) 1, null);
+        sendPacket(identifyPacket);
+
+        RADIUS radiusIdentifyPacket = (RADIUS) fetchPacket(1);
+
+        checkRadiusPacketFromSupplicant(radiusIdentifyPacket);
+
+        assertThat(radiusIdentifyPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
+        assertThat(new String(radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME).getValue()),
+                   is("testuser"));
+
+        IpAddress nasIp =
+                IpAddress.valueOf(IpAddress.Version.INET,
+                                  radiusIdentifyPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP)
+                                          .getValue());
+        assertThat(nasIp.toString(), is(aaaManager.nasIpAddress.getHostAddress()));
+
+        //  State machine should have been created by now
+
+        StateMachine stateMachine =
+                StateMachine.lookupStateMachineBySessionId(SESSION_ID);
+        assertThat(stateMachine, notNullValue());
+        assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
+
+        // (3) RADIUS MD5 challenge
+
+        RADIUS radiusCodeAccessChallengePacket =
+                constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_CHALLENGE, EAP.ATTR_MD5);
+        aaaManager.handleRadiusPacket(radiusCodeAccessChallengePacket);
+
+        Ethernet radiusChallengeMD5Packet = (Ethernet) fetchPacket(2);
+        checkRadiusPacket(aaaManager, radiusChallengeMD5Packet, EAP.ATTR_MD5);
+
+        // (4) Supplicant MD5 response
+
+        Ethernet md5RadiusPacket =
+                constructSupplicantIdentifyPacket(stateMachine,
+                                                  EAP.ATTR_MD5,
+                                                  stateMachine.challengeIdentifier(),
+                                                  radiusChallengeMD5Packet);
+        sendPacket(md5RadiusPacket);
+
+        RADIUS responseMd5RadiusPacket = (RADIUS) fetchPacket(3);
+
+        checkRadiusPacketFromSupplicant(responseMd5RadiusPacket);
+        assertThat(responseMd5RadiusPacket.getIdentifier(), is((byte) 3));
+        assertThat(responseMd5RadiusPacket.getCode(), is(RADIUS.RADIUS_CODE_ACCESS_REQUEST));
+
+        //  State machine should be in pending state
+
+        assertThat(stateMachine, notNullValue());
+        assertThat(stateMachine.state(), is(StateMachine.STATE_PENDING));
+
+        // (5) RADIUS Success
+
+        RADIUS successPacket =
+                constructRadiusCodeAccessChallengePacket(RADIUS.RADIUS_CODE_ACCESS_ACCEPT, EAP.SUCCESS);
+        aaaManager.handleRadiusPacket((successPacket));
+        Ethernet supplicantSuccessPacket = (Ethernet) fetchPacket(4);
+
+        checkRadiusPacket(aaaManager, supplicantSuccessPacket, EAP.SUCCESS);
+
+        //  State machine should be in authorized state
+
+        assertThat(stateMachine, notNullValue());
+        assertThat(stateMachine.state(), is(StateMachine.STATE_AUTHORIZED));
+
+    }
+
+    /**
+     * Tests the default configuration.
+     */
+    @Test
+    public void testConfig() {
+        assertThat(aaaManager.nasIpAddress.getHostAddress(), is(AaaConfig.DEFAULT_NAS_IP));
+        assertThat(aaaManager.nasMacAddress, is(AaaConfig.DEFAULT_NAS_MAC));
+        assertThat(aaaManager.radiusIpAddress.getHostAddress(), is(BAD_IP_ADDRESS));
+        assertThat(aaaManager.radiusMacAddress, is(AaaConfig.DEFAULT_RADIUS_MAC));
+    }
+}
diff --git a/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java b/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java
new file mode 100644
index 0000000..2e21ea3
--- /dev/null
+++ b/app/src/test/java/org/opencord/aaa/impl/AaaTestBase.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2015-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.impl;
+
+import org.onlab.packet.BasePacket;
+import org.onlab.packet.EAP;
+import org.onlab.packet.EAPOL;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+
+import org.onosproject.net.Annotations;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Element;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.packet.DefaultInboundPacket;
+import org.onosproject.net.packet.DefaultPacketContext;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketServiceAdapter;
+
+import org.opencord.sadis.BandwidthProfileInformation;
+import org.opencord.sadis.BaseInformationService;
+import org.opencord.sadis.SadisService;
+import org.opencord.sadis.SubscriberAndDeviceInformation;
+
+import java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.onosproject.net.NetTestTools.connectPoint;
+
+/**
+ * Common methods for AAA app testing.
+ */
+public class AaaTestBase {
+
+    MacAddress clientMac = MacAddress.valueOf("1a:1a:1a:1a:1a:1a");
+    MacAddress serverMac = MacAddress.valueOf("2a:2a:2a:2a:2a:2a");
+
+    // Our session id will be the device ID ("of:1") with the port ("1") concatenated
+    static final String SESSION_ID = "of:11";
+
+    List<BasePacket> savedPackets = new LinkedList<>();
+    PacketProcessor packetProcessor;
+
+    /**
+     * Saves the given packet onto the saved packets list.
+     *
+     * @param packet packet to save
+     */
+    void savePacket(BasePacket packet) {
+        savedPackets.add(packet);
+    }
+
+    /**
+     * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
+     */
+    class MockPacketService extends PacketServiceAdapter {
+
+        @Override
+        public void addProcessor(PacketProcessor processor, int priority) {
+            packetProcessor = processor;
+        }
+
+        @Override
+        public void emit(OutboundPacket packet) {
+            try {
+                Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
+                                                                   0, packet.data().array().length);
+                savePacket(eth);
+            } catch (Exception e) {
+                fail(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Mocks the DeviceService.
+     */
+    final class TestDeviceService extends DeviceServiceAdapter {
+        @Override
+        public Port getPort(ConnectPoint cp) {
+            return new MockPort();
+        }
+    }
+    private class  MockPort implements Port {
+
+        @Override
+        public boolean isEnabled() {
+            return true;
+        }
+        public long portSpeed() {
+            return 1000;
+        }
+        public Element element() {
+            return null;
+        }
+        public PortNumber number() {
+            return null;
+        }
+        public Annotations annotations() {
+            return new MockAnnotations();
+        }
+        public Type type() {
+            return Port.Type.FIBER;
+        }
+
+        private class MockAnnotations implements Annotations {
+
+            @Override
+            public String value(String val) {
+                return "PON 1/1";
+            }
+            public Set<String> keys() {
+                return null;
+            }
+        }
+    }
+
+    private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
+
+        MockSubscriberAndDeviceInformation(String id, VlanId ctag,
+                                           VlanId stag, String nasPortId,
+                                           String circuitId, MacAddress hardId,
+                                           Ip4Address ipAddress) {
+            this.setCTag(ctag);
+            this.setHardwareIdentifier(hardId);
+            this.setId(id);
+            this.setIPAddress(ipAddress);
+            this.setSTag(stag);
+            this.setNasPortId(nasPortId);
+            this.setCircuitId(circuitId);
+        }
+    }
+
+    final class MockSadisService implements SadisService {
+
+        @Override
+        public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
+            return new MockSubService();
+        }
+
+        @Override
+        public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
+            return null;
+        }
+    }
+
+    final class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
+        private final VlanId clientCtag = VlanId.vlanId((short) 999);
+        private final VlanId clientStag = VlanId.vlanId((short) 111);
+        private final String clientNasPortId = "PON 1/1";
+        private final String clientCircuitId = "CIR-PON 1/1";
+
+        MockSubscriberAndDeviceInformation sub =
+                new MockSubscriberAndDeviceInformation(clientNasPortId, clientCtag,
+                        clientStag, clientNasPortId, clientCircuitId, null, null);
+        @Override
+        public SubscriberAndDeviceInformation get(String id) {
+
+                return  sub;
+
+        }
+
+        @Override
+        public void invalidateAll() {}
+        public void invalidateId(String id) {}
+        public SubscriberAndDeviceInformation getfromCache(String id) {
+            return null;
+        }
+    }
+    /**
+     * Mocks the DefaultPacketContext.
+     */
+    final class TestPacketContext extends DefaultPacketContext {
+
+        private TestPacketContext(long time, InboundPacket inPkt,
+                                  OutboundPacket outPkt, boolean block) {
+            super(time, inPkt, outPkt, block);
+        }
+
+        @Override
+        public void send() {
+            // We don't send anything out.
+        }
+    }
+
+    /**
+     * Sends an Ethernet packet to the process method of the Packet Processor.
+     *
+     * @param reply Ethernet packet
+     */
+    void sendPacket(Ethernet reply) {
+        final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
+        InboundPacket inPacket = new DefaultInboundPacket(connectPoint("1", 1),
+                                                          reply,
+                                                          byteBuffer);
+
+        PacketContext context = new TestPacketContext(127L, inPacket, null, false);
+        packetProcessor.process(context);
+    }
+
+    /**
+     * Constructs an Ethernet packet containing identification payload.
+     *
+     * @return Ethernet packet
+     */
+    Ethernet constructSupplicantIdentifyPacket(StateMachine stateMachine,
+                                                       byte type,
+                                                       byte id,
+                                                       Ethernet radiusChallenge)
+            throws Exception {
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(clientMac.toBytes());
+        eth.setSourceMACAddress(serverMac.toBytes());
+        eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
+        eth.setVlanID((short) 2);
+
+        String username = "testuser";
+        byte[] data = username.getBytes();
+
+
+        if (type == EAP.ATTR_MD5) {
+            String password = "testpassword";
+            EAPOL eapol = (EAPOL) radiusChallenge.getPayload();
+            EAP eap = (EAP) eapol.getPayload();
+
+            byte[] identifier = new byte[password.length() + eap.getData().length];
+
+            identifier[0] = stateMachine.challengeIdentifier();
+            System.arraycopy(password.getBytes(), 0, identifier, 1, password.length());
+            System.arraycopy(eap.getData(), 1, identifier, 1 + password.length(), 16);
+
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] hash = md.digest(identifier);
+            data = new byte[17];
+            data[0] = (byte) 16;
+            System.arraycopy(hash, 0, data, 1, 16);
+        }
+        EAP eap = new EAP(EAP.RESPONSE, (byte) 1, type,
+                          data);
+        eap.setIdentifier(id);
+
+        // eapol header
+        EAPOL eapol = new EAPOL();
+        eapol.setEapolType(EAPOL.EAPOL_PACKET);
+        eapol.setPacketLength(eap.getLength());
+
+        // eap part
+        eapol.setPayload(eap);
+
+        eth.setPayload(eapol);
+        eth.setPad(true);
+        return eth;
+    }
+
+    /**
+     * Constructs an Ethernet packet containing a EAPOL_START Payload.
+     *
+     * @return Ethernet packet
+     */
+    Ethernet constructSupplicantStartPacket() {
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(clientMac.toBytes());
+        eth.setSourceMACAddress(serverMac.toBytes());
+        eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
+        eth.setVlanID((short) 2);
+
+        EAP eap = new EAP(EAPOL.EAPOL_START, (byte) 2, EAPOL.EAPOL_START, null);
+
+        // eapol header
+        EAPOL eapol = new EAPOL();
+        eapol.setEapolType(EAPOL.EAPOL_START);
+        eapol.setPacketLength(eap.getLength());
+
+        // eap part
+        eapol.setPayload(eap);
+
+        eth.setPayload(eapol);
+        eth.setPad(true);
+        return eth;
+    }
+
+    /**
+     * Checks the contents of a RADIUS packet being sent to the RADIUS server.
+     *
+     * @param radiusPacket packet to check
+     * @param code expected code
+     */
+    void checkRadiusPacket(AaaManager aaaManager, Ethernet radiusPacket, byte code) {
+
+        assertThat(radiusPacket.getSourceMAC(),
+                   is(MacAddress.valueOf(aaaManager.nasMacAddress)));
+        assertThat(radiusPacket.getDestinationMAC(), is(serverMac));
+
+        assertThat(radiusPacket.getPayload(), instanceOf(EAPOL.class));
+        EAPOL eapol = (EAPOL) radiusPacket.getPayload();
+        assertThat(eapol, notNullValue());
+
+        assertThat(eapol.getEapolType(), is(EAPOL.EAPOL_PACKET));
+        assertThat(eapol.getPayload(), instanceOf(EAP.class));
+        EAP eap = (EAP) eapol.getPayload();
+        assertThat(eap, notNullValue());
+
+        assertThat(eap.getCode(), is(code));
+    }
+}
diff --git a/app/src/test/java/org/opencord/aaa/impl/StateMachineTest.java b/app/src/test/java/org/opencord/aaa/impl/StateMachineTest.java
new file mode 100644
index 0000000..4053ff9
--- /dev/null
+++ b/app/src/test/java/org/opencord/aaa/impl/StateMachineTest.java
@@ -0,0 +1,300 @@
+/*
+ * 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.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+public class StateMachineTest {
+    StateMachine stateMachine = null;
+
+    @Before
+    public void setUp() {
+        System.out.println("Set Up.");
+        StateMachine.initializeMaps();
+        StateMachine.setDelegate(e -> { });
+        stateMachine = new StateMachine("session0");
+    }
+
+    @After
+    public void tearDown() {
+        System.out.println("Tear Down.");
+        StateMachine.destroyMaps();
+        stateMachine = null;
+    }
+
+    @Test
+    /**
+     * Test all the basic inputs from state to state: IDLE -> STARTED -> PENDING -> AUTHORIZED -> IDLE
+     */
+    public void basic() throws StateMachineException {
+        System.out.println("======= BASIC =======.");
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+    }
+
+    @Test
+    /**
+     * Test all inputs from an IDLE state (starting with the ones that are not impacting the current state)
+     */
+    public void testIdleState() throws StateMachineException {
+        System.out.println("======= IDLE STATE TEST =======.");
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+    }
+
+    @Test
+    /**
+     * Test all inputs from an STARTED state (starting with the ones that are not impacting the current state)
+     */
+    public void testStartedState() throws StateMachineException {
+        System.out.println("======= STARTED STATE TEST =======.");
+        stateMachine.start();
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+    }
+
+    @Test
+    /**
+     * Test all inputs from a PENDING state (starting with the ones that are not impacting the current state).
+     * The next valid state for this test is AUTHORIZED
+     */
+    public void testPendingStateToAuthorized() throws StateMachineException {
+        System.out.println("======= PENDING STATE TEST (AUTHORIZED) =======.");
+        stateMachine.start();
+        stateMachine.requestAccess();
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+    }
+
+    @Test
+    /**
+     * Test all inputs from an PENDING state (starting with the ones that are not impacting the current state).
+     * The next valid state for this test is UNAUTHORIZED
+     */
+    public void testPendingStateToUnauthorized() throws StateMachineException {
+        System.out.println("======= PENDING STATE TEST (DENIED) =======.");
+        stateMachine.start();
+        stateMachine.requestAccess();
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_UNAUTHORIZED);
+    }
+
+    @Test
+    /**
+     * Test all inputs from an AUTHORIZED state (starting with the ones that are not impacting the current state).
+     */
+    public void testAuthorizedState() throws StateMachineException {
+        System.out.println("======= AUTHORIZED STATE TEST =======.");
+        stateMachine.start();
+        stateMachine.requestAccess();
+        stateMachine.authorizeAccess();
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+    }
+
+    @Test
+    /**
+     * Test all inputs from an UNAUTHORIZED state (starting with the ones that are not impacting the current state).
+     */
+    public void testUnauthorizedState() throws StateMachineException {
+        System.out.println("======= UNAUTHORIZED STATE TEST =======.");
+        stateMachine.start();
+        stateMachine.requestAccess();
+        stateMachine.denyAccess();
+
+        stateMachine.start();
+        assertEquals(stateMachine.state(), StateMachine.STATE_STARTED);
+
+        stateMachine.requestAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_PENDING);
+
+        stateMachine.authorizeAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.denyAccess();
+        assertEquals(stateMachine.state(), StateMachine.STATE_AUTHORIZED);
+
+        stateMachine.logoff();
+        assertEquals(stateMachine.state(), StateMachine.STATE_IDLE);
+    }
+
+    @Test
+    public void testSessionIdLookups() {
+        String sessionId1 = "session1";
+        String sessionId2 = "session2";
+        String sessionId3 = "session3";
+
+        StateMachine machine1ShouldBeNull =
+                StateMachine.lookupStateMachineBySessionId(sessionId1);
+        assertNull(machine1ShouldBeNull);
+        StateMachine machine2ShouldBeNull =
+                StateMachine.lookupStateMachineBySessionId(sessionId2);
+        assertNull(machine2ShouldBeNull);
+
+        StateMachine stateMachine1 = new StateMachine(sessionId1);
+        StateMachine stateMachine2 = new StateMachine(sessionId2);
+
+        assertEquals(stateMachine1,
+                     StateMachine.lookupStateMachineBySessionId(sessionId1));
+        assertEquals(stateMachine2,
+                     StateMachine.lookupStateMachineBySessionId(sessionId2));
+        assertNull(StateMachine.lookupStateMachineBySessionId(sessionId3));
+    }
+
+    @Test
+    public void testIdentifierLookups() throws StateMachineException {
+        String sessionId1 = "session1";
+        String sessionId2 = "session2";
+
+        StateMachine machine1ShouldBeNull =
+                StateMachine.lookupStateMachineById((byte) 1);
+        assertNull(machine1ShouldBeNull);
+        StateMachine machine2ShouldBeNull =
+                StateMachine.lookupStateMachineById((byte) 2);
+        assertNull(machine2ShouldBeNull);
+
+        StateMachine stateMachine1 = new StateMachine(sessionId1);
+        stateMachine1.start();
+        StateMachine stateMachine2 = new StateMachine(sessionId2);
+        stateMachine2.start();
+
+        assertEquals(stateMachine1,
+                     StateMachine.lookupStateMachineById(stateMachine1.identifier()));
+        assertEquals(stateMachine2,
+                     StateMachine.lookupStateMachineById(stateMachine2.identifier()));
+    }
+
+    @Test
+    /**
+     * Test state machine deletes
+     */
+    public void testStateMachineReset() throws StateMachineException {
+
+        int count = 256;
+
+        //StateMachine.initializeMaps();
+        StateMachine.lookupStateMachineById((byte) 1);
+
+        // Instantiate a bunch of state machines
+        for (int i = 0; i < count; i += 1) {
+            String mac = String.format("00:00:00:00:00:%02x", i);
+            StateMachine sm = new StateMachine(mac);
+            sm.start();
+            sm.setSupplicantAddress(MacAddress.valueOf(mac));
+        }
+
+        // Verify all state machines with a "even" MAC exist
+        for (int i = 0; i < count; i += 2) {
+            String mac = String.format("00:00:00:00:00:%02x", i);
+            assertNotNull(StateMachine.lookupStateMachineBySessionId(mac));
+        }
+
+        // Delete all state machines with a "even" MAC
+        for (int i = 0; i < count; i += 2) {
+            String mac = String.format("00:00:00:00:00:%02x", i);
+            StateMachine.deleteByMac(MacAddress.valueOf(mac));
+        }
+
+        // Verify all the delete state machines no long exist
+        for (int i = 0; i < count; i += 2) {
+            String mac = String.format("00:00:00:00:00:%02x", i);
+            assertNull(StateMachine.lookupStateMachineBySessionId(mac));
+        }
+    }
+}
