First implementation of BNG application

The application offers network level APIs for the BNG data plane.

An attachment (BngAttachment) at network level is identified by an arbitrary string.
The exposed APIs are key-value like APIs.

Change-Id: If0e484f487ea16dd8c7dd99642f75686e1dbc29a
diff --git a/api/src/main/java/org/opencord/bng/BngAttachment.java b/api/src/main/java/org/opencord/bng/BngAttachment.java
new file mode 100644
index 0000000..3fce980
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/BngAttachment.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2019-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.bng;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.behaviour.BngProgrammable;
+
+/**
+ * Abstract implementation of an attachment.
+ */
+public abstract class BngAttachment implements BngProgrammable.Attachment {
+    private final ApplicationId appId;
+    private final VlanId sTag;
+    private final VlanId cTag;
+    private final MacAddress macAddress;
+    private final IpAddress ipAddress;
+    private final boolean lineActivated;
+    private final ConnectPoint oltConnectPoint;
+    private final String onuSerial;
+    private final short qinqTpid;
+
+    /**
+     * Creates a new attachment.
+     *
+     * @param appId           The application that created this attachment
+     * @param sTag            The VLAN S-TAG
+     * @param cTag            The VLAN C-TAG
+     * @param macAddress      The MAC address of the attachment
+     * @param ipAddress       The IP address of the attachment
+     * @param lineActivated   Define if the attachment is active or not
+     * @param oltConnectPoint The connect point of the OLT (UNI port)
+     * @param onuSerial       The serial string of the ONU
+     * @param qinqTpid        The QinQ Tpid for the packets
+     */
+    BngAttachment(ApplicationId appId, VlanId sTag, VlanId cTag,
+                  MacAddress macAddress, IpAddress ipAddress,
+                  boolean lineActivated, ConnectPoint oltConnectPoint,
+                  String onuSerial, short qinqTpid) {
+        this.appId = appId;
+        this.sTag = sTag;
+        this.cTag = cTag;
+        this.macAddress = macAddress;
+        this.ipAddress = ipAddress;
+        this.lineActivated = lineActivated;
+        this.oltConnectPoint = oltConnectPoint;
+        this.onuSerial = onuSerial;
+        this.qinqTpid = qinqTpid;
+    }
+
+    /**
+     * Returns the OLT connect point (UNI port).
+     *
+     * @return The OLT connect point
+     */
+    public ConnectPoint oltConnectPoint() {
+        return this.oltConnectPoint;
+    }
+
+    /**
+     * Returns the ONU serial number.
+     *
+     * @return The ONU serial number
+     */
+    public String onuSerial() {
+        return this.onuSerial;
+    }
+
+    /**
+     * Returns the QinQ TPID.
+     *
+     * @return The QinQ TPID
+     */
+    public short qinqTpid() {
+        return this.qinqTpid;
+    }
+
+    @Override
+    public ApplicationId appId() {
+        return appId;
+    }
+
+    @Override
+    public VlanId sTag() {
+        return sTag;
+    }
+
+    @Override
+    public VlanId cTag() {
+        return cTag;
+    }
+
+    @Override
+    public MacAddress macAddress() {
+        return macAddress;
+    }
+
+    @Override
+    public IpAddress ipAddress() {
+        return ipAddress;
+    }
+
+    @Override
+    public boolean lineActive() {
+        return lineActivated;
+    }
+
+    MoreObjects.ToStringHelper toStringHelper() {
+        return MoreObjects.toStringHelper(this)
+                .add("appId", appId)
+                .add("sTag", sTag)
+                .add("cTag", cTag)
+                .add("macAddress", macAddress)
+                .add("ipAddress", ipAddress)
+                .add("lineActivated", lineActivated)
+                .add("oltConnectPoint", oltConnectPoint)
+                .add("onuSerial", onuSerial)
+                .add("qinqTpid", qinqTpid);
+    }
+
+    /**
+     * Abstract builder of attachments.
+     * <p>
+     * TODO: javadoc
+     */
+    public abstract static class BngBuilder {
+        ApplicationId appId;
+        VlanId sTag;
+        VlanId cTag;
+        MacAddress macAddress;
+        IpAddress ipAddress = IpAddress.valueOf(0);
+        boolean lineActivated;
+        ConnectPoint oltconnectPoint;
+        String onuSerial;
+        short qinqTpid;
+
+        BngBuilder() {
+            // Hide constructor
+            this.lineActivated = false;
+        }
+
+        /**
+         * Sets the ONU serial number.
+         *
+         * @param onuSerial The ONU serial number
+         * @return self
+         */
+        public BngBuilder withOnuSerial(String onuSerial) {
+            this.onuSerial = onuSerial;
+            return this;
+        }
+
+        /**
+         * Sets the OLT connect point (UNI port).
+         *
+         * @param oltconnectPoint The OLT connect point
+         * @return self
+         */
+        public BngBuilder withOltConnectPoint(ConnectPoint oltconnectPoint) {
+            this.oltconnectPoint = oltconnectPoint;
+            return this;
+        }
+
+        /**
+         * Sets the VLAN S-Tag.
+         *
+         * @param sTag The VLAN S-Tag
+         * @return self
+         */
+        public BngBuilder withSTag(VlanId sTag) {
+            this.sTag = sTag;
+            return this;
+        }
+
+        /**
+         * Sets the VLAN C-Tag.
+         *
+         * @param cTag the VLAN C-Tag
+         * @return self
+         */
+        public BngBuilder withCTag(VlanId cTag) {
+            this.cTag = cTag;
+            return this;
+        }
+
+        /**
+         * Sets the attachment activation state.
+         *
+         * @param lineActivated The attachment activation state
+         * @return self
+         */
+        public BngBuilder lineActivated(boolean lineActivated) {
+            this.lineActivated = lineActivated;
+            return this;
+        }
+
+        /**
+         * Sets the application ID.
+         *
+         * @param appId The application ID.
+         * @return self
+         */
+        public BngBuilder withApplicationId(ApplicationId appId) {
+            this.appId = appId;
+            return this;
+        }
+
+        /**
+         * Sets the attachment MAC address.
+         *
+         * @param macAddress The MAC address
+         * @return self
+         */
+        public BngBuilder withMacAddress(MacAddress macAddress) {
+            this.macAddress = macAddress;
+            return this;
+        }
+
+        /**
+         * Sets the attachment IP address.
+         *
+         * @param ipAddress The IP address
+         * @return self
+         */
+        public BngBuilder withIpAddress(IpAddress ipAddress) {
+            this.ipAddress = ipAddress;
+            return this;
+        }
+
+        /**
+         * Sets the QinQ tpid.
+         *
+         * @param qinqTpid The QinQ tpid
+         * @return self
+         */
+        public BngBuilder withQinqTpid(short qinqTpid) {
+            this.qinqTpid = qinqTpid;
+            return this;
+        }
+
+        /**
+         * Returns a new BNG attachment.
+         *
+         * @return BNG attachment
+         */
+        public abstract BngAttachment build();
+    }
+}
diff --git a/api/src/main/java/org/opencord/bng/BngService.java b/api/src/main/java/org/opencord/bng/BngService.java
new file mode 100644
index 0000000..c9936ae
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/BngService.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2019-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.bng;
+
+import org.onosproject.net.DeviceId;
+
+import java.util.Map;
+
+/**
+ * Service for managing attachments.
+ */
+public interface BngService {
+
+    String ONU_ANNOTATION = "onu";
+
+    /**
+     * Sets up the given attachment with the given attachemtn key in the BNG
+     * app. If the attachment is already registered it will be updated. It will
+     * also trigger the termination of the attachment user traffic on the ASG
+     * device.
+     *
+     * @param attachmentKey The key for the given attachment
+     * @param attachment    The attachment to be installed or updated
+     */
+    void setupAttachment(String attachmentKey, BngAttachment attachment);
+
+    /**
+     * Removes an attachment given its attachment ID. It will also trigger the
+     * removal of all the related attachment flows from the ASG device.
+     *
+     * @param attachmentKey The ID of the attachment to be removed
+     */
+    void removeAttachment(String attachmentKey);
+
+    /**
+     * Returns a map with the registered attachments.
+     *
+     * @return The map of attachemtn keys and attachments. Empty map if no
+     * attachment is registered.
+     */
+    Map<String, BngAttachment> getAttachments();
+
+    /**
+     * Returns the registered attachment given the ID.
+     *
+     * @param attachmentKey The attachment ID
+     * @return The attachment if it is present, null otherwise
+     */
+    BngAttachment getAttachment(String attachmentKey);
+
+    /**
+     * Returns the BNG device ID currently used.
+     *
+     * @return The BNG device ID.
+     */
+    DeviceId getBngDeviceId();
+}
\ No newline at end of file
diff --git a/api/src/main/java/org/opencord/bng/BngStatsEvent.java b/api/src/main/java/org/opencord/bng/BngStatsEvent.java
new file mode 100644
index 0000000..2622b41
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/BngStatsEvent.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019-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.bng;
+
+import org.onosproject.event.AbstractEvent;
+
+/**
+ * Represents an event related to attachment-level statistics.
+ */
+public final class BngStatsEvent extends
+        AbstractEvent<BngStatsEvent.EventType, BngStatsEventSubject> {
+
+    /**
+     * Creates an attachment-level statistics event.
+     *
+     * @param type    Event type
+     * @param subject Event subject
+     */
+    public BngStatsEvent(EventType type, BngStatsEventSubject subject) {
+        super(type, subject);
+    }
+
+    /**
+     * Type of the event.
+     */
+    public enum EventType {
+        /**
+         * Signals that the statistics has been updated.
+         */
+        STATS_UPDATED
+    }
+}
diff --git a/api/src/main/java/org/opencord/bng/BngStatsEventListener.java b/api/src/main/java/org/opencord/bng/BngStatsEventListener.java
new file mode 100644
index 0000000..6232428
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/BngStatsEventListener.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019-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.bng;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Listener for attachment-level statistics events.
+ */
+public interface BngStatsEventListener extends EventListener<BngStatsEvent> {
+}
\ No newline at end of file
diff --git a/api/src/main/java/org/opencord/bng/BngStatsEventSubject.java b/api/src/main/java/org/opencord/bng/BngStatsEventSubject.java
new file mode 100644
index 0000000..05ae43a
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/BngStatsEventSubject.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2019-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.bng;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableMap;
+import org.onosproject.net.behaviour.BngProgrammable.BngCounterType;
+import org.onosproject.net.pi.runtime.PiCounterCellData;
+
+import java.util.Map;
+
+/**
+ * Subject for attachment-level statistics events.
+ */
+public final class BngStatsEventSubject {
+
+    private final BngAttachment bngAttachment;
+    private final String attachmentKey;
+    private final ImmutableMap<BngCounterType, PiCounterCellData> attachmentStats;
+
+    /**
+     * Creates a subject for attachment-level statistics event.
+     *
+     * @param attachmentKey   The attachment key
+     * @param bngAttachment   The attachment instance
+     * @param attachmentStats The attachments statistics
+     */
+    public BngStatsEventSubject(String attachmentKey, BngAttachment bngAttachment,
+                                Map<BngCounterType, PiCounterCellData> attachmentStats) {
+        this.attachmentKey = attachmentKey;
+        this.bngAttachment = bngAttachment;
+        this.attachmentStats = ImmutableMap.copyOf(attachmentStats);
+    }
+
+    /**
+     * Returns an immutable representation of the attachment-level statistics.
+     *
+     * @return The pair attachment instance and attachment-level statistics
+     */
+    public Map<BngCounterType, PiCounterCellData> getAttachmentStats() {
+        return attachmentStats;
+    }
+
+    /**
+     * Returns the BNG attachment instance of the attachment-level statistics.
+     *
+     * @return The BNG attachment instance
+     */
+    public BngAttachment getBngAttachment() {
+        return this.bngAttachment;
+    }
+
+    public String getAttachmentKey() {
+        return this.attachmentKey;
+    }
+
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("attachmentKey", attachmentKey)
+                .add("bngAttachment", bngAttachment)
+                .add("attachmentsStats", attachmentStats)
+                .toString();
+    }
+}
diff --git a/api/src/main/java/org/opencord/bng/BngStatsService.java b/api/src/main/java/org/opencord/bng/BngStatsService.java
new file mode 100644
index 0000000..45ab29b
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/BngStatsService.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2019-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.bng;
+
+import org.onosproject.event.ListenerService;
+import org.onosproject.net.behaviour.BngProgrammable;
+import org.onosproject.net.pi.runtime.PiCounterCellData;
+
+import java.util.Map;
+
+/**
+ * Service to retrieve attachment statistics.
+ */
+public interface BngStatsService
+        extends ListenerService<BngStatsEvent, BngStatsEventListener> {
+
+    /**
+     * Returns the statistics given an attachment Key. If the attachment is not
+     * programmed in the ASG, it returns an empty map. If one of the counter
+     * type is not supported by the ASG device, that specific counter will not
+     * be found in the map.
+     *
+     * @param bngAttachmentKey The attachment Key
+     * @return A map with the type of the counter and the associated statistics
+     * coming from the ASG device. Empty map if no BNG programmable is
+     * available.
+     */
+    Map<BngProgrammable.BngCounterType, PiCounterCellData> getStats(String bngAttachmentKey);
+
+    /**
+     * Returns the aggregate statistics related to attachments that are not
+     * known by this app, e.g., packets that are sent from an attachment while
+     * the attachment is negotiating the session.
+     *
+     * @return The statistics of not registered attachment. null if no BNG
+     * programmable device is available.
+     */
+    PiCounterCellData getControlStats();
+
+}
diff --git a/api/src/main/java/org/opencord/bng/PppoeBngAttachment.java b/api/src/main/java/org/opencord/bng/PppoeBngAttachment.java
new file mode 100644
index 0000000..7d6c8ed
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/PppoeBngAttachment.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2019-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.bng;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.behaviour.BngProgrammable;
+
+/**
+ * Contains all the information about an attachment in the PPPoE BNG context.
+ */
+public final class PppoeBngAttachment extends BngAttachment {
+
+    // The PPPoE session ID
+    private final short pppoeSessionId;
+
+    private PppoeBngAttachment(ApplicationId appId, VlanId sTag, VlanId cTag,
+                               MacAddress macAddress, IpAddress ipAddress, boolean lineActivated,
+                               short pppoeSessionId, ConnectPoint oltConnectPoint, String onuSerial,
+                               short qinqTpid) {
+        super(appId, sTag, cTag, macAddress, ipAddress, lineActivated,
+              oltConnectPoint, onuSerial, qinqTpid);
+        this.pppoeSessionId = pppoeSessionId;
+    }
+
+    /**
+     * Returns a builder for PPPoE BNG Attachemnt.
+     *
+     * @return The builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    // TODO: remove when BngProgrammable API are updated!
+    @Override
+    public BngProgrammable.AttachmentId attachmentId() {
+        return null;
+    }
+
+    @Override
+    public BngProgrammable.Attachment.AttachmentType type() {
+        return BngProgrammable.Attachment.AttachmentType.PPPoE;
+    }
+
+    @Override
+    public short pppoeSessionId() {
+        return this.pppoeSessionId;
+    }
+
+    @Override
+    public String toString() {
+        return this.toStringHelper()
+                .add("pppoeSessionId", pppoeSessionId())
+                .toString();
+    }
+
+    /**
+     * Builder of PPPoE attachments.
+     */
+    public static final class Builder extends BngBuilder {
+        private short pppoeSessionId = 0;
+
+        private Builder() {
+            super();
+        }
+
+        /**
+         * Sets the PPPoE session ID.
+         *
+         * @param pppoeSessionId The PPPoE session ID
+         * @return self
+         */
+        public Builder withPppoeSessionId(short pppoeSessionId) {
+            this.pppoeSessionId = pppoeSessionId;
+            return this;
+        }
+
+        /**
+         * Returns a new PPPoE attachment.
+         *
+         * @return PPPoE attachment
+         */
+        public PppoeBngAttachment build() {
+            return new PppoeBngAttachment(this.appId,
+                                          this.sTag,
+                                          this.cTag,
+                                          this.macAddress,
+                                          this.ipAddress,
+                                          this.lineActivated,
+                                          this.pppoeSessionId,
+                                          this.oltconnectPoint,
+                                          this.onuSerial,
+                                          this.qinqTpid);
+        }
+    }
+}
diff --git a/api/src/main/java/org/opencord/bng/PppoeBngControlHandler.java b/api/src/main/java/org/opencord/bng/PppoeBngControlHandler.java
new file mode 100644
index 0000000..4338da4
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/PppoeBngControlHandler.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2019-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.bng;
+
+import org.onosproject.event.ListenerService;
+
+/**
+ * BNG control packet service for PPPoE protocol.
+ */
+public interface PppoeBngControlHandler
+        extends ListenerService<PppoeEvent, PppoeEventListener> {
+}
diff --git a/api/src/main/java/org/opencord/bng/PppoeEvent.java b/api/src/main/java/org/opencord/bng/PppoeEvent.java
new file mode 100644
index 0000000..7bccabf
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/PppoeEvent.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2019-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.bng;
+
+import org.onosproject.event.AbstractEvent;
+
+/**
+ * PPPoE attachment level event. This kind of events are used to advertise
+ * control level attachment events (e.g., attachment creation, successful
+ * authentication etc.)
+ */
+public final class PppoeEvent extends
+        AbstractEvent<PppoeEvent.EventType, PppoeEventSubject> {
+    /**
+     * Creates a new event for the given attachment information.
+     *
+     * @param type    type
+     * @param subject the attachment event
+     */
+    public PppoeEvent(EventType type, PppoeEventSubject subject) {
+        super(type, subject);
+    }
+
+    /**
+     * Type of the event.
+     */
+    public enum EventType {
+        /**
+         * Signals that a PPPoE session has been initiated from the client.
+         */
+        SESSION_INIT,
+
+        /**
+         * Signal that a PPPoE session has been established.
+         */
+        SESSION_CONFIRMATION,
+
+        /**
+         * Signal that the PPPoE session has been terminated.
+         */
+        SESSION_TERMINATION,
+
+        /**
+         * Signals an IPCP configuration acknowledge event.
+         */
+        IPCP_CONF_ACK,
+
+        /**
+         * Signals an IPCP configuration request event.
+         */
+        IPCP_CONF_REQUEST,
+
+        /**
+         * Authentication initiated.
+         */
+        AUTH_REQUEST,
+
+        /**
+         * Authentication confirmation.
+         */
+        AUTH_SUCCESS,
+
+        /**
+         * Failed authentication.
+         */
+        AUTH_FAILURE
+    }
+}
\ No newline at end of file
diff --git a/api/src/main/java/org/opencord/bng/PppoeEventListener.java b/api/src/main/java/org/opencord/bng/PppoeEventListener.java
new file mode 100644
index 0000000..40d5ab1
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/PppoeEventListener.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019-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.bng;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Listener for PPPoE attachment level events.
+ */
+public interface PppoeEventListener extends EventListener<PppoeEvent> {
+}
diff --git a/api/src/main/java/org/opencord/bng/PppoeEventSubject.java b/api/src/main/java/org/opencord/bng/PppoeEventSubject.java
new file mode 100644
index 0000000..734ac37
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/PppoeEventSubject.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2019-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.bng;
+
+import com.google.common.base.MoreObjects;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+
+/**
+ * Subject for a PPPoE attachment level events.
+ */
+public final class PppoeEventSubject {
+
+    private final ConnectPoint oltConnectPoint;
+    private final IpAddress ipAddress;
+    private final MacAddress macAddress;
+    private final String onuSerialNumber;
+    private final short sessionId;
+    private final VlanId sTag;
+    private final VlanId cTag;
+
+    /**
+     * Creates a PPPoE attachment event subject.
+     *
+     * @param oltConnectPoint The connect point of the OLT (UNI port)
+     * @param ipAddress       The IP Address that has been assigned
+     * @param macAddress      The MAC address of the attachment
+     * @param onuSerialNumber The serial number of the ONU
+     * @param sessionId       The PPPoE session ID
+     * @param sTag            The VLAN S-Tag
+     * @param cTag            The VLan C-Tag
+     */
+    public PppoeEventSubject(ConnectPoint oltConnectPoint,
+                             IpAddress ipAddress,
+                             MacAddress macAddress,
+                             String onuSerialNumber,
+                             short sessionId,
+                             VlanId sTag,
+                             VlanId cTag) {
+        this.oltConnectPoint = oltConnectPoint;
+        this.ipAddress = ipAddress;
+        this.macAddress = macAddress;
+        this.onuSerialNumber = onuSerialNumber;
+        this.sessionId = sessionId;
+        this.sTag = sTag;
+        this.cTag = cTag;
+    }
+
+    /**
+     * Returns the connect point of the OLT (UNI port).
+     *
+     * @return The connect point
+     */
+    public ConnectPoint getOltConnectPoint() {
+        return this.oltConnectPoint;
+    }
+
+
+    /**
+     * Returns the assigned IP address (if any).
+     *
+     * @return The IP address
+     */
+    public IpAddress getIpAddress() {
+        return this.ipAddress;
+    }
+
+    /**
+     * Returns the MAC address.
+     *
+     * @return The MAC address
+     */
+    public MacAddress getMacAddress() {
+        return this.macAddress;
+    }
+
+    /**
+     * Returns the ONU serial number.
+     *
+     * @return The ONU serial number
+     */
+    public String getOnuSerialNumber() {
+        return onuSerialNumber;
+    }
+
+    /**
+     * Returns the session ID.
+     *
+     * @return The session ID.
+     */
+    public short getSessionId() {
+        return this.sessionId;
+    }
+
+    /**
+     * Returns the VLAN S-Tag.
+     *
+     * @return The VLAN S-Tag.
+     */
+    public VlanId getsTag() {
+        return sTag;
+    }
+
+    /**
+     * Returns the VLAN C-Tag.
+     *
+     * @return The VLAN C-Tag.
+     */
+    public VlanId getcTag() {
+        return cTag;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("oltConnectPoint", oltConnectPoint)
+                .add("ipAddress", ipAddress)
+                .add("macAddress", macAddress)
+                .add("onuSerialNumber", onuSerialNumber)
+                .add("sessionId", sessionId)
+                .add("STag", sTag)
+                .add("CTag", cTag)
+                .toString();
+    }
+}
diff --git a/api/src/main/java/org/opencord/bng/package-info.java b/api/src/main/java/org/opencord/bng/package-info.java
new file mode 100644
index 0000000..170eb9c
--- /dev/null
+++ b/api/src/main/java/org/opencord/bng/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019-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.
+ */
+
+/**
+ * BNG application.
+ */
+package org.opencord.bng;