Add SNMP Error Notification

This class represents the Error Notification
mib object.

The object of this class would be constructed from
the function (sendTrap<>()) which would be implemented
in later commit.

Change-Id: I3a737a20570acafb8263f3a69cf0464680f42b13
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/snmp_notification.hpp b/snmp_notification.hpp
new file mode 100644
index 0000000..d21e68c
--- /dev/null
+++ b/snmp_notification.hpp
@@ -0,0 +1,210 @@
+/**
+ * @brief SNMP Error Notification class.
+ *
+ * This file is part of phosphor-snmp project.
+ *
+ * Copyright (c) 2018 IBM Corporation
+ *
+ * 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.
+ *
+ * Note: In near future this file will be autogenerated by the custom parser.
+ *
+ */
+
+#pragma once
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include <sdbusplus/server.hpp>
+
+#include <experimental/any>
+#include <sstream>
+#include <string>
+#include <tuple>
+#include <vector>
+
+namespace any_ns = std::experimental;
+
+namespace phosphor
+{
+namespace network
+{
+namespace snmp
+{
+
+using OID = std::array<oid, MAX_OID_LEN>;
+using OID_LEN = size_t;
+using Type = u_char;
+
+using Value =
+    sdbusplus::message::variant<uint32_t, uint64_t, int32_t, std::string>;
+// Generic snmp trap ID
+oid SNMPTrapOID[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0};
+
+using Object = std::tuple<OID, OID_LEN, Type, Value>;
+
+/** @brief Get the ASN object type from the given templatized type.
+ *         Specialize this template for handling a specific type.
+ *  @tparam T - type of object from ASN type would be decided.
+ *  @returns the ASN object type.
+ */
+template <typename T> u_char getASNType() = delete;
+
+template <> u_char getASNType<uint32_t>()
+{
+    return ASN_UNSIGNED;
+}
+
+template <> u_char getASNType<uint64_t>()
+{
+    return ASN_OPAQUE_U64;
+}
+
+template <> u_char getASNType<int32_t>()
+{
+    return ASN_INTEGER;
+}
+
+template <> u_char getASNType<std::string>()
+{
+    return ASN_OCTET_STR;
+}
+
+/** @class Notification
+ *  @brief Notification interface.
+ *
+ *  This class implements the sendTrap function which
+ *  send the list of objects defined by the specific notification
+ *  to the configured SNMP manager.
+ */
+
+class Notification
+{
+
+  public:
+    Notification() = default;
+    Notification(const Notification &) = delete;
+    Notification(Notification &&) = default;
+    Notification &operator=(const Notification &) = delete;
+    Notification &operator=(Notification &&) = default;
+    virtual ~Notification() = default;
+
+    /** @brief Send the snmp trap to the configured
+     *          manager.
+     */
+    void sendTrap();
+
+  protected:
+    /** @brief get the SNMP notification type in the mib
+     *         defined format.
+     *         This is pure virtual function all the subclasses
+     *         need to provide its own defined type.
+     *  @returns the notification type string.
+     */
+    virtual std::pair<OID, OID_LEN> getTrapOID() = 0;
+
+    /** @brief get all the objects meta data defined under
+     *         this notification.
+     */
+    virtual std::vector<Object> getFieldOIDList() = 0;
+};
+
+/** @class ErrorNotification
+ *  @brief subclass of Notification
+ *
+ *  A Error Notification represents the objects needed by the
+ *  Error Object.
+ */
+class OBMCErrorNotification : public Notification
+{
+
+  private:
+    uint32_t OBMCErrorID;
+    uint64_t OBMCErrorTimestamp;
+    int32_t OBMCErrorSeverity;
+    std::string OBMCErrorMessage;
+
+  public:
+    OBMCErrorNotification() = default;
+    OBMCErrorNotification(const OBMCErrorNotification &) = delete;
+    OBMCErrorNotification(OBMCErrorNotification &&) = default;
+    OBMCErrorNotification &operator=(const OBMCErrorNotification &) = delete;
+    OBMCErrorNotification &operator=(OBMCErrorNotification &&) = default;
+    ~OBMCErrorNotification() = default;
+
+    /** @brief Constructor
+     *  @param[in] id - The error entry id.
+     *  @param[in] ts - The commit timestamp.
+     *  @param[in] sev - The severity of the error.
+     *  @param[in] msg - The message of the error.
+     */
+    OBMCErrorNotification(uint32_t id, uint64_t ts, int32_t sev,
+                          std::string msg) :
+        OBMCErrorID(id),
+        OBMCErrorTimestamp(ts), OBMCErrorSeverity(sev), OBMCErrorMessage(msg)
+    {
+    }
+
+  protected:
+    std::pair<OID, OID_LEN> getTrapOID() override
+    {
+        // notification sub types
+        OID id = {1, 3, 6, 1, 4, 1, 49871, 1, 0, 0, 1};
+        OID_LEN idLen = 11;
+        return std::make_pair<OID, OID_LEN>(std::move(id), std::move(idLen));
+    }
+
+    std::vector<Object> getFieldOIDList() override
+    {
+        std::vector<Object> objectList;
+
+        OID_LEN idLen = 11;
+        OID id = {1, 3, 6, 1, 4, 1, 49871, 1, 0, 1, 1};
+        auto type = getASNType<decltype(OBMCErrorID)>();
+        auto tuple =
+            std::tuple<OID, OID_LEN, Type, Value>(id, idLen, type, OBMCErrorID);
+
+        objectList.emplace_back(std::move(tuple));
+
+        id = {1, 3, 6, 1, 4, 1, 49871, 1, 0, 1, 2};
+        type = getASNType<decltype(OBMCErrorTimestamp)>();
+        tuple = std::tuple<OID, OID_LEN, Type, Value>(id, idLen, type,
+                                                      OBMCErrorTimestamp);
+
+        objectList.emplace_back(std::move(tuple));
+
+        id = {1, 3, 6, 1, 4, 1, 49871, 1, 0, 1, 3};
+        type = getASNType<decltype(OBMCErrorSeverity)>();
+
+        tuple = std::tuple<OID, OID_LEN, Type, Value>(id, idLen, type,
+                                                      OBMCErrorSeverity);
+
+        objectList.emplace_back(std::move(tuple));
+
+        id = {1, 3, 6, 1, 4, 1, 49871, 1, 0, 1, 4};
+        type = getASNType<decltype(OBMCErrorMessage)>();
+
+        tuple = std::tuple<OID, OID_LEN, Type, Value>(id, idLen, type,
+                                                      OBMCErrorMessage);
+
+        objectList.emplace_back(std::move(tuple));
+
+        return objectList;
+    }
+};
+
+} // namespace snmp
+} // namespace network
+} // namespace phosphor