diff --git a/src/selcommands.cpp b/src/selcommands.cpp
new file mode 100644
index 0000000..0fc33b4
--- /dev/null
+++ b/src/selcommands.cpp
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c)  2018 Intel Corporation.
+ * Copyright (c)  2018-present Facebook.
+ *
+ * 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.
+ */
+
+#include <ipmid/api.hpp>
+
+#include <boost/algorithm/string/join.hpp>
+#include <nlohmann/json.hpp>
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/message/types.hpp>
+#include <sdbusplus/timer.hpp>
+#include <storagecommands.hpp>
+
+//----------------------------------------------------------------------
+// Platform specific functions for storing app data
+//----------------------------------------------------------------------
+
+static void toHexStr(std::vector<uint8_t> &bytes, std::string &hexStr)
+{
+    std::stringstream stream;
+    stream << std::hex << std::uppercase << std::setfill('0');
+    for (const uint8_t byte : bytes)
+    {
+        stream << std::setw(2) << static_cast<int>(byte);
+    }
+    hexStr = stream.str();
+}
+
+static int fromHexStr(const std::string hexStr, std::vector<uint8_t> &data)
+{
+    for (unsigned int i = 0; i < hexStr.size(); i += 2)
+    {
+        try
+        {
+            data.push_back(static_cast<uint8_t>(
+                std::stoul(hexStr.substr(i, 2), nullptr, 16)));
+        }
+        catch (std::invalid_argument &e)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
+            return -1;
+        }
+        catch (std::out_of_range &e)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
+            return -1;
+        }
+    }
+    return 0;
+}
+
+namespace fb_oem::ipmi::sel
+{
+
+class SELData
+{
+  private:
+    nlohmann::json selDataObj;
+
+    void flush()
+    {
+        std::ofstream file(SEL_JSON_DATA_FILE);
+        file << selDataObj;
+        file.close();
+    }
+
+    void init()
+    {
+        selDataObj[KEY_SEL_VER] = 0x51;
+        selDataObj[KEY_SEL_COUNT] = 0;
+        selDataObj[KEY_ADD_TIME] = 0xFFFFFFFF;
+        selDataObj[KEY_ERASE_TIME] = 0xFFFFFFFF;
+        selDataObj[KEY_OPER_SUPP] = 0x02;
+        /* Spec indicates that more than 64kB is free */
+        selDataObj[KEY_FREE_SPACE] = 0xFFFF;
+    }
+
+  public:
+    SELData()
+    {
+        /* Get App data stored in json file */
+        std::ifstream file(SEL_JSON_DATA_FILE);
+        if (file)
+        {
+            file >> selDataObj;
+            file.close();
+        }
+
+        /* Initialize SelData object if no entries. */
+        if (selDataObj.find(KEY_SEL_COUNT) == selDataObj.end())
+        {
+            init();
+        }
+    }
+
+    int clear()
+    {
+        /* Clear the complete Sel Json object */
+        selDataObj.clear();
+        /* Reinitialize it with basic data */
+        init();
+        /* Save the erase time */
+        struct timespec selTime = {};
+        if (clock_gettime(CLOCK_REALTIME, &selTime) < 0)
+        {
+            return -1;
+        }
+        selDataObj[KEY_ERASE_TIME] = selTime.tv_sec;
+        flush();
+        return 0;
+    }
+
+    uint32_t getCount()
+    {
+        return selDataObj[KEY_SEL_COUNT];
+    }
+
+    void getInfo(GetSELInfoData &info)
+    {
+        info.selVersion = selDataObj[KEY_SEL_VER];
+        info.entries = selDataObj[KEY_SEL_COUNT];
+        info.freeSpace = selDataObj[KEY_FREE_SPACE];
+        info.addTimeStamp = selDataObj[KEY_ADD_TIME];
+        info.eraseTimeStamp = selDataObj[KEY_ERASE_TIME];
+        info.operationSupport = selDataObj[KEY_OPER_SUPP];
+    }
+
+    int getEntry(uint32_t index, std::string &rawStr)
+    {
+        std::stringstream ss;
+        ss << std::hex;
+        ss << std::setw(2) << std::setfill('0') << index;
+
+        /* Check or the requested SEL Entry, if record is available */
+        if (selDataObj.find(ss.str()) == selDataObj.end())
+        {
+            return -1;
+        }
+
+        rawStr = selDataObj[ss.str()][KEY_SEL_ENTRY_RAW];
+        return 0;
+    }
+
+    int addEntry(std::string keyStr)
+    {
+        struct timespec selTime = {};
+
+        if (clock_gettime(CLOCK_REALTIME, &selTime) < 0)
+        {
+            return -1;
+        }
+
+        selDataObj[KEY_ADD_TIME] = selTime.tv_sec;
+
+        int selCount = selDataObj[KEY_SEL_COUNT];
+        selDataObj[KEY_SEL_COUNT] = ++selCount;
+
+        std::stringstream ss;
+        ss << std::hex;
+        ss << std::setw(2) << std::setfill('0') << selCount;
+
+        selDataObj[ss.str()][KEY_SEL_ENTRY_RAW] = keyStr;
+        flush();
+        return selCount;
+    }
+};
+
+} // namespace fb_oem::ipmi::sel
+
+namespace ipmi
+{
+
+namespace storage
+{
+
+static void registerSELFunctions() __attribute__((constructor));
+static fb_oem::ipmi::sel::SELData selObj __attribute__((init_priority(101)));
+
+ipmi::RspType<uint8_t,  // SEL version
+              uint16_t, // SEL entry count
+              uint16_t, // free space
+              uint32_t, // last add timestamp
+              uint32_t, // last erase timestamp
+              uint8_t>  // operation support
+    ipmiStorageGetSELInfo()
+{
+
+    fb_oem::ipmi::sel::GetSELInfoData info;
+
+    selObj.getInfo(info);
+    return ipmi::responseSuccess(info.selVersion, info.entries, info.freeSpace,
+                                 info.addTimeStamp, info.eraseTimeStamp,
+                                 info.operationSupport);
+}
+
+ipmi::RspType<uint16_t, std::vector<uint8_t>>
+    ipmiStorageGetSELEntry(std::vector<uint8_t> data)
+{
+
+    if (data.size() != sizeof(fb_oem::ipmi::sel::GetSELEntryRequest))
+    {
+        return ipmi::responseReqDataLenInvalid();
+    }
+
+    fb_oem::ipmi::sel::GetSELEntryRequest *reqData =
+        reinterpret_cast<fb_oem::ipmi::sel::GetSELEntryRequest *>(&data[0]);
+
+    if (reqData->reservID != 0)
+    {
+        if (!checkSELReservation(reqData->reservID))
+        {
+            return ipmi::responseInvalidReservationId();
+        }
+    }
+
+    uint16_t selCnt = selObj.getCount();
+    if (selCnt == 0)
+    {
+        return ipmi::responseSensorInvalid();
+    }
+
+    /* If it is asked for first entry */
+    if (reqData->recordID == fb_oem::ipmi::sel::firstEntry)
+    {
+        /* First Entry (0x0000) as per Spec */
+        reqData->recordID = 1;
+    }
+    else if (reqData->recordID == fb_oem::ipmi::sel::lastEntry)
+    {
+        /* Last entry (0xFFFF) as per Spec */
+        reqData->recordID = selCnt;
+    }
+
+    std::string ipmiRaw;
+
+    if (selObj.getEntry(reqData->recordID, ipmiRaw) < 0)
+    {
+        return ipmi::responseSensorInvalid();
+    }
+
+    std::vector<uint8_t> recDataBytes;
+    if (fromHexStr(ipmiRaw, recDataBytes) < 0)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    /* Identify the next SEL record ID. If recordID is same as
+     * total SeL count then next id should be last entry else
+     * it should be incremented by 1 to current RecordID
+     */
+    uint16_t nextRecord;
+    if (reqData->recordID == selCnt)
+    {
+        nextRecord = fb_oem::ipmi::sel::lastEntry;
+    }
+    else
+    {
+        nextRecord = reqData->recordID + 1;
+    }
+
+    if (reqData->readLen == fb_oem::ipmi::sel::entireRecord)
+    {
+        return ipmi::responseSuccess(nextRecord, recDataBytes);
+    }
+    else
+    {
+        if (reqData->offset >= fb_oem::ipmi::sel::selRecordSize ||
+            reqData->readLen > fb_oem::ipmi::sel::selRecordSize)
+        {
+            return ipmi::responseUnspecifiedError();
+        }
+        std::vector<uint8_t> recPartData;
+
+        auto diff = fb_oem::ipmi::sel::selRecordSize - reqData->offset;
+        auto readLength = std::min(diff, static_cast<int>(reqData->readLen));
+
+        for (int i = 0; i < readLength; i++)
+        {
+            recPartData.push_back(recDataBytes[i + reqData->offset]);
+        }
+        return ipmi::responseSuccess(nextRecord, recPartData);
+    }
+}
+
+ipmi::RspType<uint16_t> ipmiStorageAddSELEntry(std::vector<uint8_t> data)
+{
+    /* Per the IPMI spec, need to cancel any reservation when a
+     * SEL entry is added
+     */
+    cancelSELReservation();
+
+    if (data.size() != fb_oem::ipmi::sel::selRecordSize)
+    {
+        return ipmi::responseReqDataLenInvalid();
+    }
+
+    std::string ipmiRaw, logErr;
+    toHexStr(data, ipmiRaw);
+
+    /* Log the Raw SEL message to the journal */
+    std::string journalMsg = "SEL Entry Added: " + ipmiRaw;
+    phosphor::logging::log<phosphor::logging::level::INFO>(journalMsg.c_str());
+
+    int responseID = selObj.addEntry(ipmiRaw.c_str());
+    if (responseID < 0)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+    return ipmi::responseSuccess((uint16_t)responseID);
+}
+
+void registerSELFunctions()
+{
+    // <Get SEL Info>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSelInfo, ipmi::Privilege::User,
+                          ipmiStorageGetSELInfo);
+
+    // <Get SEL Entry>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdGetSelEntry, ipmi::Privilege::User,
+                          ipmiStorageGetSELEntry);
+
+    // <Add SEL Entry>
+    ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnStorage,
+                          ipmi::storage::cmdAddSelEntry,
+                          ipmi::Privilege::Operator, ipmiStorageAddSELEntry);
+
+    return;
+}
+
+} // namespace storage
+} // namespace ipmi
