tools: start implementing blob interface

Start implementing blob interface to handle sending BLOB protocol
commands.

Change-Id: I9eeb6c1b6f49d9b0332e156e02476e2b07850d64
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 1d7d814..66cfa0e 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -10,4 +10,5 @@
 libupdater_la_SOURCES = \
 	updater.cpp \
 	bt.cpp \
-	lpc.cpp
+	lpc.cpp \
+	blob_handler.cpp
diff --git a/tools/blob_handler.cpp b/tools/blob_handler.cpp
new file mode 100644
index 0000000..a2fe9d3
--- /dev/null
+++ b/tools/blob_handler.cpp
@@ -0,0 +1,6 @@
+#include "blob_handler.hpp"
+
+std::vector<std::string> BlobHandler::getBlobList()
+{
+    return {};
+}
diff --git a/tools/blob_handler.hpp b/tools/blob_handler.hpp
new file mode 100644
index 0000000..042953b
--- /dev/null
+++ b/tools/blob_handler.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "blob_interface.hpp"
+
+class BlobHandler : public BlobInterface
+{
+  public:
+    BlobHandler() = default;
+
+    std::vector<std::string> getBlobList() override;
+};
diff --git a/tools/blob_interface.hpp b/tools/blob_interface.hpp
new file mode 100644
index 0000000..ce2b2d7
--- /dev/null
+++ b/tools/blob_interface.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+class BlobInterface
+{
+
+  public:
+    virtual ~BlobInterface() = default;
+
+    /**
+     * Get a list of the blob_ids provided by the BMC.
+     *
+     * @return list of strings, each representing a blob_id returned.
+     */
+    virtual std::vector<std::string> getBlobList() = 0;
+};
diff --git a/tools/bt.hpp b/tools/bt.hpp
index dbd5c8c..e005937 100644
--- a/tools/bt.hpp
+++ b/tools/bt.hpp
@@ -1,11 +1,15 @@
 #pragma once
 
+#include "blob_interface.hpp"
 #include "interface.hpp"
 
 class BtDataHandler : public DataInterface
 {
   public:
-    BtDataHandler() = default;
+    explicit BtDataHandler(BlobInterface* blob) : blob(blob){};
 
     bool sendContents(const std::string& input, std::uint16_t session) override;
+
+  private:
+    BlobInterface* blob;
 };
diff --git a/tools/lpc.hpp b/tools/lpc.hpp
index de35c1b..c60fd99 100644
--- a/tools/lpc.hpp
+++ b/tools/lpc.hpp
@@ -1,11 +1,15 @@
 #pragma once
 
+#include "blob_interface.hpp"
 #include "interface.hpp"
 
 class LpcDataHandler : public DataInterface
 {
   public:
-    LpcDataHandler() = default;
+    explicit LpcDataHandler(BlobInterface* blob) : blob(blob){};
 
     bool sendContents(const std::string& input, std::uint16_t session) override;
+
+  private:
+    BlobInterface* blob;
 };
diff --git a/tools/main.cpp b/tools/main.cpp
index 7bbf380..07a169b 100644
--- a/tools/main.cpp
+++ b/tools/main.cpp
@@ -14,12 +14,14 @@
  * limitations under the License.
  */
 
+#include "blob_handler.hpp"
 #include "updater.hpp"
 
 /* Use CLI11 argument parser once in openbmc/meta-oe or whatever. */
 #include <getopt.h>
 
 #include <cstdio>
+#include <memory>
 #include <string>
 
 void usage(const char* program)
@@ -104,8 +106,10 @@
             exit(EXIT_FAILURE);
         }
 
+        BlobHandler blob;
+
         /* The parameters are all filled out. */
-        return updaterMain(interface, imagePath, signaturePath);
+        return updaterMain(&blob, interface, imagePath, signaturePath);
     }
 
     return 0;
diff --git a/tools/test/blob_interface_mock.hpp b/tools/test/blob_interface_mock.hpp
new file mode 100644
index 0000000..1e57771
--- /dev/null
+++ b/tools/test/blob_interface_mock.hpp
@@ -0,0 +1,8 @@
+#include "blob_interface.hpp"
+
+class BlobInterfaceMock : public BlobInterface
+{
+  public:
+    virtual ~BlobInterfaceMock() = default;
+    MOCK_METHOD0(getBlobList, std::vector<std::string>());
+};
diff --git a/tools/updater.cpp b/tools/updater.cpp
index 4041d4c..6abbe17 100644
--- a/tools/updater.cpp
+++ b/tools/updater.cpp
@@ -20,21 +20,22 @@
 #include "interface.hpp"
 #include "lpc.hpp"
 
+#include <algorithm>
 #include <memory>
 
-int updaterMain(const std::string& interface, const std::string& imagePath,
-                const std::string& signaturePath)
+int updaterMain(BlobInterface* blob, const std::string& interface,
+                const std::string& imagePath, const std::string& signaturePath)
 {
     std::unique_ptr<DataInterface> handler;
 
     /* Input has already been validated in this case. */
     if (interface == "ipmibt")
     {
-        handler = std::make_unique<BtDataHandler>();
+        handler = std::make_unique<BtDataHandler>(blob);
     }
     else if (interface == "ipmilpc")
     {
-        handler = std::make_unique<LpcDataHandler>();
+        handler = std::make_unique<LpcDataHandler>(blob);
     }
 
     if (!handler)
@@ -48,7 +49,16 @@
     /* TODO(venture): Add optional parameter to specify the flash type, default
      * to legacy for now.
      */
-    std::string goalfirmware = "/flash/image";
+    std::string goalFirmware = "/flash/image";
+
+    std::vector<std::string> blobs = blob->getBlobList();
+
+    auto blobInst = std::find(blobs.begin(), blobs.end(), goalFirmware);
+    if (blobInst == blobs.end())
+    {
+        std::fprintf(stderr, "firmware goal not found!\n");
+        return -1; /* throw custom exception. */
+    }
 
     /* Get list of blob_ids, check for /flash/image, or /flash/tarball.
      * TODO(venture) the mechanism doesn't care, but the caller of burn_my_bmc
@@ -57,7 +67,8 @@
      */
 
     /* Call stat on /flash/image (or /flash/tarball) and check if data interface
-     * is supported. */
+     * is supported.
+     */
 
     return 0;
 }
diff --git a/tools/updater.hpp b/tools/updater.hpp
index c17025e..0f32363 100644
--- a/tools/updater.hpp
+++ b/tools/updater.hpp
@@ -1,14 +1,17 @@
 #pragma once
 
+#include "blob_interface.hpp"
+
 #include <string>
 
 /**
  * Attempt to update the BMC's firmware using the interface provided.
  *
+ * @param[in] blob - pointer to blob interface implementation object.
  * @param[in] interface - the interface to use.
  * @param[in] imagePath - the path to the image file.
  * @param[in] signaturePath - the path to the signature file.
  * @return non-zero on failure.
  */
-int updaterMain(const std::string& interface, const std::string& imagePath,
-                const std::string& signaturePath);
+int updaterMain(BlobInterface* blob, const std::string& interface,
+                const std::string& imagePath, const std::string& signaturePath);