diff --git a/listener.cpp b/listener.cpp
new file mode 100644
index 0000000..c8ae642
--- /dev/null
+++ b/listener.cpp
@@ -0,0 +1,208 @@
+#include <libpdbg.h>
+
+#include <attn/attn_main.hpp>
+#include <boost/interprocess/ipc/message_queue.hpp>
+#include <cli.hpp>
+#include <listener.hpp>
+
+/** @brief openpower-hw-diags message queue name */
+static constexpr const char* mq_listener = "openpower-hw-diags-mq";
+
+/** @brief maximum length of command line parameter */
+static constexpr int max_command_len = 25;
+
+/** @brief end of command line args message */
+static const char* msg_send_end = "999999999999999";
+
+/** @brief structure for holding main args (for threads) */
+typedef struct
+{
+    int argc;
+    char** argv;
+} MainArgs_t;
+
+/**
+ * @brief Start a thread to monitor the attention GPIO
+ *
+ * @param i_config Attention handler configuration object
+ */
+void* threadGpioMon(void* i_config)
+{
+    // Configure and start attention monitor
+    attn::attnDaemon((attn::Config*)i_config);
+
+    pthread_exit(NULL);
+}
+
+/** @brief Start a thread to listen for attention handler messages */
+void* threadListener(void* i_params)
+{
+    using namespace boost::interprocess;
+
+    // convert thread params to main arguments
+    int argc    = static_cast<MainArgs_t*>(i_params)->argc;
+    char** argv = static_cast<MainArgs_t*>(i_params)->argv;
+
+    // vector to hold messages sent to listener
+    std::vector<std::string> messages;
+
+    // remove listener message queue if exists (does not throw)
+    message_queue::remove(mq_listener);
+
+    // thread handle for gpio monitor
+    pthread_t ptidGpio;
+
+    // status of gpio monitor
+    bool gpioMonEnabled = false;
+
+    // Parse command line args to see if any flags were passed, update the
+    // booleans accordingly and pass them to the config object constructor.
+    bool vital_enable     = true;
+    bool checkstop_enable = true;
+    bool ti_enable        = true;
+    bool bp_enable        = true;
+
+    // parse config options
+    parseConfig(argv, argv + argc, vital_enable, checkstop_enable, ti_enable,
+                bp_enable);
+
+    // create config
+    attn::Config config(vital_enable, checkstop_enable, ti_enable, bp_enable);
+
+    // initialize pdbg targets
+    pdbg_targets_init(nullptr);
+
+    // This is the main listener loop. All the above code will be executed
+    // only once. All other communtication with the attention handler will
+    // originate from here via the message queue.
+    do
+    {
+        // we will catch any exceptions from thread library
+        try
+        {
+            // create new message queue or open existing
+            message_queue mq(open_or_create, mq_listener, 1, max_command_len);
+
+            // message queue parameters
+            char buffer[max_command_len + 1];
+            size_t recvd_size;
+            unsigned int priority;
+
+            // We will continue receiving messages until we receive
+            // a msg_send_end message to indicate all command line parameters
+            // have been sent.
+            do
+            {
+                // wait for a message to arrive
+                mq.receive((void*)&buffer, max_command_len, recvd_size,
+                           priority);
+
+                // null terminate message and store
+                buffer[recvd_size] = '\0';
+                messages.push_back(buffer);
+
+            } while (buffer != std::string(msg_send_end));
+
+            messages.pop_back(); // remove msg_send_end message
+
+            // convert messages to command line arguments
+            std::vector<char*> argv;
+
+            for (const auto& arg : messages)
+            {
+                argv.push_back((char*)arg.data());
+            }
+
+            int argc = argv.size();
+            argv.push_back(nullptr);
+
+            // stop attention handler daemon?
+            if (true == getCliOption(argv.data(), argv.data() + argc, "--stop"))
+            {
+                message_queue::remove(mq_listener);
+                break;
+            }
+
+            // parse config options
+            parseConfig(argv.data(), argv.data() + argc, vital_enable,
+                        checkstop_enable, ti_enable, bp_enable);
+
+            // set config
+            config.setConfig(vital_enable, checkstop_enable, ti_enable,
+                             bp_enable);
+
+            // start attention handler daemon?
+            if (true ==
+                getCliOption(argv.data(), argv.data() + argc, "--start"))
+            {
+                if (false == gpioMonEnabled)
+                {
+                    if (0 == pthread_create(&ptidGpio, NULL, &threadGpioMon,
+                                            &config))
+                    {
+                        gpioMonEnabled = true;
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+            }
+        }
+
+        catch (interprocess_exception& e)
+        {
+            break;
+        }
+    } while (1);
+
+    // stop the gpio monitor if running
+    if (true == gpioMonEnabled)
+    {
+        pthread_cancel(ptidGpio);
+    }
+
+    pthread_exit(NULL);
+}
+
+/** @brief Send command line to a threadi */
+int sendCmdLine(int i_argc, char** i_argv)
+{
+    int count = 0; // number of arguments sent
+
+    using namespace boost::interprocess;
+
+    try
+    {
+        message_queue mq(open_only, mq_listener);
+
+        while (count < i_argc)
+        {
+            mq.send(i_argv[count], strlen(i_argv[count]), 0);
+            count++;
+        }
+        // indicate to listener last cmdline arg was sent
+        mq.send(msg_send_end, strlen(msg_send_end), 0);
+    }
+    catch (interprocess_exception& e)
+    {
+        count = 0; // assume no arguments sent
+    }
+    return count;
+}
+
+/** @brief See if the listener thread message queue exists */
+bool listenerMqExists()
+{
+    using namespace boost::interprocess;
+
+    try
+    {
+        message_queue mq(open_only, mq_listener);
+        return true;
+    }
+    catch (interprocess_exception& e)
+    {
+        return false;
+    }
+}
