Skip to content

Commit

Permalink
Add multicast listening on linux
Browse files Browse the repository at this point in the history
  • Loading branch information
jepenven-silabs committed Nov 30, 2021
1 parent 2bd6bd6 commit ac1a3d2
Show file tree
Hide file tree
Showing 14 changed files with 136 additions and 115 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
- name: Build all clusters app
timeout-minutes: 5
run: |
scripts/examples/gn_build_example.sh examples/all-clusters-app/linux out/debug/standalone/ chip_config_network_layer_ble=false is_tsan=${USE_TSAN}
scripts/examples/gn_build_example.sh examples/all-clusters-app/linux out/debug/standalone/ chip_config_network_layer_ble=false chip_enable_Test_Group=true is_tsan=${USE_TSAN}
- name: Build TV app
timeout-minutes: 5
run: |
Expand Down
9 changes: 9 additions & 0 deletions src/app/server/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,21 @@
import("//build_overrides/chip.gni")
import("${chip_root}/src/app/common_flags.gni")

# Move this inside the GroupDataProvider once implemented Issue #11075
declare_args() {
chip_enable_Test_Group = false
}

config("server_config") {
defines = []

if (chip_app_use_echo) {
defines += [ "CHIP_APP_USE_ECHO" ]
}

if (chip_enable_Test_Group) {
defines += [ "TEST_SUITE_GROUP" ]
}
}

static_library("server") {
Expand Down
10 changes: 10 additions & 0 deletions src/app/server/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,16 @@ CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint
#endif
SuccessOrExit(err);

// Enable Group Listening
// TODO : Fix this once GroupDataProvider is implemented #Issue 11075
// for (iterate through all GroupDataProvider multicast Address)
// {
#ifdef TEST_SUITE_GROUP
err = mTransports.MulticastGroupJoinLeave(Transport::PeerAddress::Multicast(1, 1234), true);
SuccessOrExit(err);
#endif
//}

err = mSessions.Init(&DeviceLayer::SystemLayer(), &mTransports, &mMessageCounterManager);
SuccessOrExit(err);

Expand Down
1 change: 0 additions & 1 deletion src/darwin/Framework/CHIP/templates/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ function getTests()
'TestIdentifyCluster',
'TestOperationalCredentialsCluster',
'TestModeSelectCluster',
'TestGroupMessaging',
];

const SoftwareDiagnostics = [
Expand Down
93 changes: 0 additions & 93 deletions src/darwin/Framework/CHIPTests/CHIPClustersTests.m

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 3 additions & 6 deletions src/inet/UDPEndPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ namespace {

CHIP_ERROR CheckMulticastGroupArgs(InterfaceId aInterfaceId, const IPAddress & aAddress)
{
VerifyOrReturnError(aInterfaceId.IsPresent(), INET_ERROR_UNKNOWN_INTERFACE);
// Skip verification of Interface since IsPresent() always fail
// VerifyOrReturnError(aInterfaceId.IsPresent(), INET_ERROR_UNKNOWN_INTERFACE);
VerifyOrReturnError(aAddress.IsMulticast(), INET_ERROR_WRONG_ADDRESS_TYPE);
return CHIP_NO_ERROR;
}
Expand Down Expand Up @@ -1424,7 +1425,6 @@ CHIP_ERROR UDPEndPointImplSockets::IPv6JoinLeaveMulticastGroupImpl(InterfaceId a
}
#endif // CHIP_SYSTEM_CONFIG_USE_PLATFORM_MULTICAST_API

#if defined(INET_IPV6_ADD_MEMBERSHIP) && defined(INET_IPV6_DROP_MEMBERSHIP)
const InterfaceId::PlatformType lIfIndex = aInterfaceId.GetPlatformInterface();

struct ipv6_mreq lMulticastRequest;
Expand All @@ -1440,9 +1440,6 @@ CHIP_ERROR UDPEndPointImplSockets::IPv6JoinLeaveMulticastGroupImpl(InterfaceId a
return CHIP_ERROR_POSIX(errno);
}
return CHIP_NO_ERROR;
#else // defined(INET_IPV6_ADD_MEMBERSHIP) && defined(INET_IPV6_DROP_MEMBERSHIP)
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
#endif // defined(INET_IPV6_ADD_MEMBERSHIP) && defined(INET_IPV6_DROP_MEMBERSHIP)
}

#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
Expand Down Expand Up @@ -2030,7 +2027,7 @@ void UDPEndPoint::Close()

CHIP_ERROR UDPEndPoint::JoinMulticastGroup(InterfaceId aInterfaceId, const IPAddress & aAddress)
{
CHIP_ERROR lRetval = CHIP_ERROR_NOT_IMPLEMENTED;
CHIP_ERROR lRetval = CHIP_NO_ERROR;

const IPAddressType lAddrType = aAddress.Type();
lRetval = CheckMulticastGroupArgs(aInterfaceId, aAddress);
Expand Down
4 changes: 4 additions & 0 deletions src/messaging/ExchangeMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,10 @@ void ExchangeManager::OnMessageReceived(const PacketHeader & packetHeader, const
return;
}
}
else
{
ChipLogProgress(ExchangeManager, "Received Groupcast Message with GroupId of %d", packetHeader.GetDestinationGroupId().Value());
}

// If it's not a duplicate message, search for an unsolicited message handler if it is marked as being sent by an initiator.
// Since we didn't find an existing exchange that matches the message, it must be an unsolicited message. However all
Expand Down
47 changes: 33 additions & 14 deletions src/transport/SessionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,25 +195,44 @@ CHIP_ERROR SessionManager::SendPreparedMessage(SessionHandle sessionHandle, cons

if (sessionHandle.IsSecure())
{
// Find an active connection to the specified peer node
SecureSession * session = GetSecureSession(sessionHandle);
if (session == nullptr)
if (sessionHandle.IsGroupSession())
{
ChipLogError(Inet, "Secure transport could not find a valid PeerConnection");
return CHIP_ERROR_NOT_CONNECTED;
chip::Transport::PeerAddress multicastAddress =
Transport::PeerAddress::Multicast(sessionHandle.GetFabricIndex(), sessionHandle.GetGroupId().Value());
destination = static_cast<Transport::PeerAddress *>(&multicastAddress);
char addressStr[72];
multicastAddress.ToString(addressStr, 72);

ChipLogProgress(Inet,
"Sending %s msg %p with MessageCounter:" ChipLogFormatMessageCounter " to %d"
" at monotonic time: %" PRId64
" msec to Multicast IPV6 address : %s with GroupID of %d and fabric Id of %d",
"encrypted", &preparedMessage, preparedMessage.GetMessageCounter(), sessionHandle.GetGroupId().Value(),
System::SystemClock().GetMonotonicMilliseconds64().count(), addressStr,
sessionHandle.GetGroupId().Value(), sessionHandle.GetFabricIndex());
}
else
{
// Find an active connection to the specified peer node
SecureSession * session = GetSecureSession(sessionHandle);
if (session == nullptr)
{
ChipLogError(Inet, "Secure transport could not find a valid PeerConnection");
return CHIP_ERROR_NOT_CONNECTED;
}

// This marks any connection where we send data to as 'active'
mSecureSessions.MarkSessionActive(session);
// This marks any connection where we send data to as 'active'
mSecureSessions.MarkSessionActive(session);

destination = &session->GetPeerAddress();
destination = &session->GetPeerAddress();

ChipLogProgress(Inet,
"Sending %s msg %p with MessageCounter:" ChipLogFormatMessageCounter " to 0x" ChipLogFormatX64
" (%u) at monotonic time: %" PRId64 " msec",
"encrypted", &preparedMessage, preparedMessage.GetMessageCounter(),
ChipLogValueX64(session->GetPeerNodeId()), session->GetFabricIndex(),
System::SystemClock().GetMonotonicMilliseconds64().count());
ChipLogProgress(Inet,
"Sending %s msg %p with MessageCounter:" ChipLogFormatMessageCounter " to 0x" ChipLogFormatX64
" (%u) at monotonic time: %" PRId64 " msec",
"encrypted", &preparedMessage, preparedMessage.GetMessageCounter(),
ChipLogValueX64(session->GetPeerNodeId()), session->GetFabricIndex(),
System::SystemClock().GetMonotonicMilliseconds64().count());
}
}
else
{
Expand Down
5 changes: 5 additions & 0 deletions src/transport/TransportMgrBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ void TransportMgrBase::Close()
mTransport = nullptr;
}

CHIP_ERROR TransportMgrBase::MulticastGroupJoinLeave(const Transport::PeerAddress & address, bool join)
{
return mTransport->MulticastGroupJoinLeave(address, join);
}

void TransportMgrBase::HandleMessageReceived(const Transport::PeerAddress & peerAddress, System::PacketBufferHandle && msg)
{
if (msg->HasChainedBuffer())
Expand Down
2 changes: 2 additions & 0 deletions src/transport/TransportMgrBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class TransportMgrBase : public Transport::RawTransportDelegate

void SetSessionManager(TransportMgrDelegate * sessionManager) { mSessionManager = sessionManager; }

CHIP_ERROR MulticastGroupJoinLeave(const Transport::PeerAddress & address, bool join);

void HandleMessageReceived(const Transport::PeerAddress & peerAddress, System::PacketBufferHandle && msg) override;

private:
Expand Down
10 changes: 10 additions & 0 deletions src/transport/raw/Base.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,21 @@ class Base
*/
virtual bool CanSendToPeer(const PeerAddress & address) = 0;

/**
* Determine if this transport can Listen to IPV6 Multicast.
*/
virtual bool CanListenMulticast() { return false; }

/**
* Handle disconnection from the specified peer if currently connected to it.
*/
virtual void Disconnect(const PeerAddress & address) {}

/**
* Enable Listening for multicast messages ( IPV6 UDP only)
*/
virtual CHIP_ERROR MulticastGroupJoinLeave(const Transport::PeerAddress & address, bool join) { return CHIP_ERROR_INTERNAL; }

/**
* Close the open endpoint without destroying the object
*/
Expand Down
35 changes: 35 additions & 0 deletions src/transport/raw/Tuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ class Tuple : public Base
return SendMessageImpl<0>(address, std::move(msgBuf));
}

CHIP_ERROR MulticastGroupJoinLeave(const Transport::PeerAddress & address, bool join) override
{
return MulticastGroupJoinLeaveImpl<0>(address, join);
}

bool CanSendToPeer(const PeerAddress & address) override { return CanSendToPeerImpl<0>(address); }

void Disconnect(const PeerAddress & address) override { return DisconnectImpl<0>(address); }
Expand Down Expand Up @@ -203,6 +208,36 @@ class Tuple : public Base
return CHIP_ERROR_NO_MESSAGE_HANDLER;
}

/**
* Recursive GroupJoinLeave implementation iterating through transport members.
*
* Listener is activated through the first transport from index N or above, which returns 'CanListenMulticast'
*
* @tparam N the index of the underlying transport to run GroupJoinLeave through.
*
* @param address where to send the message
* @param msgBuf the message to send. Includes all CHIP message fields except optional length.
*/
template <size_t N, typename std::enable_if<(N < sizeof...(TransportTypes))>::type * = nullptr>
CHIP_ERROR MulticastGroupJoinLeaveImpl(const Transport::PeerAddress & address, bool join)
{
Base * base = &std::get<N>(mTransports);
if (base->CanListenMulticast())
{
return base->MulticastGroupJoinLeave(address, join);
}
return MulticastGroupJoinLeaveImpl<N + 1>(address, join);
}

/**
* GroupJoinLeave when N is out of range. Always returns an error code.
*/
template <size_t N, typename std::enable_if<(N >= sizeof...(TransportTypes))>::type * = nullptr>
CHIP_ERROR MulticastGroupJoinLeaveImpl(const Transport::PeerAddress & address, bool join)
{
return CHIP_ERROR_NO_MESSAGE_HANDLER;
}

/**
* Recursive init implementation iterating through transport members
*
Expand Down
17 changes: 17 additions & 0 deletions src/transport/raw/UDP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,5 +125,22 @@ void UDP::OnUdpReceive(Inet::UDPEndPoint * endPoint, System::PacketBufferHandle
}
}

CHIP_ERROR UDP::MulticastGroupJoinLeave(const Transport::PeerAddress & address, bool join)
{
char addressStr[72];
address.ToString(addressStr, 72);

if (join)
{
ChipLogProgress(Inet, "Joining Multicast Group with address %s", addressStr);
return mUDPEndPoint->JoinMulticastGroup(mUDPEndPoint->GetBoundInterface(), address.GetIPAddress());
}
else
{
ChipLogProgress(Inet, "Leaving Multicast Group with address %s", addressStr);
return mUDPEndPoint->LeaveMulticastGroup(mUDPEndPoint->GetBoundInterface(), address.GetIPAddress());
}
}

} // namespace Transport
} // namespace chip
7 changes: 7 additions & 0 deletions src/transport/raw/UDP.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ class DLL_EXPORT UDP : public Base

CHIP_ERROR SendMessage(const Transport::PeerAddress & address, System::PacketBufferHandle && msgBuf) override;

CHIP_ERROR MulticastGroupJoinLeave(const Transport::PeerAddress & address, bool join) override;

bool CanListenMulticast() override
{
return (mState == State::kInitialized) && (mUDPEndpointType == Inet::IPAddressType::kIPv6);
}

bool CanSendToPeer(const Transport::PeerAddress & address) override
{
return (mState == State::kInitialized) && (address.GetTransportType() == Type::kUdp) &&
Expand Down

0 comments on commit ac1a3d2

Please sign in to comment.