Skip to content

Commit

Permalink
Migrate Device Controller from transport layer to exchange layer and …
Browse files Browse the repository at this point in the history
…enable exchange layer by default. (#5627)

* Migrate Device Controller from transport layer to messaging layer

* Update src/app/util/chip-message-send.cpp

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

* Update src/controller/CHIPDevice.cpp

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

* Update src/controller/CHIPDevice.h

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

* Update src/controller/CHIPDevice.h

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

* Update to address review comments

* Adjust CHIP compile-time configuration constants for messaging layer

* Apply suggestions from code review

* Fix restyle issue

* Fix restyle issue for real

Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
  • Loading branch information
yufengwangca and bzbarsky-apple authored Apr 10, 2021
1 parent 60553a1 commit a369e89
Show file tree
Hide file tree
Showing 30 changed files with 360 additions and 157 deletions.
2 changes: 1 addition & 1 deletion config/esp32/components/chip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ menu "CHIP Core"
config MAX_UNSOLICITED_MESSAGE_HANDLERS
int "Max Unsolicited Message Handlers"
range 0 65535
default 16
default 8
help
The maximum number of simultaneously active unsolicited message handlers.

Expand Down
1 change: 0 additions & 1 deletion src/app/server/RendezvousServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

#include <app/server/RendezvousServer.h>

#include <app/server/SessionManager.h>
#include <core/CHIPError.h>
#include <support/CodeUtils.h>
#include <support/SafeInt.h>
Expand Down
59 changes: 31 additions & 28 deletions src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <app/server/DataModelHandler.h>
#include <app/server/EchoHandler.h>
#include <app/server/RendezvousServer.h>
#include <app/server/SessionManager.h>

#include <ble/BLEEndPoint.h>
#include <core/CHIPPersistentStorageDelegate.h>
Expand Down Expand Up @@ -297,7 +296,6 @@ class ServerRendezvousAdvertisementDelegate : public RendezvousAdvertisementDele
DemoTransportMgr gTransports;
SecureSessionMgr gSessions;
RendezvousServer gRendezvousServer;

ServerRendezvousAdvertisementDelegate gAdvDelegate;

static CHIP_ERROR OpenPairingWindowUsingVerifier(uint16_t discriminator, PASEVerifier & verifier)
Expand All @@ -323,24 +321,23 @@ static CHIP_ERROR OpenPairingWindowUsingVerifier(uint16_t discriminator, PASEVer
return gRendezvousServer.WaitForPairing(std::move(params), &gTransports, &gSessions, adminInfo);
}

class ServerCallback : public SecureSessionMgrDelegate
class ServerCallback : public ExchangeDelegate
{
public:
void OnMessageReceived(const PacketHeader & header, const PayloadHeader & payloadHeader, SecureSessionHandle session,
System::PacketBufferHandle buffer, SecureSessionMgr * mgr) override
void OnMessageReceived(Messaging::ExchangeContext * exchangeContext, const PacketHeader & packetHeader,
const PayloadHeader & payloadHeader, System::PacketBufferHandle buffer) override
{
auto state = mgr->GetPeerConnectionState(session);
char src_addr[PeerAddress::kMaxToStringSize];

// as soon as a client connects, assume it is connected
VerifyOrExit(!buffer.IsNull(), ChipLogProgress(AppServer, "Received data but couldn't process it..."));
VerifyOrExit(header.GetSourceNodeId().HasValue(), ChipLogProgress(AppServer, "Unknown source for received message"));
VerifyOrExit(!buffer.IsNull(), ChipLogError(AppServer, "Received data but couldn't process it..."));
VerifyOrExit(packetHeader.GetSourceNodeId().HasValue(), ChipLogError(AppServer, "Unknown source for received message"));

VerifyOrExit(state->GetPeerNodeId() != kUndefinedNodeId, ChipLogProgress(AppServer, "Unknown source for received message"));
VerifyOrExit(mSessionMgr != nullptr, ChipLogError(AppServer, "SecureSessionMgr is not initilized yet"));

state->GetPeerAddress().ToString(src_addr);
VerifyOrExit(packetHeader.GetSourceNodeId().Value() != kUndefinedNodeId,
ChipLogError(AppServer, "Unknown source for received message"));

ChipLogProgress(AppServer, "Packet received from %s: %u bytes", src_addr, buffer->DataLength());
ChipLogProgress(AppServer, "Packet received from Node:%x: %u bytes", packetHeader.GetSourceNodeId().Value(),
buffer->DataLength());

// TODO: This code is temporary, and must be updated to use the Cluster API.
// Issue: https://github.com/project-chip/connectedhomeip/issues/4725
Expand Down Expand Up @@ -387,35 +384,30 @@ class ServerCallback : public SecureSessionMgrDelegate
}
else
{
HandleDataModelMessage(header.GetSourceNodeId().Value(), std::move(buffer));
HandleDataModelMessage(packetHeader.GetSourceNodeId().Value(), std::move(buffer));
}

exit:;
}

void OnReceiveError(CHIP_ERROR error, const Transport::PeerAddress & source, SecureSessionMgr * mgr) override
void OnResponseTimeout(ExchangeContext * ec) override
{
ChipLogProgress(AppServer, "Packet received error: %s", ErrorStr(error));
ChipLogProgress(AppServer, "Failed to receive response");
if (mDelegate != nullptr)
{
mDelegate->OnReceiveError();
}
}

void OnNewConnection(SecureSessionHandle session, SecureSessionMgr * mgr) override
{
ChipLogProgress(AppServer, "Received a new connection.");
}

void SetDelegate(AppDelegate * delegate) { mDelegate = delegate; }
void SetSessionMgr(SecureSessionMgr * mgr) { mSessionMgr = mgr; }

private:
AppDelegate * mDelegate = nullptr;
AppDelegate * mDelegate = nullptr;
SecureSessionMgr * mSessionMgr = nullptr;
};

#if CHIP_ENABLE_INTERACTION_MODEL || defined(CHIP_APP_USE_ECHO)
Messaging::ExchangeManager gExchangeMgr;
#endif
ServerCallback gCallbacks;
SecurePairingUsingTestSecret gTestPairing;

Expand All @@ -426,6 +418,11 @@ SecureSessionMgr & chip::SessionManager()
return gSessions;
}

Messaging::ExchangeManager & chip::ExchangeManager()
{
return gExchangeMgr;
}

CHIP_ERROR OpenDefaultPairingWindow(ResetAdmins resetAdmins, chip::PairingWindowAdvertisement advertisementMode)
{
// TODO(cecille): If this is re-called when the window is already open, what should happen?
Expand Down Expand Up @@ -491,12 +488,8 @@ void InitServer(AppDelegate * delegate)
err = gSessions.Init(chip::kTestDeviceNodeId, &DeviceLayer::SystemLayer, &gTransports, &gAdminPairings);
SuccessOrExit(err);

#if CHIP_ENABLE_INTERACTION_MODEL || defined(CHIP_APP_USE_ECHO)
err = gExchangeMgr.Init(&gSessions);
SuccessOrExit(err);
#else
gSessions.SetDelegate(&gCallbacks);
#endif

#if CHIP_ENABLE_INTERACTION_MODEL
err = chip::app::InteractionModelEngine::GetInstance()->Init(&gExchangeMgr, nullptr);
Expand Down Expand Up @@ -538,6 +531,16 @@ void InitServer(AppDelegate * delegate)
app::Mdns::StartServer();
#endif

gCallbacks.SetSessionMgr(&gSessions);

// Register to receive unsolicited legacy ZCL messages from the exchange manager.
err = gExchangeMgr.RegisterUnsolicitedMessageHandlerForProtocol(Protocols::TempZCL::Id, &gCallbacks);
VerifyOrExit(err == CHIP_NO_ERROR, err = CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER);

// Register to receive unsolicited Service Provisioning messages from the exchange manager.
err = gExchangeMgr.RegisterUnsolicitedMessageHandlerForProtocol(Protocols::ServiceProvisioning::Id, &gCallbacks);
VerifyOrExit(err == CHIP_NO_ERROR, err = CHIP_ERROR_NO_UNSOLICITED_MESSAGE_HANDLER);

exit:
if (err != CHIP_NO_ERROR)
{
Expand Down
5 changes: 5 additions & 0 deletions src/app/server/Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

#include <app/server/AppDelegate.h>
#include <inet/InetConfig.h>
#include <messaging/ExchangeMgr.h>
#include <transport/AdminPairingTable.h>
#include <transport/SecureSessionMgr.h>
#include <transport/TransportMgr.h>
#include <transport/raw/UDP.h>

Expand Down Expand Up @@ -55,6 +57,9 @@ enum class PairingWindowAdvertisement
kMdns,
};

SecureSessionMgr & SessionManager();
Messaging::ExchangeManager & ExchangeManager();

} // namespace chip

/**
Expand Down
24 changes: 0 additions & 24 deletions src/app/server/SessionManager.h

This file was deleted.

26 changes: 24 additions & 2 deletions src/app/util/chip-message-send.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@

#include <assert.h>
#include <inet/InetLayer.h>
#include <messaging/ExchangeContext.h>
#include <messaging/ExchangeMgr.h>
#include <protocols/Protocols.h>
#include <support/logging/CHIPLogging.h>
#include <transport/SecureSessionMgr.h>
#include <transport/raw/MessageHeader.h>
Expand All @@ -37,7 +40,8 @@ using namespace chip;
// https://github.com/project-chip/connectedhomeip/issues/2566 tracks that API.
namespace chip {
extern SecureSessionMgr & SessionManager();
}
extern Messaging::ExchangeManager & ExchangeManager();
} // namespace chip

EmberStatus chipSendUnicast(NodeId destination, EmberApsFrame * apsFrame, uint16_t messageLength, uint8_t * message)
{
Expand Down Expand Up @@ -75,7 +79,25 @@ EmberStatus chipSendUnicast(NodeId destination, EmberApsFrame * apsFrame, uint16
buffer->SetDataLength(dataLength);

// TODO: temprary create a handle from node id, will be fix in PR 3602
CHIP_ERROR err = SessionManager().SendMessage({ destination, Transport::kAnyKeyId, 0 }, std::move(buffer));
Messaging::ExchangeContext * exchange = ExchangeManager().NewContext({ destination, Transport::kAnyKeyId, 0 }, nullptr);
if (exchange == nullptr)
{
return EMBER_DELIVERY_FAILED;
}

// TODO(#5675): This code is temporary, and must be updated to use the IM API. Currently, we use a temporary Protocol
// TempZCL to carry over legacy ZCL messages, use an ephemeral exchange to send message and use its unsolicited message
// handler to receive messages. We need to set flag kFromInitiator to allow receiver to deliver message to corresponding
// unsolicited message handler, and we also need to set flag kNoAutoRequestAck since there is no persistent exchange to
// receive the ack message. This logic needs to be deleted after we convert all legacy ZCL messages to IM messages.

Messaging::SendFlags sendFlags;

sendFlags.Set(Messaging::SendMessageFlags::kFromInitiator).Set(Messaging::SendMessageFlags::kNoAutoRequestAck);
CHIP_ERROR err = exchange->SendMessage(Protocols::TempZCL::Id, 0, std::move(buffer), sendFlags);

exchange->Close();

if (err != CHIP_NO_ERROR)
{
// FIXME: Figure out better translations between our error types?
Expand Down
2 changes: 1 addition & 1 deletion src/controller/CHIPCluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ CHIP_ERROR ClusterBase::SendCommand(uint8_t seqNum, chip::System::PacketBufferHa
VerifyOrExit(mDevice != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(!payload.IsNull(), err = CHIP_ERROR_INTERNAL);

err = mDevice->SendMessage(std::move(payload));
err = mDevice->SendMessage(Protocols::TempZCL::Id, 0, std::move(payload));
SuccessOrExit(err);

if (onSuccessCallback != nullptr || onFailureCallback != nullptr)
Expand Down
43 changes: 24 additions & 19 deletions src/controller/CHIPDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <core/CHIPCore.h>
#include <core/CHIPEncoding.h>
#include <core/CHIPSafeCasts.h>
#include <protocols/Protocols.h>
#include <support/Base64.h>
#include <support/CHIPMem.h>
#include <support/CodeUtils.h>
Expand All @@ -55,16 +56,19 @@ using namespace chip::Callback;
namespace chip {
namespace Controller {

CHIP_ERROR Device::SendMessage(System::PacketBufferHandle buffer, PayloadHeader & payloadHeader)
CHIP_ERROR Device::SendMessage(Protocols::Id protocolId, uint8_t msgType, System::PacketBufferHandle buffer)
{
System::PacketBufferHandle resend;
bool loadedSecureSession = false;
Messaging::SendFlags sendFlags;

VerifyOrReturnError(mSessionManager != nullptr, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnError(!buffer.IsNull(), CHIP_ERROR_INVALID_ARGUMENT);

ReturnErrorOnFailure(LoadSecureSessionParametersIfNeeded(loadedSecureSession));

Messaging::ExchangeContext * exchange = mExchangeMgr->NewContext(mSecureSession, nullptr);
VerifyOrReturnError(exchange != nullptr, CHIP_ERROR_NO_MEMORY);

if (!loadedSecureSession)
{
// Secure connection already existed
Expand All @@ -75,7 +79,14 @@ CHIP_ERROR Device::SendMessage(System::PacketBufferHandle buffer, PayloadHeader
resend = buffer.CloneData();
}

CHIP_ERROR err = mSessionManager->SendMessage(mSecureSession, payloadHeader, std::move(buffer));
// TODO(#5675): This code is temporary, and must be updated to use the IM API. Currenlty, we use a temporary Protocol
// TempZCL to carry over legacy ZCL messages, use an ephemeral exchange to send message and use its unsolicited message
// handler to receive messages. We need to set flag kFromInitiator to allow receiver to deliver message to corresponding
// unsolicited message handler, and we also need to set flag kNoAutoRequestAck since there is no persistent exchange to
// receive the ack message. This logic need to be deleted after we converting all legacy ZCL messages to IM messages.
sendFlags.Set(Messaging::SendMessageFlags::kFromInitiator).Set(Messaging::SendMessageFlags::kNoAutoRequestAck);

CHIP_ERROR err = exchange->SendMessage(protocolId, msgType, std::move(buffer), sendFlags);

buffer = nullptr;
ChipLogDetail(Controller, "SendMessage returned %s", ErrorStr(err));
Expand All @@ -88,11 +99,16 @@ CHIP_ERROR Device::SendMessage(System::PacketBufferHandle buffer, PayloadHeader

ReturnErrorOnFailure(LoadSecureSessionParameters(ResetTransport::kYes));

err = mSessionManager->SendMessage(mSecureSession, std::move(resend));
err = exchange->SendMessage(protocolId, msgType, std::move(resend), sendFlags);
ChipLogDetail(Controller, "Re-SendMessage returned %d", err);
ReturnErrorOnFailure(err);
}

if (exchange != nullptr)
{
exchange->Close();
}

return CHIP_NO_ERROR;
}

Expand Down Expand Up @@ -132,12 +148,6 @@ CHIP_ERROR Device::SendCommands()
return mCommandSender->SendCommandRequest(mDeviceId, mAdminId);
}

CHIP_ERROR Device::SendMessage(System::PacketBufferHandle buffer)
{
PayloadHeader unusedHeader;
return SendMessage(std::move(buffer), unusedHeader);
}

CHIP_ERROR Device::Serialize(SerializedDevice & output)
{
CHIP_ERROR error = CHIP_NO_ERROR;
Expand Down Expand Up @@ -223,20 +233,19 @@ CHIP_ERROR Device::Deserialize(const SerializedDevice & input)
return error;
}

void Device::OnNewConnection(SecureSessionHandle session, SecureSessionMgr * mgr)
void Device::OnNewConnection(SecureSessionHandle session)
{
mState = ConnectionState::SecureConnected;
mSecureSession = session;
}

void Device::OnConnectionExpired(SecureSessionHandle session, SecureSessionMgr * mgr)
void Device::OnConnectionExpired(SecureSessionHandle session)
{
mState = ConnectionState::NotConnected;
mSecureSession = SecureSessionHandle{};
}

void Device::OnMessageReceived(const PacketHeader & header, const PayloadHeader & payloadHeader, SecureSessionHandle session,
System::PacketBufferHandle msgBuf, SecureSessionMgr * mgr)
void Device::OnMessageReceived(const PacketHeader & header, const PayloadHeader & payloadHeader, System::PacketBufferHandle msgBuf)
{
if (mState == ConnectionState::SecureConnected)
{
Expand Down Expand Up @@ -279,11 +288,7 @@ CHIP_ERROR Device::OpenPairingWindow(uint32_t timeout, PairingWindowOption optio
System::PacketBufferHandle outBuffer;
ReturnErrorOnFailure(writer.Finalize(&outBuffer));

PayloadHeader header;

header.SetMessageType(chip::Protocols::ServiceProvisioning::Id, 0);

ReturnErrorOnFailure(SendMessage(std::move(outBuffer), header));
ReturnErrorOnFailure(SendMessage(Protocols::ServiceProvisioning::Id, 0, std::move(outBuffer)));

setupPayload.version = 0;
setupPayload.rendezvousInformation = RendezvousInformationFlags(RendezvousInformationFlag::kBLE);
Expand Down
Loading

0 comments on commit a369e89

Please sign in to comment.