tools: blob: implement open blob

Implement the host-side tool's open blob command.

Change-Id: Iee432eae0539015e87969159a3d03761df9f8fb5
Signed-off-by: Patrick Venture <venture@google.com>
diff --git a/tools/blob_handler.cpp b/tools/blob_handler.cpp
index a30eb9e..dd4a97c 100644
--- a/tools/blob_handler.cpp
+++ b/tools/blob_handler.cpp
@@ -16,6 +16,7 @@
 
 #include "blob_handler.hpp"
 
+#include "blob_errors.hpp"
 #include "crc.hpp"
 #include "ipmi_errors.hpp"
 
@@ -169,3 +170,26 @@
 
     return meta;
 }
+
+std::uint16_t
+    BlobHandler::openBlob(const std::string& id,
+                          blobs::FirmwareBlobHandler::UpdateFlags handlerFlags)
+{
+    std::uint16_t session;
+    std::vector<std::uint8_t> request;
+    std::uint16_t flags =
+        blobs::FirmwareBlobHandler::UpdateFlags::openWrite | handlerFlags;
+    auto addrFlags = reinterpret_cast<std::uint8_t*>(&flags);
+    std::copy(addrFlags, addrFlags + sizeof(flags),
+              std::back_inserter(request));
+    std::copy(id.begin(), id.end(), std::back_inserter(request));
+
+    auto resp = sendIpmiPayload(BlobOEMCommands::bmcBlobOpen, request);
+    if (resp.size() != sizeof(session))
+    {
+        throw BlobException("Did not receive session.");
+    }
+
+    std::memcpy(&session, resp.data(), sizeof(session));
+    return session;
+}