Handling Broadcast message service

This commit implements the broadcast of the messages from one
connected client to other connected clients via BMC. When the
management console creates a subscription on the BMC, they will
be provided with the broadcast message service.

Tested by: (Used https://github.com/DMTF/Redfish-Event-Listener)
    1. Create a subscription
       POST -D headers.txt https://${bmc}/redfish/v1/EventService/Subscriptions
       -d '{"Destination":"https://<host:port>","Protocol":"Redfish"}'

    2. Send the message
        POST https://${bmc}/ibm/v1/HMC/BroadcastService -d '{"Message":"<msg>"}'

    3. Verify the event is generated and posted to the subscriber:
       bodydata: {"Message":"<The message from HMC to be forwarded>",
                  "Name":"Broadcast Event","OriginOfCondition":
                  "/ibm/v1/HMC/BroadcastService",
                  "Timestamp":"2020-07-15T12:03:30+00:00"}

Signed-off-by: Asmitha Karunanithi <asmitk01@in.ibm.com>
Change-Id: Ib36b4f25505cf66251adc5aeda282312996c25af
diff --git a/include/ibm/management_console_rest.hpp b/include/ibm/management_console_rest.hpp
index 88f2fc6..74cddc6 100644
--- a/include/ibm/management_console_rest.hpp
+++ b/include/ibm/management_console_rest.hpp
@@ -17,9 +17,6 @@
 #include <fstream>
 #include <regex>
 
-// Allow save area file size to 500KB
-#define MAX_SAVE_AREA_FILESIZE 500000
-
 using SType = std::string;
 using SegmentFlags = std::vector<std::pair<std::string, uint32_t>>;
 using LockRequest = std::tuple<SType, SType, SType, uint64_t, SegmentFlags>;
@@ -38,6 +35,11 @@
 constexpr const char* contentNotAcceptableMsg = "Content Not Acceptable";
 constexpr const char* internalServerError = "Internal Server Error";
 
+constexpr size_t maxSaveareaFileSize =
+    500000; // Allow save area file size upto 500KB
+constexpr size_t maxBroadcastMsgSize =
+    1000; // Allow Broadcast message size upto 1KB
+
 bool createSaveAreaPath(crow::Response& res)
 {
     // The path /var/lib/obmc will be created by initrdscripts
@@ -109,7 +111,7 @@
 
     std::string data = std::move(req.body);
     BMCWEB_LOG_DEBUG << "data capaticty : " << data.capacity();
-    if (data.capacity() > MAX_SAVE_AREA_FILESIZE)
+    if (data.capacity() > maxSaveareaFileSize)
     {
         res.result(boost::beast::http::status::bad_request);
         res.jsonValue["Description"] =
@@ -275,6 +277,28 @@
     return;
 }
 
+inline void handleBroadcastService(const crow::Request& req,
+                                   crow::Response& res)
+{
+    std::string broadcastMsg;
+
+    if (!redfish::json_util::readJson(req, res, "Message", broadcastMsg))
+    {
+        BMCWEB_LOG_DEBUG << "Not a Valid JSON";
+        res.result(boost::beast::http::status::bad_request);
+        return;
+    }
+    if (broadcastMsg.size() > maxBroadcastMsgSize)
+    {
+        BMCWEB_LOG_ERROR << "Message size exceeds maximum allowed size[1KB]";
+        res.result(boost::beast::http::status::bad_request);
+        return;
+    }
+    redfish::EventServiceManager::getInstance().sendBroadcastMsg(broadcastMsg);
+    res.end();
+    return;
+}
+
 inline void handleFileUrl(const crow::Request& req, crow::Response& res,
                           const std::string& fileID)
 {
@@ -568,6 +592,8 @@
                     {"@odata.id", "/ibm/v1/Host/ConfigFiles"}};
                 res.jsonValue["LockService"] = {
                     {"@odata.id", "/ibm/v1/HMC/LockService"}};
+                res.jsonValue["BroadcastService"] = {
+                    {"@odata.id", "/ibm/v1/HMC/BroadcastService"}};
                 res.end();
             });
 
@@ -659,6 +685,13 @@
                 }
                 handleGetLockListAPI(req, res, listSessionIds);
             });
+
+    BMCWEB_ROUTE(app, "/ibm/v1/HMC/BroadcastService")
+        .requires({"ConfigureComponents", "ConfigureManager"})
+        .methods(boost::beast::http::verb::post)(
+            [](const crow::Request& req, crow::Response& res) {
+                handleBroadcastService(req, res);
+            });
 }
 
 } // namespace ibm_mc