Fill in NameOwnerChanged signal support

A NameOwnerChanged signal message provides three strings containing the
service name that has changed along with its old service owner name and
new service owner name. These names are then passed along to the handler
to find/update the group associated with the changed owner name.

Change-Id: I7d67883b010fec5b282bd00a4dcc29629486af00
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/control/functor.hpp b/control/functor.hpp
index 1f3e4d8..faf0d3e 100644
--- a/control/functor.hpp
+++ b/control/functor.hpp
@@ -13,6 +13,7 @@
 class Zone;
 
 using namespace phosphor::fan;
+using namespace sdbusplus::bus::match;
 using namespace phosphor::logging;
 using InternalFailure = sdbusplus::xyz::openbmc_project::Common::
                                 Error::InternalFailure;
@@ -283,14 +284,47 @@
                     sdbusplus::message::message& msg,
                     Zone& zone) const
     {
+        std::string name;
+        bool hasOwner = false;
         if (msg)
         {
-            // TODO Handle NameOwnerChanged signals
+            // Handle NameOwnerChanged signals
+            msg.read(name);
+
+            std::string oldOwn;
+            msg.read(oldOwn);
+
+            std::string newOwn;
+            msg.read(newOwn);
+            if (!newOwn.empty())
+            {
+                hasOwner = true;
+            }
         }
         else
         {
-            // TODO Initialize NameOwnerChanged data store with service names
+            try
+            {
+                // Initialize NameOwnerChanged data store with service name
+                name = util::SDBusPlus::getService(bus,
+                                                   _path,
+                                                   _iface);
+                hasOwner = util::SDBusPlus::callMethodAndRead<bool>(
+                        bus,
+                        "org.freedesktop.DBus",
+                        "/org/freedesktop/DBus",
+                        "org.freedesktop.DBus",
+                        "NameHasOwner",
+                        name);
+            }
+            catch (const InternalFailure& ife)
+            {
+                // Failed to get service name owner state
+                hasOwner = false;
+            }
         }
+
+        _handler(zone, name, hasOwner);
     }
 
 private:
diff --git a/control/handlers.hpp b/control/handlers.hpp
index 3f42d3c..96cfa2f 100644
--- a/control/handlers.hpp
+++ b/control/handlers.hpp
@@ -44,7 +44,8 @@
 {
     return [group = std::move(group)](auto& zone, auto& name, bool hasOwner)
     {
-        // TODO Update service name owner state list of a group
+        // Update service name owner state list of a group
+        zone.setServiceOwner(&group, name, hasOwner);
     };
 }