firmware: implement stat command

Implement the BmcBlobStat command for the generic blob_ids, versus the
active ones.

Also, reduce the size of our transport bits to match the use-case state.

Change-Id: I9e2b28134026e8abfa18952dc80c526f0325308f
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/firmware_handler.cpp b/firmware_handler.cpp
index b828002..41bf853 100644
--- a/firmware_handler.cpp
+++ b/firmware_handler.cpp
@@ -16,7 +16,7 @@
 
 std::unique_ptr<GenericBlobInterface>
     FirmwareBlobHandler::CreateFirmwareBlobHandler(
-        const std::vector<std::string>& firmwares, std::uint32_t transports)
+        const std::vector<std::string>& firmwares, std::uint16_t transports)
 {
     /* There must be at least one. */
     if (!firmwares.size())
@@ -73,6 +73,27 @@
      * of the data cached, and any additional pertinent information.  The
      * blob_state on the active files will return the state of the update.
      */
+
+    /* We know we support this path because canHandle is called ahead */
+    if (path == FirmwareBlobHandler::activeImageBlobID)
+    {
+        /* We need to return information for the image that's staged. */
+    }
+    else if (path == FirmwareBlobHandler::activeHashBlobID)
+    {
+        /* We need to return information for the hash that's staged. */
+    }
+    else
+    {
+        /* They are requesting information about the generic blob_id. */
+        meta->blobState = transports;
+        meta->size = 0;
+
+        /* The generic blob_ids state is only the bits related to the transport
+         * mechanisms. */
+        return true;
+    }
+
     return false;
 }
 
@@ -154,8 +175,7 @@
 bool FirmwareBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
 {
     /*
-     * Return the supported mechanisms if it's the handler blob_id, versus
-     * the active one.
+     * Return session specific information.
      */
     return false;
 }
diff --git a/firmware_handler.hpp b/firmware_handler.hpp
index 916a5ce..9d57b63 100644
--- a/firmware_handler.hpp
+++ b/firmware_handler.hpp
@@ -30,7 +30,7 @@
      */
     static std::unique_ptr<GenericBlobInterface>
         CreateFirmwareBlobHandler(const std::vector<std::string>& firmwares,
-                                  std::uint32_t transports);
+                                  std::uint16_t transports);
 
     /**
      * Create a FirmwareBlobHandler.
@@ -39,7 +39,7 @@
      * @param[in] transports - bitmask of transports to support.
      */
     FirmwareBlobHandler(const std::vector<std::string>& blobs,
-                        std::uint32_t transports) :
+                        std::uint16_t transports) :
         blobIDs(blobs),
         transports(transports)
     {
@@ -73,7 +73,7 @@
 
   private:
     std::vector<std::string> blobIDs;
-    std::uint32_t transports;
+    std::uint16_t transports;
 };
 
 } // namespace blobs
diff --git a/main.cpp b/main.cpp
index ec0f53b..f6d63da 100644
--- a/main.cpp
+++ b/main.cpp
@@ -17,18 +17,18 @@
 #endif
 };
 
-std::uint32_t supportedTransports =
-    static_cast<std::uint32_t>(FirmwareUpdateFlags::bt);
+std::uint16_t supportedTransports =
+    static_cast<std::uint16_t>(FirmwareUpdateFlags::bt);
 
 void setupFirmwareHandler() __attribute__((constructor));
 
 void setupFirmwareHandler()
 {
 #ifdef ENABLE_PCI_BRIDGE
-    supportedTransports |= static_cast<std::uint32_t>(FirmwareUpdateFlags::p2a);
+    supportedTransports |= static_cast<std::uint16_t>(FirmwareUpdateFlags::p2a);
 #endif
 #ifdef ENABLE_LPC_BRIDGE
-    supportedTransports |= static_cast<std::uint32_t>(FirmwareUpdateFlags::lpc);
+    supportedTransports |= static_cast<std::uint16_t>(FirmwareUpdateFlags::lpc);
 #endif
 
     auto handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
diff --git a/test/Makefile.am b/test/Makefile.am
index d3a971d..9afb25a 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -10,10 +10,14 @@
 
 # Run all 'check' test programs
 check_PROGRAMS = \
-	firmware_handler
+	firmware_handler \
+	firmware_stat
 
 TESTS = $(check_PROGRAMS)
 
 firmware_handler_SOURCES = firmware_handler_unittest.cpp
 firmware_handler_LDADD = $(top_builddir)/firmware_handler.o
 
+firmware_stat_SOURCES = firmware_stat_unittest.cpp
+firmware_stat_LDADD = $(top_builddir)/firmware_handler.o
+
diff --git a/test/firmware_stat_unittest.cpp b/test/firmware_stat_unittest.cpp
new file mode 100644
index 0000000..b872b16
--- /dev/null
+++ b/test/firmware_stat_unittest.cpp
@@ -0,0 +1,25 @@
+#include "firmware_handler.hpp"
+
+#include <memory>
+
+#include <gtest/gtest.h>
+
+namespace blobs
+{
+TEST(FirmwareHandlerStatTest, StatOnInactiveBlobIDReturnsTransport)
+{
+    /* Test that the metadata information returned matches expectations for this
+     * case.
+     *
+     * canHandle has already been called at this point, so we don't need to test
+     * the input for this function.
+     */
+
+    auto handler = FirmwareBlobHandler::CreateFirmwareBlobHandler(
+        {"asdf"}, static_cast<uint16_t>(FirmwareUpdateFlags::bt));
+    struct BlobMeta meta;
+    EXPECT_TRUE(handler->stat("asdf", &meta));
+    EXPECT_EQ(static_cast<uint16_t>(FirmwareUpdateFlags::bt), meta.blobState);
+}
+
+} // namespace blobs