tools: move interface building into main

Move interface building into the main method to simplify processing and
input further down the call stack.

Change-Id: Ib14827bfe8c4ea89a04a7c201fdff9d538546ef5
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/tools/main.cpp b/tools/main.cpp
index 95657dc..218eebe 100644
--- a/tools/main.cpp
+++ b/tools/main.cpp
@@ -15,22 +15,46 @@
  */
 
 #include "blob_handler.hpp"
+#include "bt.hpp"
 #include "ipmi_handler.hpp"
+#include "lpc.hpp"
 #include "updater.hpp"
 
 /* Use CLI11 argument parser once in openbmc/meta-oe or whatever. */
 #include <getopt.h>
 
+#include <algorithm>
 #include <cstdio>
 #include <memory>
+#include <sstream>
 #include <string>
+#include <vector>
+
+#define IPMILPC "ipmilpc"
+#define IPMIBT "ipmibt"
+
+namespace
+{
+const std::vector<std::string> interfaceList = {IPMIBT, IPMILPC};
+}
 
 void usage(const char* program)
 {
+    std::ostringstream intfs;
+
+    /* can use std::accumulate(), also probably loads of better ways
+     */
+    for (const auto& intf : interfaceList)
+    {
+        intfs << intf << ", ";
+    }
+
     std::fprintf(stderr,
                  "Usage: %s -command <command> -interface <interface> -image "
-                 "<image file> -sig <signature file>",
+                 "<image file> -sig <signature file>\n",
                  program);
+
+    std::fprintf(stderr, "interfaces: %s", intfs.str().c_str());
 }
 
 bool checkCommand(const std::string& command)
@@ -40,7 +64,9 @@
 
 bool checkInterface(const std::string& interface)
 {
-    return (interface == "ipmibt" || interface == "ipmilpc");
+    auto intf =
+        std::find(interfaceList.begin(), interfaceList.end(), interface);
+    return (intf != interfaceList.end());
 }
 
 int main(int argc, char* argv[])
@@ -110,8 +136,28 @@
         IpmiHandler ipmi;
         BlobHandler blob(&ipmi);
 
+        std::unique_ptr<DataInterface> handler;
+
+        /* Input has already been validated in this case. */
+        if (interface == IPMIBT)
+        {
+            handler = std::make_unique<BtDataHandler>(&blob);
+        }
+        else if (interface == IPMILPC)
+        {
+            handler = std::make_unique<LpcDataHandler>(&blob);
+        }
+
+        if (!handler)
+        {
+            /* TODO(venture): use a custom exception. */
+            std::fprintf(stderr, "Interface %s is unavailable\n",
+                         interface.c_str());
+            exit(EXIT_FAILURE);
+        }
+
         /* The parameters are all filled out. */
-        return updaterMain(&blob, interface, imagePath, signaturePath);
+        return updaterMain(&blob, handler.get(), imagePath, signaturePath);
     }
 
     return 0;
diff --git a/tools/updater.cpp b/tools/updater.cpp
index 6abbe17..817b6f1 100644
--- a/tools/updater.cpp
+++ b/tools/updater.cpp
@@ -16,36 +16,12 @@
 
 #include "updater.hpp"
 
-#include "bt.hpp"
-#include "interface.hpp"
-#include "lpc.hpp"
-
 #include <algorithm>
 #include <memory>
 
-int updaterMain(BlobInterface* blob, const std::string& interface,
+int updaterMain(BlobInterface* blob, DataInterface* handler,
                 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>(blob);
-    }
-    else if (interface == "ipmilpc")
-    {
-        handler = std::make_unique<LpcDataHandler>(blob);
-    }
-
-    if (!handler)
-    {
-        /* TODO(venture): use a custom exception. */
-        std::fprintf(stderr, "Interface %s is unavailable\n",
-                     interface.c_str());
-        return -1;
-    }
-
     /* TODO(venture): Add optional parameter to specify the flash type, default
      * to legacy for now.
      */
diff --git a/tools/updater.hpp b/tools/updater.hpp
index 0f32363..331b3a2 100644
--- a/tools/updater.hpp
+++ b/tools/updater.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "blob_interface.hpp"
+#include "interface.hpp"
 
 #include <string>
 
@@ -8,10 +9,10 @@
  * 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] handler - pointer to the data interface implementation object.
  * @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(BlobInterface* blob, const std::string& interface,
+int updaterMain(BlobInterface* blob, DataInterface* handler,
                 const std::string& imagePath, const std::string& signaturePath);