diff --git a/src/intrusion/ChassisIntrusionSensor.cpp b/src/intrusion/ChassisIntrusionSensor.cpp
new file mode 100644
index 0000000..2c1e391
--- /dev/null
+++ b/src/intrusion/ChassisIntrusionSensor.cpp
@@ -0,0 +1,500 @@
+/*
+// Copyright (c) 2018 Intel 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.
+*/
+
+#include "ChassisIntrusionSensor.hpp"
+
+#include <fcntl.h>
+#include <linux/i2c.h>
+#include <sys/ioctl.h>
+#include <sys/syslog.h>
+#include <systemd/sd-journal.h>
+#include <unistd.h>
+
+#include <Utils.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/posix/stream_descriptor.hpp>
+#include <gpiod.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <chrono>
+#include <cstddef>
+#include <cstdint>
+#include <filesystem>
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <stdexcept>
+#include <string>
+#include <utility>
+#include <vector>
+
+extern "C"
+{
+#include <i2c/smbus.h>
+#include <linux/i2c-dev.h>
+}
+
+static constexpr bool debug = false;
+
+static constexpr unsigned int defaultPollSec = 1;
+static constexpr unsigned int sensorFailedPollSec = 5;
+static unsigned int intrusionSensorPollSec = defaultPollSec;
+static constexpr const char* hwIntrusionValStr =
+    "xyz.openbmc_project.Chassis.Intrusion.Status.HardwareIntrusion";
+static constexpr const char* normalValStr =
+    "xyz.openbmc_project.Chassis.Intrusion.Status.Normal";
+static constexpr const char* manualRearmStr =
+    "xyz.openbmc_project.Chassis.Intrusion.RearmMode.Manual";
+static constexpr const char* autoRearmStr =
+    "xyz.openbmc_project.Chassis.Intrusion.RearmMode.Automatic";
+
+// SMLink Status Register
+const static constexpr size_t pchStatusRegIntrusion = 0x04;
+
+// Status bit field masks
+const static constexpr size_t pchRegMaskIntrusion = 0x01;
+
+// Value to clear intrusion status hwmon file
+const static constexpr size_t intrusionStatusHwmonClearValue = 0;
+
+void ChassisIntrusionSensor::updateValue(const size_t& value)
+{
+    std::string newValue = value != 0 ? hwIntrusionValStr : normalValStr;
+
+    // Take no action if the hardware status does not change
+    // Same semantics as Sensor::updateValue(const double&)
+    if (newValue == mValue)
+    {
+        return;
+    }
+
+    if constexpr (debug)
+    {
+        std::cout << "Update value from " << mValue << " to " << newValue
+                  << "\n";
+    }
+
+    // Automatic Rearm mode allows direct update
+    // Manual Rearm mode requires a rearm action to clear the intrusion
+    // status
+    if (!mAutoRearm)
+    {
+        if (newValue == normalValStr)
+        {
+            // Chassis is first closed from being open. If it has been
+            // rearmed externally, reset the flag, update mValue and
+            // return, without having to write "Normal" to DBus property
+            // (because the rearm action already did).
+            // Otherwise, return with no more action.
+            if (mRearmFlag)
+            {
+                mRearmFlag = false;
+                mValue = newValue;
+            }
+            return;
+        }
+    }
+
+    // Flush the rearm flag everytime it allows an update to Dbus
+    mRearmFlag = false;
+
+    // indicate that it is internal set call
+    mOverridenState = false;
+    mInternalSet = true;
+    mIface->set_property("Status", newValue);
+    mInternalSet = false;
+
+    mValue = newValue;
+}
+
+int ChassisIntrusionPchSensor::readSensor()
+{
+    int32_t statusMask = pchRegMaskIntrusion;
+    int32_t statusReg = pchStatusRegIntrusion;
+
+    int32_t value = i2c_smbus_read_byte_data(mBusFd, statusReg);
+    if constexpr (debug)
+    {
+        std::cout << "Pch type: raw value is " << value << "\n";
+    }
+
+    if (value < 0)
+    {
+        std::cerr << "i2c_smbus_read_byte_data failed \n";
+        return -1;
+    }
+
+    // Get status value with mask
+    value &= statusMask;
+
+    if constexpr (debug)
+    {
+        std::cout << "Pch type: masked raw value is " << value << "\n";
+    }
+    return value;
+}
+
+void ChassisIntrusionPchSensor::pollSensorStatus()
+{
+    std::weak_ptr<ChassisIntrusionPchSensor> weakRef = weak_from_this();
+
+    // setting a new experation implicitly cancels any pending async wait
+    mPollTimer.expires_after(std::chrono::seconds(intrusionSensorPollSec));
+
+    mPollTimer.async_wait([weakRef](const boost::system::error_code& ec) {
+        // case of being canceled
+        if (ec == boost::asio::error::operation_aborted)
+        {
+            std::cerr << "Timer of intrusion sensor is cancelled\n";
+            return;
+        }
+
+        std::shared_ptr<ChassisIntrusionPchSensor> self = weakRef.lock();
+        if (!self)
+        {
+            std::cerr << "ChassisIntrusionSensor no self\n";
+            return;
+        }
+
+        int value = self->readSensor();
+        if (value < 0)
+        {
+            intrusionSensorPollSec = sensorFailedPollSec;
+        }
+        else
+        {
+            intrusionSensorPollSec = defaultPollSec;
+            self->updateValue(value);
+        }
+
+        // trigger next polling
+        self->pollSensorStatus();
+    });
+}
+
+int ChassisIntrusionGpioSensor::readSensor()
+{
+    mGpioLine.event_read();
+    auto value = mGpioLine.get_value();
+    if constexpr (debug)
+    {
+        std::cout << "Gpio type: raw value is " << value << "\n";
+    }
+    return value;
+}
+
+void ChassisIntrusionGpioSensor::pollSensorStatus()
+{
+    mGpioFd.async_wait(
+        boost::asio::posix::stream_descriptor::wait_read,
+        [this](const boost::system::error_code& ec) {
+            if (ec == boost::system::errc::bad_file_descriptor)
+            {
+                return; // we're being destroyed
+            }
+
+            if (ec)
+            {
+                std::cerr
+                    << "Error on GPIO based intrusion sensor wait event\n";
+            }
+            else
+            {
+                int value = readSensor();
+                if (value >= 0)
+                {
+                    updateValue(value);
+                }
+                // trigger next polling
+                pollSensorStatus();
+            }
+        });
+}
+
+int ChassisIntrusionHwmonSensor::readSensor()
+{
+    int value = 0;
+
+    std::fstream stream(mHwmonPath, std::ios::in | std::ios::out);
+    if (!stream.good())
+    {
+        std::cerr << "Error reading status at " << mHwmonPath << "\n";
+        return -1;
+    }
+
+    std::string line;
+    if (!std::getline(stream, line))
+    {
+        std::cerr << "Error reading status at " << mHwmonPath << "\n";
+        return -1;
+    }
+
+    try
+    {
+        value = std::stoi(line);
+        if constexpr (debug)
+        {
+            std::cout << "Hwmon type: raw value is " << value << "\n";
+        }
+    }
+    catch (const std::invalid_argument& e)
+    {
+        std::cerr << "Error reading status at " << mHwmonPath << " : "
+                  << e.what() << "\n";
+        return -1;
+    }
+
+    // Reset chassis intrusion status after every reading
+    stream << intrusionStatusHwmonClearValue;
+
+    return value;
+}
+
+void ChassisIntrusionHwmonSensor::pollSensorStatus()
+{
+    std::weak_ptr<ChassisIntrusionHwmonSensor> weakRef = weak_from_this();
+
+    // setting a new experation implicitly cancels any pending async wait
+    mPollTimer.expires_after(std::chrono::seconds(intrusionSensorPollSec));
+
+    mPollTimer.async_wait([weakRef](const boost::system::error_code& ec) {
+        // case of being canceled
+        if (ec == boost::asio::error::operation_aborted)
+        {
+            std::cerr << "Timer of intrusion sensor is cancelled\n";
+            return;
+        }
+
+        std::shared_ptr<ChassisIntrusionHwmonSensor> self = weakRef.lock();
+        if (!self)
+        {
+            std::cerr << "ChassisIntrusionSensor no self\n";
+            return;
+        }
+
+        int value = self->readSensor();
+        if (value < 0)
+        {
+            intrusionSensorPollSec = sensorFailedPollSec;
+        }
+        else
+        {
+            intrusionSensorPollSec = defaultPollSec;
+            self->updateValue(value);
+        }
+
+        // trigger next polling
+        self->pollSensorStatus();
+    });
+}
+
+int ChassisIntrusionSensor::setSensorValue(const std::string& req,
+                                           std::string& propertyValue)
+{
+    if (!mInternalSet)
+    {
+        /*
+           1. Assuming that setting property in Automatic mode causes
+           no effect but only event logs and propertiesChanged signal
+           (because the property will be updated continuously to the
+           current hardware status anyway), only update Status property
+           and raise rearm flag in Manual rearm mode.
+           2. Only accept Normal value from an external call.
+        */
+        if (!mAutoRearm && req == normalValStr)
+        {
+            mRearmFlag = true;
+            propertyValue = req;
+            mOverridenState = true;
+        }
+    }
+    else if (!mOverridenState)
+    {
+        propertyValue = req;
+    }
+    else
+    {
+        return 1;
+    }
+    // Send intrusion event to Redfish
+    if (mValue == normalValStr && propertyValue != normalValStr)
+    {
+        sd_journal_send("MESSAGE=%s", "Chassis intrusion assert event",
+                        "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                        "OpenBMC.0.1.ChassisIntrusionDetected", NULL);
+    }
+    else if (mValue == hwIntrusionValStr && propertyValue == normalValStr)
+    {
+        sd_journal_send("MESSAGE=%s", "Chassis intrusion de-assert event",
+                        "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
+                        "OpenBMC.0.1.ChassisIntrusionReset", NULL);
+    }
+    return 1;
+}
+
+void ChassisIntrusionSensor::start()
+{
+    mIface->register_property(
+        "Status", mValue,
+        [&](const std::string& req, std::string& propertyValue) {
+            return setSensorValue(req, propertyValue);
+        });
+    std::string rearmStr = mAutoRearm ? autoRearmStr : manualRearmStr;
+    mIface->register_property("Rearm", rearmStr);
+    mIface->initialize();
+    pollSensorStatus();
+}
+
+ChassisIntrusionSensor::ChassisIntrusionSensor(
+    bool autoRearm, sdbusplus::asio::object_server& objServer) :
+    mValue(normalValStr), mAutoRearm(autoRearm), mObjServer(objServer)
+{
+    mIface = mObjServer.add_interface("/xyz/openbmc_project/Chassis/Intrusion",
+                                      "xyz.openbmc_project.Chassis.Intrusion");
+}
+
+ChassisIntrusionPchSensor::ChassisIntrusionPchSensor(
+    bool autoRearm, boost::asio::io_context& io,
+    sdbusplus::asio::object_server& objServer, int busId, int slaveAddr) :
+    ChassisIntrusionSensor(autoRearm, objServer), mPollTimer(io)
+{
+    if (busId < 0 || slaveAddr <= 0)
+    {
+        throw std::invalid_argument(
+            "Invalid i2c bus " + std::to_string(busId) + " address " +
+            std::to_string(slaveAddr) + "\n");
+    }
+
+    mSlaveAddr = slaveAddr;
+
+    std::string devPath = "/dev/i2c-" + std::to_string(busId);
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
+    mBusFd = open(devPath.c_str(), O_RDWR | O_CLOEXEC);
+    if (mBusFd < 0)
+    {
+        throw std::invalid_argument("Unable to open " + devPath + "\n");
+    }
+
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
+    if (ioctl(mBusFd, I2C_SLAVE_FORCE, mSlaveAddr) < 0)
+    {
+        throw std::runtime_error("Unable to set device address\n");
+    }
+
+    unsigned long funcs = 0;
+
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
+    if (ioctl(mBusFd, I2C_FUNCS, &funcs) < 0)
+    {
+        throw std::runtime_error("Don't support I2C_FUNCS\n");
+    }
+
+    if ((funcs & I2C_FUNC_SMBUS_READ_BYTE_DATA) == 0U)
+    {
+        throw std::runtime_error(
+            "Do not have I2C_FUNC_SMBUS_READ_BYTE_DATA \n");
+    }
+}
+
+ChassisIntrusionGpioSensor::ChassisIntrusionGpioSensor(
+    bool autoRearm, boost::asio::io_context& io,
+    sdbusplus::asio::object_server& objServer, bool gpioInverted) :
+    ChassisIntrusionSensor(autoRearm, objServer), mGpioInverted(gpioInverted),
+    mGpioFd(io)
+{
+    mGpioLine = gpiod::find_line(mPinName);
+    if (!mGpioLine)
+    {
+        throw std::invalid_argument(
+            "Error finding gpio pin name: " + mPinName + "\n");
+    }
+    mGpioLine.request(
+        {"ChassisIntrusionSensor", gpiod::line_request::EVENT_BOTH_EDGES,
+         mGpioInverted ? gpiod::line_request::FLAG_ACTIVE_LOW : 0});
+
+    auto gpioLineFd = mGpioLine.event_get_fd();
+    if (gpioLineFd < 0)
+    {
+        throw std::invalid_argument("Failed to get " + mPinName + " fd\n");
+    }
+
+    mGpioFd.assign(gpioLineFd);
+}
+
+ChassisIntrusionHwmonSensor::ChassisIntrusionHwmonSensor(
+    bool autoRearm, boost::asio::io_context& io,
+    sdbusplus::asio::object_server& objServer, std::string hwmonName) :
+    ChassisIntrusionSensor(autoRearm, objServer),
+    mHwmonName(std::move(hwmonName)), mPollTimer(io)
+{
+    std::vector<fs::path> paths;
+
+    if (!findFiles(fs::path("/sys/class/hwmon"), mHwmonName, paths))
+    {
+        throw std::invalid_argument("Failed to find hwmon path in sysfs\n");
+    }
+
+    if (paths.empty())
+    {
+        throw std::invalid_argument(
+            "Hwmon file " + mHwmonName + " can't be found in sysfs\n");
+    }
+
+    if (paths.size() > 1)
+    {
+        std::cerr << "Found more than 1 hwmon file to read chassis intrusion"
+                  << " status. Taking the first one. \n";
+    }
+
+    // Expecting only one hwmon file for one given chassis
+    mHwmonPath = paths[0].string();
+
+    if constexpr (debug)
+    {
+        std::cout << "Found " << paths.size()
+                  << " paths for intrusion status \n"
+                  << " The first path is: " << mHwmonPath << "\n";
+    }
+}
+
+ChassisIntrusionSensor::~ChassisIntrusionSensor()
+{
+    mObjServer.remove_interface(mIface);
+}
+
+ChassisIntrusionPchSensor::~ChassisIntrusionPchSensor()
+{
+    mPollTimer.cancel();
+    if (close(mBusFd) < 0)
+    {
+        std::cerr << "Failed to close fd " << std::to_string(mBusFd);
+    }
+}
+
+ChassisIntrusionGpioSensor::~ChassisIntrusionGpioSensor()
+{
+    mGpioFd.close();
+    if (mGpioLine)
+    {
+        mGpioLine.release();
+    }
+}
+
+ChassisIntrusionHwmonSensor::~ChassisIntrusionHwmonSensor()
+{
+    mPollTimer.cancel();
+}
diff --git a/src/intrusion/ChassisIntrusionSensor.hpp b/src/intrusion/ChassisIntrusionSensor.hpp
new file mode 100644
index 0000000..d22eaf8
--- /dev/null
+++ b/src/intrusion/ChassisIntrusionSensor.hpp
@@ -0,0 +1,97 @@
+#pragma once
+
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <gpiod.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+
+#include <memory>
+#include <string>
+
+namespace fs = std::filesystem;
+
+class ChassisIntrusionSensor
+{
+  public:
+    explicit ChassisIntrusionSensor(bool autoRearm,
+                                    sdbusplus::asio::object_server& objServer);
+
+    virtual ~ChassisIntrusionSensor();
+
+    void start();
+
+  protected:
+    virtual int readSensor() = 0;
+    virtual void pollSensorStatus() = 0;
+    void updateValue(const size_t& value);
+
+  private:
+    std::string mValue;
+    // If this sensor uses automatic rearm method. Otherwise, manually rearm it
+    bool mAutoRearm;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> mIface;
+    sdbusplus::asio::object_server& mObjServer;
+    bool mOverridenState = false;
+    bool mInternalSet = false;
+    bool mRearmFlag = false;
+
+    int setSensorValue(const std::string& req, std::string& propertyValue);
+};
+
+class ChassisIntrusionPchSensor :
+    public ChassisIntrusionSensor,
+    public std::enable_shared_from_this<ChassisIntrusionPchSensor>
+{
+  public:
+    ChassisIntrusionPchSensor(bool autoRearm, boost::asio::io_context& io,
+                              sdbusplus::asio::object_server& objServer,
+                              int busId, int slaveAddr);
+
+    ~ChassisIntrusionPchSensor() override;
+
+  private:
+    int mBusFd{-1};
+    int mSlaveAddr{-1};
+    boost::asio::steady_timer mPollTimer;
+    int readSensor() override;
+    void pollSensorStatus() override;
+};
+
+class ChassisIntrusionGpioSensor :
+    public ChassisIntrusionSensor,
+    public std::enable_shared_from_this<ChassisIntrusionGpioSensor>
+{
+  public:
+    ChassisIntrusionGpioSensor(bool autoRearm, boost::asio::io_context& io,
+                               sdbusplus::asio::object_server& objServer,
+                               bool gpioInverted);
+
+    ~ChassisIntrusionGpioSensor() override;
+
+  private:
+    bool mGpioInverted{false};
+    std::string mPinName = "CHASSIS_INTRUSION";
+    gpiod::line mGpioLine;
+    boost::asio::posix::stream_descriptor mGpioFd;
+    int readSensor() override;
+    void pollSensorStatus() override;
+};
+
+class ChassisIntrusionHwmonSensor :
+    public ChassisIntrusionSensor,
+    public std::enable_shared_from_this<ChassisIntrusionHwmonSensor>
+{
+  public:
+    ChassisIntrusionHwmonSensor(bool autoRearm, boost::asio::io_context& io,
+                                sdbusplus::asio::object_server& objServer,
+                                std::string hwmonName);
+
+    ~ChassisIntrusionHwmonSensor() override;
+
+  private:
+    std::string mHwmonName;
+    std::string mHwmonPath;
+    boost::asio::steady_timer mPollTimer;
+    int readSensor() override;
+    void pollSensorStatus() override;
+};
diff --git a/src/intrusion/IntrusionSensorMain.cpp b/src/intrusion/IntrusionSensorMain.cpp
new file mode 100644
index 0000000..c94727a
--- /dev/null
+++ b/src/intrusion/IntrusionSensorMain.cpp
@@ -0,0 +1,548 @@
+/*
+// Copyright (c) 2018 Intel 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.
+*/
+
+#include "ChassisIntrusionSensor.hpp"
+#include "Utils.hpp"
+
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <boost/container/flat_map.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+
+#include <array>
+#include <charconv>
+#include <chrono>
+#include <cstdint>
+#include <ctime>
+#include <exception>
+#include <filesystem>
+#include <fstream>
+#include <functional>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <utility>
+#include <variant>
+#include <vector>
+
+static constexpr bool debug = false;
+
+static constexpr const char* sensorType = "ChassisIntrusionSensor";
+static constexpr const char* nicType = "NIC";
+static constexpr auto nicTypes{std::to_array<const char*>({nicType})};
+
+static const std::map<std::string, std::string> compatibleHwmonNames = {
+    {"Aspeed2600_Hwmon", "intrusion0_alarm"}
+    // Add compatible strings here for new hwmon intrusion detection
+    // drivers that have different hwmon names but would also like to
+    // use the available Hwmon class.
+};
+
+static void createSensorsFromConfig(
+    boost::asio::io_context& io, sdbusplus::asio::object_server& objServer,
+    const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
+    std::shared_ptr<ChassisIntrusionSensor>& pSensor)
+{
+    // find matched configuration according to sensor type
+    ManagedObjectType sensorConfigurations;
+    bool useCache = false;
+
+    if (!getSensorConfiguration(sensorType, dbusConnection,
+                                sensorConfigurations, useCache))
+    {
+        std::cerr << "error communicating to entity manager\n";
+        return;
+    }
+
+    const SensorData* sensorData = nullptr;
+    const std::pair<std::string, SensorBaseConfigMap>* baseConfiguration =
+        nullptr;
+
+    for (const auto& [path, cfgData] : sensorConfigurations)
+    {
+        baseConfiguration = nullptr;
+        sensorData = &cfgData;
+
+        // match sensor type
+        auto sensorBase = sensorData->find(configInterfaceName(sensorType));
+        if (sensorBase == sensorData->end())
+        {
+            std::cerr << "error finding base configuration \n";
+            continue;
+        }
+
+        baseConfiguration = &(*sensorBase);
+
+        // Rearm defaults to "Automatic" mode
+        bool autoRearm = true;
+        auto findRearm = baseConfiguration->second.find("Rearm");
+        if (findRearm != baseConfiguration->second.end())
+        {
+            std::string rearmStr = std::get<std::string>(findRearm->second);
+            if (rearmStr != "Automatic" && rearmStr != "Manual")
+            {
+                std::cerr << "Wrong input for Rearm parameter\n";
+                continue;
+            }
+            autoRearm = (rearmStr == "Automatic");
+        }
+
+        // judge class, "Gpio", "Hwmon" or "I2C"
+        auto findClass = baseConfiguration->second.find("Class");
+        if (findClass != baseConfiguration->second.end())
+        {
+            auto classString = std::get<std::string>(findClass->second);
+            if (classString == "Gpio")
+            {
+                auto findGpioPolarity =
+                    baseConfiguration->second.find("GpioPolarity");
+
+                if (findGpioPolarity == baseConfiguration->second.end())
+                {
+                    std::cerr
+                        << "error finding gpio polarity in configuration \n";
+                    continue;
+                }
+
+                try
+                {
+                    bool gpioInverted =
+                        (std::get<std::string>(findGpioPolarity->second) ==
+                         "Low");
+                    pSensor = std::make_shared<ChassisIntrusionGpioSensor>(
+                        autoRearm, io, objServer, gpioInverted);
+                    pSensor->start();
+                    if (debug)
+                    {
+                        std::cout
+                            << "find chassis intrusion sensor polarity inverted "
+                               "flag is "
+                            << gpioInverted << "\n";
+                    }
+                    return;
+                }
+                catch (const std::bad_variant_access& e)
+                {
+                    std::cerr << "invalid value for gpio info in config. \n";
+                    continue;
+                }
+                catch (const std::exception& e)
+                {
+                    std::cerr << e.what() << std::endl;
+                    continue;
+                }
+            }
+            // If class string contains Hwmon string
+            else if (classString.find("Hwmon") != std::string::npos)
+            {
+                std::string hwmonName;
+                std::map<std::string, std::string>::const_iterator
+                    compatIterator = compatibleHwmonNames.find(classString);
+
+                if (compatIterator == compatibleHwmonNames.end())
+                {
+                    std::cerr << "Hwmon Class string is not supported\n";
+                    continue;
+                }
+
+                hwmonName = compatIterator->second;
+
+                try
+                {
+                    pSensor = std::make_shared<ChassisIntrusionHwmonSensor>(
+                        autoRearm, io, objServer, hwmonName);
+                    pSensor->start();
+                    return;
+                }
+                catch (const std::exception& e)
+                {
+                    std::cerr << e.what() << std::endl;
+                    continue;
+                }
+            }
+            else
+            {
+                auto findBus = baseConfiguration->second.find("Bus");
+                auto findAddress = baseConfiguration->second.find("Address");
+                if (findBus == baseConfiguration->second.end() ||
+                    findAddress == baseConfiguration->second.end())
+                {
+                    std::cerr
+                        << "error finding bus or address in configuration \n";
+                    continue;
+                }
+                try
+                {
+                    int busId = std::get<uint64_t>(findBus->second);
+                    int slaveAddr = std::get<uint64_t>(findAddress->second);
+                    pSensor = std::make_shared<ChassisIntrusionPchSensor>(
+                        autoRearm, io, objServer, busId, slaveAddr);
+                    pSensor->start();
+                    if (debug)
+                    {
+                        std::cout
+                            << "find matched bus " << busId
+                            << ", matched slave addr " << slaveAddr << "\n";
+                    }
+                    return;
+                }
+                catch (const std::bad_variant_access& e)
+                {
+                    std::cerr
+                        << "invalid value for bus or address in config. \n";
+                    continue;
+                }
+                catch (const std::exception& e)
+                {
+                    std::cerr << e.what() << std::endl;
+                    continue;
+                }
+            }
+        }
+    }
+
+    std::cerr << " Can't find matched I2C, GPIO or Hwmon configuration\n";
+
+    // Make sure nothing runs when there's failure in configuration for the
+    // sensor after rescan
+    if (pSensor)
+    {
+        std::cerr << " Reset the occupied sensor pointer\n";
+        pSensor = nullptr;
+    }
+}
+
+static constexpr bool debugLanLeash = false;
+boost::container::flat_map<int, bool> lanStatusMap;
+boost::container::flat_map<int, std::string> lanInfoMap;
+boost::container::flat_map<std::string, int> pathSuffixMap;
+
+static void getNicNameInfo(
+    const std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
+{
+    auto getter = std::make_shared<GetSensorConfiguration>(
+        dbusConnection, [](const ManagedObjectType& sensorConfigurations) {
+            // Get NIC name and save to map
+            lanInfoMap.clear();
+            for (const auto& [path, cfgData] : sensorConfigurations)
+            {
+                const std::pair<std::string, SensorBaseConfigMap>*
+                    baseConfiguration = nullptr;
+
+                // find base configuration
+                auto sensorBase = cfgData.find(configInterfaceName(nicType));
+                if (sensorBase == cfgData.end())
+                {
+                    continue;
+                }
+                baseConfiguration = &(*sensorBase);
+
+                auto findEthIndex = baseConfiguration->second.find("EthIndex");
+                auto findName = baseConfiguration->second.find("Name");
+
+                if (findEthIndex != baseConfiguration->second.end() &&
+                    findName != baseConfiguration->second.end())
+                {
+                    const auto* pEthIndex =
+                        std::get_if<uint64_t>(&findEthIndex->second);
+                    const auto* pName =
+                        std::get_if<std::string>(&findName->second);
+                    if (pEthIndex != nullptr && pName != nullptr)
+                    {
+                        lanInfoMap[*pEthIndex] = *pName;
+                        if (debugLanLeash)
+                        {
+                            std::cout << "find name of eth" << *pEthIndex
+                                      << " is " << *pName << "\n";
+                        }
+                    }
+                }
+            }
+
+            if (lanInfoMap.empty())
+            {
+                std::cerr << "can't find matched NIC name. \n";
+            }
+        });
+
+    getter->getConfiguration(
+        std::vector<std::string>{nicTypes.begin(), nicTypes.end()});
+}
+
+static void processLanStatusChange(sdbusplus::message_t& message)
+{
+    const std::string& pathName = message.get_path();
+    std::string interfaceName;
+    SensorBaseConfigMap properties;
+    message.read(interfaceName, properties);
+
+    auto findStateProperty = properties.find("OperationalState");
+    if (findStateProperty == properties.end())
+    {
+        return;
+    }
+    std::string* pState =
+        std::get_if<std::string>(&(findStateProperty->second));
+    if (pState == nullptr)
+    {
+        std::cerr << "invalid OperationalState \n";
+        return;
+    }
+
+    bool newLanConnected = (*pState == "routable" || *pState == "carrier" ||
+                            *pState == "degraded");
+
+    // get ethNum from path. /org/freedesktop/network1/link/_32 for eth0
+    size_t pos = pathName.find("/_");
+    if (pos == std::string::npos || pathName.length() <= pos + 2)
+    {
+        std::cerr << "unexpected path name " << pathName << "\n";
+        return;
+    }
+    std::string suffixStr = pathName.substr(pos + 2);
+
+    auto findEthNum = pathSuffixMap.find(suffixStr);
+    if (findEthNum == pathSuffixMap.end())
+    {
+        std::cerr << "unexpected eth for suffixStr " << suffixStr << "\n";
+        return;
+    }
+    int ethNum = findEthNum->second;
+
+    // get lan status from map
+    auto findLanStatus = lanStatusMap.find(ethNum);
+    if (findLanStatus == lanStatusMap.end())
+    {
+        std::cerr << "unexpected eth " << ethNum << " in lanStatusMap \n";
+        return;
+    }
+    bool oldLanConnected = findLanStatus->second;
+
+    // get lan info from map
+    std::string lanInfo;
+    if (!lanInfoMap.empty())
+    {
+        auto findLanInfo = lanInfoMap.find(ethNum);
+        if (findLanInfo == lanInfoMap.end())
+        {
+            std::cerr << "unexpected eth " << ethNum << " in lanInfoMap \n";
+        }
+        else
+        {
+            lanInfo = "(" + findLanInfo->second + ")";
+        }
+    }
+
+    if (debugLanLeash)
+    {
+        std::cout << "ethNum = " << ethNum << ", state = " << *pState
+                  << ", oldLanConnected = "
+                  << (oldLanConnected ? "true" : "false")
+                  << ", newLanConnected = "
+                  << (newLanConnected ? "true" : "false") << "\n";
+    }
+
+    if (oldLanConnected != newLanConnected)
+    {
+        std::string strEthNum = "eth" + std::to_string(ethNum) + lanInfo;
+        const auto* strState = newLanConnected ? "connected" : "lost";
+        const auto* strMsgId =
+            newLanConnected ? "OpenBMC.0.1.LanRegained" : "OpenBMC.0.1.LanLost";
+
+        lg2::info("{ETHDEV} LAN leash {STATE}", "ETHDEV", strEthNum, "STATE",
+                  strState, "REDFISH_MESSAGE_ID", strMsgId,
+                  "REDFISH_MESSAGE_ARGS", strEthNum);
+
+        lanStatusMap[ethNum] = newLanConnected;
+    }
+}
+
+/** @brief Initialize the lan status.
+ *
+ * @return true on success and false on failure
+ */
+static bool initializeLanStatus(
+    const std::shared_ptr<sdbusplus::asio::connection>& conn)
+{
+    // init lan port name from configuration
+    getNicNameInfo(conn);
+
+    // get eth info from sysfs
+    std::vector<fs::path> files;
+    if (!findFiles(fs::path("/sys/class/net/"), R"(eth\d+/ifindex)", files))
+    {
+        std::cerr << "No eth in system\n";
+        return false;
+    }
+
+    // iterate through all found eth files, and save ifindex
+    for (const fs::path& fileName : files)
+    {
+        if (debugLanLeash)
+        {
+            std::cout << "Reading " << fileName << "\n";
+        }
+        std::ifstream sysFile(fileName);
+        if (!sysFile.good())
+        {
+            std::cerr << "Failure reading " << fileName << "\n";
+            continue;
+        }
+        std::string line;
+        getline(sysFile, line);
+        const uint8_t ifindex = std::stoi(line);
+        // pathSuffix is ASCII of ifindex
+        const std::string& pathSuffix = std::to_string(ifindex + 30);
+
+        // extract ethNum
+        const std::string& fileStr = fileName.string();
+        const int pos = fileStr.find("eth");
+        const std::string& ethNumStr = fileStr.substr(pos + 3);
+        int ethNum = 0;
+        std::from_chars_result r = std::from_chars(
+            ethNumStr.data(), ethNumStr.data() + ethNumStr.size(), ethNum);
+        if (r.ec != std::errc())
+        {
+            std::cerr << "invalid ethNum string: " << ethNumStr << "\n";
+            continue;
+        }
+
+        // save pathSuffix
+        pathSuffixMap[pathSuffix] = ethNum;
+        if (debugLanLeash)
+        {
+            std::cout << "ethNum = " << std::to_string(ethNum) << ", ifindex = "
+                      << line << ", pathSuffix = " << pathSuffix << "\n";
+        }
+
+        // init lan connected status from networkd
+        conn->async_method_call(
+            [ethNum](boost::system::error_code ec,
+                     const std::variant<std::string>& property) {
+                lanStatusMap[ethNum] = false;
+                if (ec)
+                {
+                    std::cerr
+                        << "Error reading init status of eth" << ethNum << "\n";
+                    return;
+                }
+                const std::string* pState = std::get_if<std::string>(&property);
+                if (pState == nullptr)
+                {
+                    std::cerr << "Unable to read lan status value\n";
+                    return;
+                }
+                bool isLanConnected =
+                    (*pState == "routable" || *pState == "carrier" ||
+                     *pState == "degraded");
+                if (debugLanLeash)
+                {
+                    std::cout << "ethNum = " << std::to_string(ethNum)
+                              << ", init LAN status = "
+                              << (isLanConnected ? "true" : "false") << "\n";
+                }
+                lanStatusMap[ethNum] = isLanConnected;
+            },
+            "org.freedesktop.network1",
+            "/org/freedesktop/network1/link/_" + pathSuffix,
+            "org.freedesktop.DBus.Properties", "Get",
+            "org.freedesktop.network1.Link", "OperationalState");
+    }
+    return true;
+}
+
+int main()
+{
+    std::shared_ptr<ChassisIntrusionSensor> intrusionSensor;
+
+    // setup connection to dbus
+    boost::asio::io_context io;
+    auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
+
+    // setup object server, define interface
+    systemBus->request_name("xyz.openbmc_project.IntrusionSensor");
+
+    sdbusplus::asio::object_server objServer(systemBus, true);
+
+    objServer.add_manager("/xyz/openbmc_project/Chassis");
+
+    createSensorsFromConfig(io, objServer, systemBus, intrusionSensor);
+
+    // callback to handle configuration change
+    boost::asio::steady_timer filterTimer(io);
+    std::function<void(sdbusplus::message_t&)> eventHandler =
+        [&](sdbusplus::message_t& message) {
+            if (message.is_method_error())
+            {
+                std::cerr << "callback method error\n";
+                return;
+            }
+            // this implicitly cancels the timer
+            filterTimer.expires_after(std::chrono::seconds(1));
+            filterTimer.async_wait([&](const boost::system::error_code& ec) {
+                if (ec == boost::asio::error::operation_aborted)
+                {
+                    // timer was cancelled
+                    return;
+                }
+                std::cout << "rescan due to configuration change \n";
+                createSensorsFromConfig(io, objServer, systemBus,
+                                        intrusionSensor);
+            });
+        };
+
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(
+            *systemBus, std::to_array<const char*>({sensorType}), eventHandler);
+
+    if (initializeLanStatus(systemBus))
+    {
+        // add match to monitor lan status change
+        sdbusplus::bus::match_t lanStatusMatch(
+            static_cast<sdbusplus::bus_t&>(*systemBus),
+            "type='signal', member='PropertiesChanged',"
+            "arg0namespace='org.freedesktop.network1.Link'",
+            [](sdbusplus::message_t& msg) { processLanStatusChange(msg); });
+
+        // add match to monitor entity manager signal about nic name config
+        // change
+        sdbusplus::bus::match_t lanConfigMatch(
+            static_cast<sdbusplus::bus_t&>(*systemBus),
+            "type='signal', member='PropertiesChanged',path_namespace='" +
+                std::string(inventoryPath) + "',arg0namespace='" +
+                configInterfaceName(nicType) + "'",
+            [&systemBus](sdbusplus::message_t& msg) {
+                if (msg.is_method_error())
+                {
+                    std::cerr << "callback method error\n";
+                    return;
+                }
+                getNicNameInfo(systemBus);
+            });
+    }
+
+    io.run();
+
+    return 0;
+}
diff --git a/src/intrusion/meson.build b/src/intrusion/meson.build
new file mode 100644
index 0000000..f88d2c9
--- /dev/null
+++ b/src/intrusion/meson.build
@@ -0,0 +1,15 @@
+src_inc = include_directories('..')
+
+executable(
+    'intrusionsensor',
+    'ChassisIntrusionSensor.cpp',
+    'IntrusionSensorMain.cpp',
+    dependencies: [
+        default_deps,
+        gpiodcxx,
+        i2c,
+        utils_dep,
+    ],
+    include_directories: src_inc,
+    install: true,
+)
\ No newline at end of file
