Add OEM command to request flash size

The BMC flash is `/dev/mtd0` and the size can found in
`/sys/class/mtd/mtd0/size`. This OEM command will request that
information with MTDINFO.

Tested:
Successfully requested the flash size information with ipmitool.

```
cat /sys/class/mtd/mtd0/size
67108864
```
67108864 / 1024 / 1024 = 64MB flash

```
ipmitool raw 0x2e 0x32 0x79 0x2b 0x00 0x09
 79 2b 00 09 00 00 00 04
```
Output in little endian.
0x04000000 -> 67108864

Change-Id: Iec1b33503d1166a42ceef4b8491e5c19c3a077fe
Signed-off-by: Willy Tu <wltu@google.com>
diff --git a/flash_size.cpp b/flash_size.cpp
new file mode 100644
index 0000000..069b1b1
--- /dev/null
+++ b/flash_size.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2021 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "flash_size.hpp"
+
+#include "commands.hpp"
+#include "errors.hpp"
+#include "handler.hpp"
+
+#include <cstdint>
+#include <cstring>
+#include <string>
+#include <vector>
+
+namespace google
+{
+namespace ipmi
+{
+
+struct GetFlashSizeRequest
+{
+    uint8_t subcommand;
+} __attribute__((packed));
+
+struct GetFlashSizeReply
+{
+    uint8_t subcommand;
+    uint32_t flashSize;
+} __attribute__((packed));
+
+ipmi_ret_t getFlashSize(const uint8_t* reqBuf, uint8_t* replyBuf,
+                        size_t* dataLen, HandlerInterface* handler)
+{
+    struct GetFlashSizeRequest request;
+
+    if ((*dataLen) < sizeof(request))
+    {
+        std::fprintf(stderr, "Invalid command length: %u\n",
+                     static_cast<uint32_t>(*dataLen));
+        return IPMI_CC_REQ_DATA_LEN_INVALID;
+    }
+
+    std::memcpy(&request, &reqBuf[0], sizeof(request));
+    uint32_t flashSize;
+    try
+    {
+        flashSize = handler->getFlashSize();
+    }
+    catch (const IpmiException& e)
+    {
+        return e.getIpmiError();
+    }
+
+    auto reply = reinterpret_cast<struct GetFlashSizeReply*>(&replyBuf[0]);
+    reply->subcommand = SysGetFlashSize;
+    reply->flashSize = htole32(flashSize);
+
+    (*dataLen) = sizeof(struct GetFlashSizeReply);
+    return IPMI_CC_OK;
+}
+} // namespace ipmi
+} // namespace google