Fix issue two identical requests are received and one of them is timeout

Sometimes, there are two identical requests are sent, but one of them
is timeout, BMC should only response the latter and ignore the
former; otherwise host driver will receive duplicate responses which result to
fail to create ssif interface. Below is one of the log demonstrate that scenario
02:23:14 Read ssif request message with len=4 netfn=6 lun=0 cmd=66
02:23:35 Read ssif request message with len=4 netfn=6 lun=0 cmd=66
02:23:47 Send ssif respond message with len=12 netfn=7 lun=0 cmd=66 cc=0
02:23:47 Send ssif respond message with len=12 netfn=7 lun=0 cmd=66 cc=0

This commit fixes that

Change-Id: Ie0ee5cc572d54245dafe27d77315952ce5d4ab97
Signed-off-by: Quang Nguyen <quangnguyen@os.amperecomputing.com>
diff --git a/ssifbridged.cpp b/ssifbridged.cpp
index 9b74337..20fc608 100644
--- a/ssifbridged.cpp
+++ b/ssifbridged.cpp
@@ -58,7 +58,8 @@
 
     SsifChannel(std::shared_ptr<boost::asio::io_context>& io,
                    std::shared_ptr<sdbusplus::asio::connection>& bus,
-                   const std::string& channel, bool verbose);
+                   const std::string& channel, bool verbose,
+                   int numberOfReqNotRsp);
     bool initOK() const
     {
         return !!dev;
@@ -74,13 +75,18 @@
     std::shared_ptr<sdbusplus::asio::object_server> server;
     std::unique_ptr<boost::asio::posix::stream_descriptor> dev = nullptr;
     bool verbose;
+    /* This variable is always 0 when a request is responsed properly,
+     * any value larger than 0 meaning there is/are request(s) which
+     * not processed properly
+     * */
+    int numberOfReqNotRsp;
 };
 
 SsifChannel::SsifChannel(std::shared_ptr<boost::asio::io_context>& io,
                          std::shared_ptr<sdbusplus::asio::connection>& bus,
-                         const std::string& device, bool verbose) :
+                         const std::string& device, bool verbose, int numberOfReqNotRsp) :
     io(io),
-    bus(bus), verbose(verbose)
+    bus(bus), verbose(verbose), numberOfReqNotRsp(numberOfReqNotRsp)
 {
     std::string devName = devBase;
     if (!device.empty())
@@ -148,10 +154,14 @@
     uint8_t lun = rawIter[sizeofLenField] & lunMask;
     uint8_t cmd = rawIter[sizeofLenField + 1];
 
+    /* keep track of previous request */
     prev_req_cmd.netfn = netfn;
     prev_req_cmd.lun = lun;
     prev_req_cmd.cmd = cmd;
 
+    /* there is a request coming */
+    numberOfReqNotRsp++;
+
     if (verbose)
     {
         unsigned int lenRecv;
@@ -185,6 +195,7 @@
                       const IpmiDbusRspType& response) {
             std::vector<uint8_t> rsp;
             const auto& [netfn, lun, cmd, cc, payload] = response;
+            numberOfReqNotRsp--;
             if (ec)
             {
                 std::string msgToLog = "ssif<->ipmid bus error:"
@@ -197,19 +208,27 @@
                            sizeof(cc));
                 /* if dbusTimeout, just return and do not send any response
                  * to let host continue with other commands, response here
-                 * is potentionally make the response duplicated 
+                 * is potentially make the response duplicated
                  * */
                 return;
             }
             else
             {
-                if(prev_req_cmd.netfn != (netfn-1) ||
+                if ((prev_req_cmd.netfn != (netfn-1) ||
                         prev_req_cmd.lun != lun ||
-                        prev_req_cmd.cmd != cmd)
+                        prev_req_cmd.cmd != cmd) ||
+                        ((prev_req_cmd.netfn == (netfn-1) ||
+                        prev_req_cmd.lun == lun ||
+                        prev_req_cmd.cmd == cmd) &&
+                        numberOfReqNotRsp > 0))
                 {
                     /* Only send response to the last request command to void
                      * duplicated response which makes host driver confused and
                      * failed to create interface
+                     *
+                     * Drop responses which are (1) different from the request
+                     * (2) parameters are the same as request but handshake flow
+                     * are in dupplicate request state
                      * */
                     return;
                 }
@@ -267,6 +286,7 @@
     app.add_option("-d,--device", device,
                    "use <DEVICE> file. Default is /dev/ipmi-ssif-host");
     bool verbose = false;
+    int numberOfReqNotRsp = 0;
     app.add_option("-v,--verbose", verbose, "print more verbose output");
     CLI11_PARSE(app, argc, argv);
 
@@ -277,7 +297,7 @@
     auto bus = std::make_shared<sdbusplus::asio::connection>(*io, dbus);
     bus->request_name(ssifBus);
     // Create the SSIF channel, listening on D-Bus and on the SSIF device
-    SsifChannel ssifchannel(io, bus, device, verbose);
+    SsifChannel ssifchannel(io, bus, device, verbose, numberOfReqNotRsp);
     if (!ssifchannel.initOK())
     {
         return EXIT_FAILURE;