Introduce ExchangeAcceptor for unsolicited message handler (#17069)

* Introduce ExchangeAcceptor for unsolicited message handler

* Resolve comments

* Apply suggestions from code review

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>

* Fix build

* Fix build

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
diff --git a/src/messaging/ExchangeMgr.cpp b/src/messaging/ExchangeMgr.cpp
index 9bad953..adfc214 100644
--- a/src/messaging/ExchangeMgr.cpp
+++ b/src/messaging/ExchangeMgr.cpp
@@ -114,15 +114,16 @@
     return mContextPool.CreateObject(this, mNextExchangeId++, session, true, delegate);
 }
 
-CHIP_ERROR ExchangeManager::RegisterUnsolicitedMessageHandlerForProtocol(Protocols::Id protocolId, ExchangeDelegate * delegate)
+CHIP_ERROR ExchangeManager::RegisterUnsolicitedMessageHandlerForProtocol(Protocols::Id protocolId,
+                                                                         UnsolicitedMessageHandler * handler)
 {
-    return RegisterUMH(protocolId, kAnyMessageType, delegate);
+    return RegisterUMH(protocolId, kAnyMessageType, handler);
 }
 
 CHIP_ERROR ExchangeManager::RegisterUnsolicitedMessageHandlerForType(Protocols::Id protocolId, uint8_t msgType,
-                                                                     ExchangeDelegate * delegate)
+                                                                     UnsolicitedMessageHandler * handler)
 {
-    return RegisterUMH(protocolId, static_cast<int16_t>(msgType), delegate);
+    return RegisterUMH(protocolId, static_cast<int16_t>(msgType), handler);
 }
 
 CHIP_ERROR ExchangeManager::UnregisterUnsolicitedMessageHandlerForProtocol(Protocols::Id protocolId)
@@ -135,9 +136,9 @@
     return UnregisterUMH(protocolId, static_cast<int16_t>(msgType));
 }
 
-CHIP_ERROR ExchangeManager::RegisterUMH(Protocols::Id protocolId, int16_t msgType, ExchangeDelegate * delegate)
+CHIP_ERROR ExchangeManager::RegisterUMH(Protocols::Id protocolId, int16_t msgType, UnsolicitedMessageHandler * handler)
 {
-    UnsolicitedMessageHandler * selected = nullptr;
+    UnsolicitedMessageHandlerSlot * selected = nullptr;
 
     for (auto & umh : UMHandlerPool)
     {
@@ -148,7 +149,7 @@
         }
         else if (umh.Matches(protocolId, msgType))
         {
-            umh.Delegate = delegate;
+            umh.Handler = handler;
             return CHIP_NO_ERROR;
         }
     }
@@ -156,7 +157,7 @@
     if (selected == nullptr)
         return CHIP_ERROR_TOO_MANY_UNSOLICITED_MESSAGE_HANDLERS;
 
-    selected->Delegate    = delegate;
+    selected->Handler     = handler;
     selected->ProtocolId  = protocolId;
     selected->MessageType = msgType;
 
@@ -184,7 +185,7 @@
                                         const SessionHandle & session, const Transport::PeerAddress & source,
                                         DuplicateMessage isDuplicate, System::PacketBufferHandle && msgBuf)
 {
-    UnsolicitedMessageHandler * matchingUMH = nullptr;
+    UnsolicitedMessageHandlerSlot * matchingUMH = nullptr;
 
     ChipLogProgress(ExchangeManager,
                     "Received message of type " ChipLogFormatMessageType " with protocolId " ChipLogFormatProtocolId
@@ -273,7 +274,20 @@
     // handle the message.
     if (matchingUMH != nullptr || payloadHeader.NeedsAck())
     {
-        ExchangeDelegate * delegate = matchingUMH ? matchingUMH->Delegate : nullptr;
+        ExchangeDelegate * delegate = nullptr;
+
+        // Fetch delegate from the handler
+        if (matchingUMH != nullptr)
+        {
+            CHIP_ERROR err = matchingUMH->Handler->OnUnsolicitedMessageReceived(payloadHeader, delegate);
+            if (err != CHIP_NO_ERROR)
+            {
+                // Using same error message for all errors to reduce code size.
+                ChipLogError(ExchangeManager, "OnMessageReceived failed, err = %s", ErrorStr(err));
+                return;
+            }
+        }
+
         // If rcvd msg is from initiator then this exchange is created as not Initiator.
         // If rcvd msg is not from initiator then this exchange is created as Initiator.
         // Note that if matchingUMH is not null then rcvd msg if from initiator.
@@ -283,6 +297,11 @@
 
         if (ec == nullptr)
         {
+            if (matchingUMH != nullptr && delegate != nullptr)
+            {
+                matchingUMH->Handler->OnExchangeCreationFailed(delegate);
+            }
+
             // Using same error message for all errors to reduce code size.
             ChipLogError(ExchangeManager, "OnMessageReceived failed, err = %s", ErrorStr(CHIP_ERROR_NO_MEMORY));
             return;