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/.clang-format b/.clang-format
new file mode 100644
index 0000000..bbc1bb1
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,85 @@
+---
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands:   true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+  AfterClass:      true
+  AfterControlStatement: true
+  AfterEnum:       true
+  AfterFunction:   true
+  AfterNamespace:  true
+  AfterObjCDeclaration: true
+  AfterStruct:     true
+  AfterUnion:      true
+  BeforeCatch:     true
+  BeforeElse:      true
+  IndentBraces:    false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: AfterColon
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: true
+PointerAlignment: Left
+DisableFormat:   false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IndentCaseLabels: true
+IndentWidth:     4
+IndentWrappedFunctionNames: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+ReflowComments:  true
+SortIncludes:    false
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard:        Cpp11
+TabWidth:        4
+UseTab:          Never
+...
+
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