Add overriding methods for the base interface definition

Defines the functions that override the default setter for
the led state property.

Change-Id: Ic3a8d43cc783003c43f53df8f7e90d7fc4d6715a
Signed-off-by: Vishwanatha Subbanna <vishwa@linux.vnet.ibm.com>
diff --git a/Makefile.am b/Makefile.am
index b82fdf8..ddb81e3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,7 +2,8 @@
 
 phosphor_ledcontroller_SOURCES = \
 				controller.cpp  \
-				argument.cpp 	 \
+				argument.cpp 	\
+				physical.cpp	\
 				xyz.openbmc_project.Led.Physical.cpp
 
 phosphor_ledcontroller_LDFLAGS = $(SYSTEMD_LIBS)
diff --git a/argument.cpp b/argument.cpp
index 3df84e7..7b70fe0 100644
--- a/argument.cpp
+++ b/argument.cpp
@@ -28,10 +28,9 @@
 const std::string ArgumentParser::true_string = "true";
 const std::string ArgumentParser::empty_string = "";
 
-const char* ArgumentParser::optionstr = "n:p:?h";
+const char* ArgumentParser::optionstr = "p:?h";
 const option ArgumentParser::options[] =
 {
-    { "name",   required_argument,  nullptr,   'n' },
     { "path",   required_argument,  nullptr,   'p' },
     { "help",   no_argument,        nullptr,   'h' },
     { 0, 0, 0, 0},
@@ -74,8 +73,6 @@
     std::cerr << "Usage: " << argv[0] << " [options]" << std::endl;
     std::cerr << "Options:" << std::endl;
     std::cerr << "    --help               Print this menu" << std::endl;
-    std::cerr << "    --name=<name>        Name of the LED"
-              << std::endl;
     std::cerr << "    --path=<path>        sysfs path like /sys/class/leds"
               << std::endl;
 }
diff --git a/controller.cpp b/controller.cpp
index bfc1c74..656c9bf 100644
--- a/controller.cpp
+++ b/controller.cpp
@@ -15,7 +15,10 @@
  */
 
 #include <iostream>
+#include <string>
 #include "argument.hpp"
+#include "physical.hpp"
+#include "config.h"
 
 static void ExitWithError(const char* err, char** argv)
 {
@@ -30,19 +33,46 @@
     // Read arguments.
     auto options = phosphor::led::ArgumentParser(argc, argv);
 
-    // Parse out Name argument.
-    auto name = std::move((options)["name"]);
-    if (name == phosphor::led::ArgumentParser::empty_string)
-    {
-        ExitWithError("Name not specified.", argv);
-    }
-
-    // Parse out Name argument.
+    // Parse out Path argument.
     auto path = std::move((options)["path"]);
     if (path == phosphor::led::ArgumentParser::empty_string)
     {
         ExitWithError("Path not specified.", argv);
     }
 
+    // Extract the name of LED from path.
+    auto index = path.rfind("/");
+    if (index == std::string::npos)
+    {
+        throw std::runtime_error("No Led in " + path);
+    }
+
+    // Remove the leading "/"
+    auto name = path.substr(index + 1);
+
+    // Unique bus name representing a single LED.
+    auto busName =  std::string(BUSNAME) + '.' + name;
+    auto objPath =  std::string(OBJPATH) + '/' + name;
+
+    // Get a handle to system dbus.
+    auto bus = std::move(sdbusplus::bus::new_default());
+
+    // Add systemd object manager.
+    sdbusplus::server::manager::manager(bus, objPath.c_str());
+
+    // Create the Physical LED objects for directing actions.
+    // Need to save this else sdbusplus destructor will wipe this off.
+    auto obj = phosphor::led::Physical(bus, objPath, path);
+
+    /** @brief Claim the bus */
+    bus.request_name(busName.c_str());
+
+    /** @brief Wait for client requests */
+    while(true)
+    {
+        // Handle dbus message / signals discarding unhandled
+        bus.process_discard();
+        bus.wait();
+    }
     return 0;
 }
diff --git a/physical.cpp b/physical.cpp
new file mode 100644
index 0000000..31fc1ee
--- /dev/null
+++ b/physical.cpp
@@ -0,0 +1,58 @@
+/**
+ * Copyright © 2016 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.
+ */
+
+#include <iostream>
+#include <string>
+#include "physical.hpp"
+namespace phosphor
+{
+namespace led
+{
+
+/** @brief Populates key parameters */
+void Physical::setInitialState()
+{
+    // 1. read /sys/class/leds/name/trigger
+    // 2. If its 'timer', then its blinking.
+    //    2.1: On blink, use delay_on and delay_off into dutyOn
+    // 3. If its 'none', then read brightness. 255 means, its ON, else OFF.
+    // Implementation in the next patchset.
+}
+
+/** @brief Overloaded State Property Setter function */
+auto Physical::state(Action value) -> Action
+{
+    // Set the base class's state to actuals since the getter
+    // operation is handled there.
+    auto action = sdbusplus::xyz::openbmc_project::Led::server
+                                   ::Physical::state(value);
+
+    // Apply the action.
+    driveLED();
+
+    return action;
+}
+
+/** @brief apply action on the LED */
+void Physical::driveLED()
+{
+    // Replace with actual code.
+    std::cout << " Drive LED  STUB :: \n";
+    return;
+}
+
+} // namespace led
+} // namespace phosphor
diff --git a/physical.hpp b/physical.hpp
index f0b4048..0eac97b 100644
--- a/physical.hpp
+++ b/physical.hpp
@@ -20,10 +20,13 @@
         ~Physical() = default;
         Physical(const Physical&) = delete;
         Physical& operator=(const Physical&) = delete;
-        Physical(Physical&&) = delete;
-        Physical& operator=(Physical&&) = delete;
+        Physical(Physical&&) = default;
+        Physical& operator=(Physical&&) = default;
 
-        /** @brief Constructs LED object
+        /** @brief Constructs LED object. Argument 'true' says that we hold off
+         *   from sending the signals since we need to do some house keeping and
+         *   only when we finish that, we are considered active and can then
+         *   broadcast the signal.
          *
          * @param[in] bus       - system dbus handler
          * @param[in] objPath   - The Dbus path that hosts physical LED
@@ -35,18 +38,43 @@
 
             sdbusplus::server::object::object<
                 sdbusplus::xyz::openbmc_project::Led::server::Physical>(
-                        bus, objPath.c_str()),
+                        bus, objPath.c_str(), true),
             path(ledPath)
         {
-                // Nothing to do here
+            // Suppose this is getting launched as part of BMC reboot, then we
+            // need to save what the micro-controller currently has.
+            setInitialState();
+
+            // We are now ready.
+            emit_object_added();
         }
 
+        /** @brief Overloaded State Property Setter function
+         *
+         *  @param[in] value   -  One of OFF / ON / BLINK
+         *  @return            -  Success or exception thrown
+         */
+        Action state(Action value) override;
+
     private:
         /** @brief File system location where this LED is exposed
          *   Typically /sys/class/leds/<Led-Name>
          */
         std::string path;
+
+        /** @brief Applies the user triggered action on the LED
+         *   by writing to sysfs
+         *
+         *  @return None
+         */
+        void driveLED(void);
+
+        /** @brief reads sysfs and then setsup the parameteres accordingly
+         *
+         *  @return Status or exception thrown
+         */
+        void setInitialState(void);
 };
 
 } // namespace led
-} // namespace phosphor
+}