diff --git a/examples/lighting-app/efr32/args.gni b/examples/lighting-app/efr32/args.gni index 1b73ad66dcea58..d3853c338ba61e 100644 --- a/examples/lighting-app/efr32/args.gni +++ b/examples/lighting-app/efr32/args.gni @@ -22,3 +22,4 @@ pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip" pw_assert_BACKEND = "$dir_pw_assert_log" chip_enable_openthread = true chip_openthread_ftd = true +chip_system_config_use_ot_udp = true diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index 48067d02b4d85d..67a12cf897bc2c 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -127,6 +127,9 @@ CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint err = mTransports.Init(UdpListenParameters(DeviceLayer::UDPEndPointManager()) .SetAddressType(IPAddressType::kIPv6) .SetListenPort(mSecuredServicePort) +#if CHIP_SYSTEM_CONFIG_USE_OT_UDP + .SetOtInstance(chip::DeviceLayer::ThreadStackMgrImpl().OTInstance()) +#endif // CHIP_SYSTEM_CONFIG_USE_OT_UDP #if INET_CONFIG_ENABLE_IPV4 , @@ -149,10 +152,10 @@ CHIP_ERROR Server::Init(AppDelegate * delegate, uint16_t secureServicePort, uint // TODO : Fix this once GroupDataProvider is implemented #Issue 11075 // for (iterate through all GroupDataProvider multicast Address) // { -#ifdef CHIP_ENABLE_GROUP_MESSAGING_TESTS + //#ifdef CHIP_ENABLE_GROUP_MESSAGING_TESTS err = mTransports.MulticastGroupJoinLeave(Transport::PeerAddress::Multicast(1, 1234), true); SuccessOrExit(err); -#endif + //#endif //} err = mSessions.Init(&DeviceLayer::SystemLayer(), &mTransports, &mMessageCounterManager); diff --git a/src/inet/BUILD.gn b/src/inet/BUILD.gn index fc94850e7e7f8d..709b2c39a7e9f5 100644 --- a/src/inet/BUILD.gn +++ b/src/inet/BUILD.gn @@ -24,6 +24,10 @@ import("${chip_root}/src/lwip/lwip.gni") import("${chip_root}/src/platform/device.gni") import("inet.gni") +if (chip_system_config_use_ot_udp) { + import("//build_overrides/openthread.gni") +} + declare_args() { # Extra header to include in SystemConfig.h for project. chip_inet_project_config_include = "" @@ -50,10 +54,13 @@ buildconfig_header("inet_buildconfig") { [ "INET_PLATFORM_CONFIG_INCLUDE=${chip_inet_platform_config_include}" ] } - defines += [ - "INET_TCP_END_POINT_IMPL_CONFIG_FILE=", - "INET_UDP_END_POINT_IMPL_CONFIG_FILE=", - ] + defines += [ "INET_TCP_END_POINT_IMPL_CONFIG_FILE=" ] + if (chip_system_config_use_ot_udp) { + defines += + [ "INET_UDP_END_POINT_IMPL_CONFIG_FILE=" ] + } else { + defines += [ "INET_UDP_END_POINT_IMPL_CONFIG_FILE=" ] + } } source_set("inet_config_header") { @@ -105,6 +112,16 @@ static_library("inet") { public_deps += [ "${chip_root}/src/lwip" ] } + if (chip_system_config_use_ot_udp) { + if (chip_openthread_ftd) { + public_deps += + [ "${chip_root}/third_party/openthread/repo:libopenthread-ftd" ] + } else { + public_deps += + [ "${chip_root}/third_party/openthread/repo:libopenthread-mtd" ] + } + } + if (chip_inet_config_enable_tcp_endpoint) { sources += [ "TCPEndPoint.cpp", @@ -119,10 +136,20 @@ static_library("inet") { sources += [ "UDPEndPoint.cpp", "UDPEndPoint.h", - "UDPEndPointImpl${chip_system_config_inet}.cpp", - "UDPEndPointImpl${chip_system_config_inet}.h", "UDPEndPointImpl.h", ] + + if (chip_system_config_use_ot_udp) { + sources += [ + "UDPEndPointImplOT.cpp", + "UDPEndPointImplOT.h", + ] + } else { + sources += [ + "UDPEndPointImpl${chip_system_config_inet}.cpp", + "UDPEndPointImpl${chip_system_config_inet}.h", + ] + } } if (chip_with_nlfaultinjection) { diff --git a/src/inet/UDPEndPoint.h b/src/inet/UDPEndPoint.h index 005dccf26eb8b5..e9a603f7a2dcd5 100644 --- a/src/inet/UDPEndPoint.h +++ b/src/inet/UDPEndPoint.h @@ -37,6 +37,8 @@ #include #include +struct otInstance; + namespace chip { namespace Inet { @@ -245,6 +247,8 @@ class DLL_EXPORT UDPEndPoint : public EndPointBasis */ virtual void Free() = 0; + virtual inline void SetOtInstance(otInstance * instance) { (void) instance; } + protected: UDPEndPoint(EndPointManager & endPointManager) : EndPointBasis(endPointManager), mState(State::kReady), OnMessageReceived(nullptr), OnReceiveError(nullptr) diff --git a/src/inet/UDPEndPointImplOT.cpp b/src/inet/UDPEndPointImplOT.cpp new file mode 100644 index 00000000000000..7634523fe65224 --- /dev/null +++ b/src/inet/UDPEndPointImplOT.cpp @@ -0,0 +1,273 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2018 Google LLC. + * Copyright (c) 2013-2018 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This file implements Inet::UDPEndPoint using OpenThread. + */ + +#include + +#include +#include +#include + +#include +//#include + +#include + +namespace chip { +namespace Inet { + +void UDPEndPointImplOT::handleUdpReceive(void * aContext, otMessage * aMessage, const otMessageInfo * aMessageInfo) +{ + UDPEndPointImplOT * ep = static_cast(aContext); + IPPacketInfo pktInfo; + uint16_t msgLen = otMessageGetLength(aMessage); + System::PacketBufferHandle payload; +#if CHIP_DETAIL_LOGGING + static uint16_t msgReceivedCount = 0; + char sourceStr[Inet::IPAddress::kMaxStringLength]; + char destStr[Inet::IPAddress::kMaxStringLength]; +#endif + + if (msgLen > System::PacketBuffer::kMaxSizeWithoutReserve) + { + ChipLogError(Inet, "UDP message too long, discarding. Size received %d", msgLen); + return; + } + + pktInfo.SrcAddress = chip::DeviceLayer::Internal::ToIPAddress(aMessageInfo->mPeerAddr); + pktInfo.DestAddress = chip::DeviceLayer::Internal::ToIPAddress(aMessageInfo->mSockAddr); + pktInfo.SrcPort = aMessageInfo->mPeerPort; + pktInfo.DestPort = aMessageInfo->mSockPort; + + payload = System::PacketBufferHandle::New(msgLen, 0); + + if (payload.IsNull()) + { + ChipLogError(Inet, "Failed to allocate a System buffer of size %d for UDP Message reception.", msgLen); + return; + } + +#if CHIP_DETAIL_LOGGING + pktInfo.SrcAddress.ToString(sourceStr, Inet::IPAddress::kMaxStringLength); + pktInfo.DestAddress.ToString(destStr, Inet::IPAddress::kMaxStringLength); + + ChipLogDetail(Inet, + "UDP Message Received packet nb : %d with the following data :\r\nSrcAddr : %s\r\nSrc Port : %d\r\n\r\nDestAddr " + ": %s\r\nDest Port %d\r\nPayload Length %d", + ++msgReceivedCount, sourceStr, pktInfo.SrcPort, destStr, pktInfo.DestPort, msgLen); + +#endif + + memcpy(payload->Start(), &pktInfo, sizeof(IPPacketInfo)); + + if (otMessageRead(aMessage, 0, payload->Start() + sizeof(IPPacketInfo), msgLen) != msgLen) + { + ChipLogError(Inet, "Failed to copy OpenThread buffer into System Packet buffer"); + return; + } + payload->SetDataLength(msgLen + sizeof(IPPacketInfo)); + + ep->Retain(); + CHIP_ERROR err = ep->GetSystemLayer().ScheduleLambda([ep, p = System::LwIPPacketBufferView::UnsafeGetLwIPpbuf(payload)] { + ep->HandleDataReceived(System::PacketBufferHandle::Adopt(p)); + ep->Release(); + }); + if (err == CHIP_NO_ERROR) + { + // If ScheduleLambda() succeeded, it has ownership of the buffer, so we need to release it (without freeing it). + static_cast(std::move(payload).UnsafeRelease()); + } + else + { + ep->Release(); + } +} + +CHIP_ERROR UDPEndPointImplOT::IPv6Bind(otUdpSocket & socket, const IPAddress & address, uint16_t port, InterfaceId interface) +{ + (void) interface; + otError err = OT_ERROR_NONE; + otSockAddr listenSockAddr; + + memset(&socket, 0, sizeof(socket)); + memset(&listenSockAddr, 0, sizeof(listenSockAddr)); + + listenSockAddr.mPort = port; + listenSockAddr.mAddress = chip::DeviceLayer::Internal::ToOpenThreadIP6Address(address); + + otUdpOpen(mOTInstance, &socket, handleUdpReceive, this); + otUdpBind(mOTInstance, &socket, &listenSockAddr, OT_NETIF_THREAD); + + return chip::DeviceLayer::Internal::MapOpenThreadError(err); +} + +CHIP_ERROR UDPEndPointImplOT::BindImpl(IPAddressType addressType, const IPAddress & addr, uint16_t port, InterfaceId interface) +{ + + if (addressType == IPAddressType::kIPv6) + { + ReturnErrorOnFailure(IPv6Bind(mSocket, addr, port, interface)); + } + else + { + return INET_ERROR_WRONG_ADDRESS_TYPE; + } + + mBoundPort = port; + mBoundIntfId = interface; + + return CHIP_NO_ERROR; +} + +InterfaceId UDPEndPointImplOT::GetBoundInterface() const +{ + return mBoundIntfId; +} + +uint16_t UDPEndPointImplOT::GetBoundPort() const +{ + return mBoundPort; +} + +CHIP_ERROR UDPEndPointImplOT::ListenImpl() +{ + // Nothing to do. Callback was set upon Binding call. + return CHIP_NO_ERROR; +} + +void UDPEndPointImplOT::HandleDataReceived(System::PacketBufferHandle && msg) +{ + if ((mState == State::kListening) && (OnMessageReceived != nullptr)) + { + const IPPacketInfo * pktInfo = GetPacketInfo(msg); + + if (pktInfo != nullptr) + { + const IPPacketInfo pktInfoCopy = *pktInfo; // copy the address info so that the app can free the + // PacketBuffer without affecting access to address info. + + msg->ConsumeHead(sizeof(IPPacketInfo)); + OnMessageReceived(this, std::move(msg), &pktInfoCopy); + } + else + { + if (OnReceiveError != nullptr) + { + OnReceiveError(this, CHIP_ERROR_INBOUND_MESSAGE_TOO_BIG, nullptr); + } + } + } +} + +CHIP_ERROR UDPEndPointImplOT::SetMulticastLoopback(IPVersion aIPVersion, bool aLoopback) +{ + (void) aIPVersion; + (void) aLoopback; + // TODO + return CHIP_NO_ERROR; +} + +CHIP_ERROR UDPEndPointImplOT::BindInterfaceImpl(IPAddressType addressType, InterfaceId interfaceId) +{ + (void) addressType; + (void) interfaceId; + return CHIP_NO_ERROR; +} + +CHIP_ERROR UDPEndPointImplOT::SendMsgImpl(const IPPacketInfo * aPktInfo, System::PacketBufferHandle && msg) +{ + otError error = OT_ERROR_NONE; + otMessage * message; + otMessageInfo messageInfo; + + // For now the entire message must fit within a single buffer. + VerifyOrReturnError(!msg->HasChainedBuffer(), CHIP_ERROR_MESSAGE_TOO_LONG); + + memset(&messageInfo, 0, sizeof(messageInfo)); + + messageInfo.mSockAddr = chip::DeviceLayer::Internal::ToOpenThreadIP6Address(aPktInfo->SrcAddress); + messageInfo.mPeerAddr = chip::DeviceLayer::Internal::ToOpenThreadIP6Address(aPktInfo->DestAddress); + messageInfo.mPeerPort = aPktInfo->DestPort; + + message = otUdpNewMessage(mOTInstance, NULL); + VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS); + + error = otMessageAppend(message, msg->Start(), msg->DataLength()); + + if (error == OT_ERROR_NONE) + { + error = otUdpSend(mOTInstance, &mSocket, message, &messageInfo); + } + +exit: + if (error != OT_ERROR_NONE && message != NULL) + { + otMessageFree(message); + } + + return chip::DeviceLayer::Internal::MapOpenThreadError(error); +} + +void UDPEndPointImplOT::CloseImpl() +{ + if (otUdpIsOpen(mOTInstance, &mSocket)) + { + otUdpClose(mOTInstance, &mSocket); + } +} + +void UDPEndPointImplOT::Free() +{ + Close(); + Release(); +} + +CHIP_ERROR UDPEndPointImplOT::IPv6JoinLeaveMulticastGroupImpl(InterfaceId aInterfaceId, const IPAddress & aAddress, bool join) +{ + const otIp6Address otAddress = chip::DeviceLayer::Internal::ToOpenThreadIP6Address(aAddress); + + if (join) + { + return chip::DeviceLayer::Internal::MapOpenThreadError(otIp6SubscribeMulticastAddress(mOTInstance, &otAddress)); + } + else + { + return chip::DeviceLayer::Internal::MapOpenThreadError(otIp6UnsubscribeMulticastAddress(mOTInstance, &otAddress)); + } +} + +IPPacketInfo * UDPEndPointImplOT::GetPacketInfo(const System::PacketBufferHandle & aBuffer) +{ + if (!aBuffer->EnsureReservedSize(sizeof(IPPacketInfo))) + { + return nullptr; + } + + uintptr_t lStart = (uintptr_t) aBuffer->Start(); + uintptr_t lPacketInfoStart = lStart - sizeof(IPPacketInfo); + + // Align to a 4-byte boundary + return reinterpret_cast(lPacketInfoStart & ~(sizeof(uint32_t) - 1)); +} + +} // namespace Inet +} // namespace chip diff --git a/src/inet/UDPEndPointImplOT.h b/src/inet/UDPEndPointImplOT.h new file mode 100644 index 00000000000000..6a53fac903b4e5 --- /dev/null +++ b/src/inet/UDPEndPointImplOT.h @@ -0,0 +1,75 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2018 Google LLC + * Copyright (c) 2013-2017 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This file declares an implementation of Inet::UDPEndPoint using sockets. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace Inet { + +class UDPEndPointImplOT : public UDPEndPoint +{ +public: + UDPEndPointImplOT(EndPointManager & endPointManager) : + UDPEndPoint(endPointManager), mBoundIntfId(InterfaceId::Null()) + {} + + // UDPEndPoint overrides. + InterfaceId GetBoundInterface() const override; + uint16_t GetBoundPort() const override; + void Free() override; + void HandleDataReceived(System::PacketBufferHandle && msg); + inline void SetOtInstance(otInstance * instance) { mOTInstance = instance; } + CHIP_ERROR SetMulticastLoopback(IPVersion aIPVersion, bool aLoopback) override; + CHIP_ERROR BindInterfaceImpl(IPAddressType addressType, InterfaceId interfaceId) override; + +private: + // UDPEndPoint overrides. + CHIP_ERROR IPv6JoinLeaveMulticastGroupImpl(InterfaceId aInterfaceId, const IPAddress & aAddress, bool join) override; + CHIP_ERROR BindImpl(IPAddressType addressType, const IPAddress & address, uint16_t port, InterfaceId interfaceId) override; + CHIP_ERROR ListenImpl() override; + CHIP_ERROR SendMsgImpl(const IPPacketInfo * pktInfo, chip::System::PacketBufferHandle && msg) override; + void CloseImpl() override; + CHIP_ERROR IPv6Bind(otUdpSocket & socket, const IPAddress & address, uint16_t port, InterfaceId interface); + static IPPacketInfo * GetPacketInfo(const System::PacketBufferHandle & aBuffer); + + static void handleUdpReceive(void * aContext, otMessage * aMessage, const otMessageInfo * aMessageInfo); + + InterfaceId mBoundIntfId; + uint16_t mBoundPort; + otUdpSocket mSocket; + otInstance * mOTInstance = nullptr; +}; + +using UDPEndPointImpl = UDPEndPointImplOT; + +} // namespace Inet +} // namespace chip diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp index 957dc20a05ab24..c81becc6a0dbbf 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread_LwIP.cpp @@ -34,8 +34,13 @@ #include #include +#include + #include +#include +#include + namespace chip { namespace DeviceLayer { namespace Internal { @@ -225,6 +230,40 @@ void GenericThreadStackManagerImpl_OpenThread_LwIP::UpdateThreadInter addrAssigned[addrIdx] = true; } } + +// Multicast won't work with LWIP on top of OT +// Duplication of listeners, unecessary timers, buffer duplication, hardfault etc... +#if CHIP_SYSTEM_CONFIG_USE_OT_UDP + // Refresh Multicast listening + if (GenericThreadStackManagerImpl_OpenThread::IsThreadAttachedNoLock()) + { + ChipLogDetail(DeviceLayer, "Thread Attached updating Multicast address"); + + Credentials::GroupDataProvider * provider = Credentials::GetGroupDataProvider(); + TransportMgrBase * transportMgr = &(chip::Server::GetInstance().GetTransportManager()); + Credentials::GroupDataProvider::GroupInfo group; + CHIP_ERROR err = CHIP_NO_ERROR; + for (const FabricInfo & fabricInfo : Server::GetInstance().GetFabricTable()) + { + auto it = provider->IterateGroupInfo(fabricInfo.GetFabricIndex()); + if (it) + { + while (it->Next(group)) + { + err = transportMgr->MulticastGroupJoinLeave( + Transport::PeerAddress::Multicast(fabricInfo.GetFabricIndex(), group.group_id), true); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to Join Multicast Group: %s", err.AsString()); + it->Release(); + break; + } + } + it->Release(); + } + } + } +#endif // CHIP_SYSTEM_CONFIG_USE_OT_UDP } ChipLogDetail(DeviceLayer, "LwIP Thread interface addresses %s", isInterfaceUp ? "updated" : "cleared"); diff --git a/src/system/BUILD.gn b/src/system/BUILD.gn index 874bc3cdc0171d..e5b441a25770b5 100644 --- a/src/system/BUILD.gn +++ b/src/system/BUILD.gn @@ -59,6 +59,7 @@ buildconfig_header("system_buildconfig") { "CHIP_WITH_NLFAULTINJECTION=${chip_with_nlfaultinjection}", "CHIP_SYSTEM_CONFIG_USE_DISPATCH=${chip_system_config_use_dispatch}", "CHIP_SYSTEM_CONFIG_USE_LWIP=${chip_system_config_use_lwip}", + "CHIP_SYSTEM_CONFIG_USE_OT_UDP=${chip_system_config_use_ot_udp}", "CHIP_SYSTEM_CONFIG_USE_SOCKETS=${chip_system_config_use_sockets}", "CHIP_SYSTEM_CONFIG_USE_NETWORK_FRAMEWORK=false", "CHIP_SYSTEM_CONFIG_POSIX_LOCKING=${chip_system_config_posix_locking}", diff --git a/src/system/SystemPacketBuffer.h b/src/system/SystemPacketBuffer.h index 031a397c422bba..6f973229d8998a 100644 --- a/src/system/SystemPacketBuffer.h +++ b/src/system/SystemPacketBuffer.h @@ -847,6 +847,13 @@ namespace Inet { class UDPEndPointImplLwIP; } // namespace Inet +#if CHIP_SYSTEM_CONFIG_USE_OT_UDP +// TODO : Temp Implementation issue : 13085 +namespace Inet { +class UDPEndPointImplOT; +} // namespace Inet +#endif + namespace System { /** @@ -864,6 +871,10 @@ class LwIPPacketBufferView : public PacketBufferHandle */ static struct pbuf * UnsafeGetLwIPpbuf(const PacketBufferHandle & handle) { return PacketBufferHandle::GetLwIPpbuf(handle); } friend class Inet::UDPEndPointImplLwIP; +#if CHIP_SYSTEM_CONFIG_USE_OT_UDP + // TODO : Temp Implementation issue : 13085 + friend class Inet::UDPEndPointImplOT; +#endif }; } // namespace System diff --git a/src/system/system.gni b/src/system/system.gni index 12e371a7c29d1b..df7a38d35c394c 100644 --- a/src/system/system.gni +++ b/src/system/system.gni @@ -31,6 +31,9 @@ declare_args() { # Enable metrics collection. chip_system_config_provide_statistics = true + + # Use OpenThread UDP stack directly + chip_system_config_use_ot_udp = false } declare_args() { diff --git a/src/transport/raw/UDP.cpp b/src/transport/raw/UDP.cpp index d1d996fa6a2043..ae9652487c2643 100644 --- a/src/transport/raw/UDP.cpp +++ b/src/transport/raw/UDP.cpp @@ -49,12 +49,16 @@ CHIP_ERROR UDP::Init(UdpListenParameters & params) err = params.GetEndPointManager()->NewEndPoint(&mUDPEndPoint); SuccessOrExit(err); +#if CHIP_SYSTEM_CONFIG_USE_OT_UDP + mUDPEndPoint->SetOtInstance(params.GetOtInstance()); +#endif // CHIP_SYSTEM_CONFIG_USE_OT_UDP + ChipLogDetail(Inet, "UDP::Init bind&listen port=%d", params.GetListenPort()); err = mUDPEndPoint->Bind(params.GetAddressType(), Inet::IPAddress::Any, params.GetListenPort(), params.GetInterfaceId()); SuccessOrExit(err); - err = mUDPEndPoint->Listen(OnUdpReceive, nullptr /*onReceiveError*/, this); + err = mUDPEndPoint->Listen(OnUdpReceive, OnUdpError, this); SuccessOrExit(err); mUDPEndpointType = params.GetAddressType(); @@ -125,6 +129,11 @@ void UDP::OnUdpReceive(Inet::UDPEndPoint * endPoint, System::PacketBufferHandle } } +void UDP::OnUdpError(Inet::UDPEndPoint * endPoint, CHIP_ERROR err, const Inet::IPPacketInfo * pktInfo) +{ + ChipLogError(Inet, "Failed to receive UDP message: %s", ErrorStr(err)); +} + CHIP_ERROR UDP::MulticastGroupJoinLeave(const Transport::PeerAddress & address, bool join) { char addressStr[Transport::PeerAddress::kMaxToStringSize]; diff --git a/src/transport/raw/UDP.h b/src/transport/raw/UDP.h index fcdc624eb06d81..ab4f1b4de85ffa 100644 --- a/src/transport/raw/UDP.h +++ b/src/transport/raw/UDP.h @@ -34,6 +34,10 @@ #include #include +#if CHIP_SYSTEM_CONFIG_USE_OT_UDP +struct otInstance; +#endif // CHIP_SYSTEM_CONFIG_USE_OT_UDP + namespace chip { namespace Transport { @@ -76,6 +80,21 @@ class UdpListenParameters Inet::IPAddressType mAddressType = Inet::IPAddressType::kIPv6; ///< type of listening socket uint16_t mListenPort = CHIP_PORT; ///< UDP listen port Inet::InterfaceId mInterfaceId = Inet::InterfaceId::Null(); ///< Interface to listen on + +#if CHIP_SYSTEM_CONFIG_USE_OT_UDP +public: + otInstance * GetOtInstance() const { return mOtInstance; } + UdpListenParameters & SetOtInstance(otInstance * instance) + { + mOtInstance = instance; + + return *this; + } + +private: + otInstance * mOtInstance = nullptr; + +#endif // CHIP_SYSTEM_CONFIG_USE_OT_UDP }; /** Implements a transport using UDP. */ @@ -133,6 +152,8 @@ class DLL_EXPORT UDP : public Base static void OnUdpReceive(Inet::UDPEndPoint * endPoint, System::PacketBufferHandle && buffer, const Inet::IPPacketInfo * pktInfo); + static void OnUdpError(Inet::UDPEndPoint * endPoint, CHIP_ERROR err, const Inet::IPPacketInfo * pktInfo); + Inet::UDPEndPoint * mUDPEndPoint = nullptr; ///< UDP socket used by the transport Inet::IPAddressType mUDPEndpointType = Inet::IPAddressType::kUnknown; ///< Socket listening type State mState = State::kNotReady; ///< State of the UDP transport