modbus_rtu_lib: define read holding register

Add the modbus rtu library commands with initial support for read
holding register. Define a base Message classes which all subsequent and
specific request & response messages can inherit from. Also add the
relevant unit testing for the added command set.

Tested:
```
> meson test -C builddir
ninja: Entering directory `/host/repos/Modbus/phosphor-modbus/builddir'
ninja: no work to do.
1/1 test_modbus_commands        OK              0.01s

Ok:                1
Fail:              0

```

Change-Id: I331b0dee66a0829e9352ae0eac8ac82a9150904c
Signed-off-by: Jagpal Singh Gill <paligill@gmail.com>
diff --git a/rtu/modbus/modbus_message.hpp b/rtu/modbus/modbus_message.hpp
new file mode 100644
index 0000000..6b26dab
--- /dev/null
+++ b/rtu/modbus/modbus_message.hpp
@@ -0,0 +1,65 @@
+#pragma once
+
+#include <array>
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace phosphor::modbus::rtu
+{
+
+class Message
+{
+  public:
+    static constexpr auto maxADUSize = 256;
+    std::array<uint8_t, maxADUSize> raw{};
+    size_t len = 0;
+
+    // Push to the end of raw message
+    Message& operator<<(uint8_t d);
+    Message& operator<<(uint16_t d);
+    Message& operator<<(uint32_t d);
+
+    // Pop from the end of raw message
+    Message& operator>>(uint8_t& d);
+    Message& operator>>(uint16_t& d);
+    Message& operator>>(uint32_t& d);
+
+    Message() = default;
+    Message(const Message&) = delete;
+    Message& operator=(const Message&) = delete;
+
+    uint8_t& address = raw[0];
+    uint8_t& functionCode = raw[1];
+
+  protected:
+    auto appendCRC() -> void;
+    auto validate() -> void;
+    auto verifyValue(const std::string& name, uint32_t currentValue,
+                     uint32_t expectedValue) -> void;
+
+    template <typename T>
+    Message& operator>>(std::vector<T>& d)
+    {
+        for (auto it = d.rbegin(); it != d.rend(); it++)
+        {
+            *this >> *it;
+        }
+        return *this;
+    }
+
+  private:
+    auto generateCRC() -> uint16_t;
+
+    constexpr auto begin() noexcept
+    {
+        return raw.begin();
+    }
+    auto end() noexcept
+    {
+        return raw.begin() + len;
+    }
+};
+
+} // namespace phosphor::modbus::rtu