1bf58cd64SPatrick Venture /*
2bf58cd64SPatrick Venture  * Copyright 2018 Google Inc.
3bf58cd64SPatrick Venture  *
4bf58cd64SPatrick Venture  * Licensed under the Apache License, Version 2.0 (the "License");
5bf58cd64SPatrick Venture  * you may not use this file except in compliance with the License.
6bf58cd64SPatrick Venture  * You may obtain a copy of the License at
7bf58cd64SPatrick Venture  *
8bf58cd64SPatrick Venture  *     http://www.apache.org/licenses/LICENSE-2.0
9bf58cd64SPatrick Venture  *
10bf58cd64SPatrick Venture  * Unless required by applicable law or agreed to in writing, software
11bf58cd64SPatrick Venture  * distributed under the License is distributed on an "AS IS" BASIS,
12bf58cd64SPatrick Venture  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bf58cd64SPatrick Venture  * See the License for the specific language governing permissions and
14bf58cd64SPatrick Venture  * limitations under the License.
15bf58cd64SPatrick Venture  */
16bf58cd64SPatrick Venture 
17bf58cd64SPatrick Venture #include "updater.hpp"
18bf58cd64SPatrick Venture 
190533d0b0SPatrick Venture #include "blob_errors.hpp"
202bc23fe1SPatrick Venture #include "tool_errors.hpp"
210533d0b0SPatrick Venture 
2200887597SPatrick Venture #include <algorithm>
23339dece8SPatrick Venture #include <cstring>
24af69625fSPatrick Venture #include <memory>
25*2a927e87SPatrick Venture #include <string>
26af69625fSPatrick Venture 
279b534f06SPatrick Venture namespace host_tool
289b534f06SPatrick Venture {
299b534f06SPatrick Venture 
302bc23fe1SPatrick Venture void updaterMain(BlobInterface* blob, DataInterface* handler,
3100887597SPatrick Venture                  const std::string& imagePath, const std::string& signaturePath)
32bf58cd64SPatrick Venture {
33af69625fSPatrick Venture     /* TODO(venture): Add optional parameter to specify the flash type, default
34af69625fSPatrick Venture      * to legacy for now.
35af69625fSPatrick Venture      */
3600887597SPatrick Venture     std::string goalFirmware = "/flash/image";
3700887597SPatrick Venture 
380bf8bf0cSPatrick Venture     /* Get list of blob_ids, check for /flash/image, or /flash/tarball.
390bf8bf0cSPatrick Venture      * TODO(venture) the mechanism doesn't care, but the caller of burn_my_bmc
400bf8bf0cSPatrick Venture      * will have in mind which they're sending and we need to verify it's
410bf8bf0cSPatrick Venture      * available and use it.
420bf8bf0cSPatrick Venture      */
4300887597SPatrick Venture     std::vector<std::string> blobs = blob->getBlobList();
44339dece8SPatrick Venture     auto blobInst = std::find_if(
45*2a927e87SPatrick Venture         blobs.begin(), blobs.end(), [&goalFirmware](const std::string& iter) {
46339dece8SPatrick Venture             /* Running into weird scenarios where the string comparison doesn't
47339dece8SPatrick Venture              * work.  TODO: revisit.
48339dece8SPatrick Venture              */
49339dece8SPatrick Venture             return (0 == std::memcmp(goalFirmware.c_str(), iter.c_str(),
50339dece8SPatrick Venture                                      goalFirmware.length()));
51339dece8SPatrick Venture             // return (goalFirmware.compare(iter));
52339dece8SPatrick Venture         });
5300887597SPatrick Venture     if (blobInst == blobs.end())
5400887597SPatrick Venture     {
552bc23fe1SPatrick Venture         throw ToolException(goalFirmware + " not found");
5600887597SPatrick Venture     }
57af69625fSPatrick Venture 
58af69625fSPatrick Venture     /* Call stat on /flash/image (or /flash/tarball) and check if data interface
5900887597SPatrick Venture      * is supported.
6000887597SPatrick Venture      */
61339dece8SPatrick Venture     StatResponse stat;
62339dece8SPatrick Venture     try
63339dece8SPatrick Venture     {
64339dece8SPatrick Venture         stat = blob->getStat(goalFirmware);
65339dece8SPatrick Venture     }
66339dece8SPatrick Venture     catch (const BlobException& b)
67339dece8SPatrick Venture     {
68339dece8SPatrick Venture         throw ToolException("blob exception received: " +
69339dece8SPatrick Venture                             std::string(b.what()));
70339dece8SPatrick Venture     }
71339dece8SPatrick Venture 
72aa32a36aSPatrick Venture     auto supported = handler->supportedType();
73aa32a36aSPatrick Venture     if ((stat.blob_state & supported) == 0)
748a55dcbdSPatrick Venture     {
752bc23fe1SPatrick Venture         throw ToolException("data interface selected not supported.");
768a55dcbdSPatrick Venture     }
77af69625fSPatrick Venture 
780533d0b0SPatrick Venture     /* Yay, our data handler is supported. */
790533d0b0SPatrick Venture     std::uint16_t session;
800533d0b0SPatrick Venture     try
810533d0b0SPatrick Venture     {
82aa32a36aSPatrick Venture         session = blob->openBlob(goalFirmware, supported);
830533d0b0SPatrick Venture     }
840533d0b0SPatrick Venture     catch (const BlobException& b)
850533d0b0SPatrick Venture     {
862bc23fe1SPatrick Venture         throw ToolException("blob exception received: " +
872bc23fe1SPatrick Venture                             std::string(b.what()));
880533d0b0SPatrick Venture     }
890533d0b0SPatrick Venture 
90fd6aaec8SPatrick Venture     /* Send over the firmware image. */
91fd6aaec8SPatrick Venture     if (!handler->sendContents(imagePath, session))
92fd6aaec8SPatrick Venture     {
93f9566d88SPatrick Venture         /* Need to close the session on failure, or it's stuck open (until the
94f9566d88SPatrick Venture          * blob handler timeout is implemented, and even then, why make it wait.
95f9566d88SPatrick Venture          */
96f9566d88SPatrick Venture         blob->closeBlob(session);
972bc23fe1SPatrick Venture         throw ToolException("Failed to send contents of " + imagePath);
98fd6aaec8SPatrick Venture     }
99fd6aaec8SPatrick Venture 
1009a5ce561SPatrick Venture     blob->closeBlob(session);
1019a5ce561SPatrick Venture 
102fd6aaec8SPatrick Venture     /* Send over the hash contents. */
103fd6aaec8SPatrick Venture     /* Trigger the verification. */
104fd6aaec8SPatrick Venture     /* Check the verification. */
105fd6aaec8SPatrick Venture 
1062bc23fe1SPatrick Venture     return;
107bf58cd64SPatrick Venture }
1089b534f06SPatrick Venture 
1099b534f06SPatrick Venture } // namespace host_tool
110