diff --git a/include/openthread/instance.h b/include/openthread/instance.h index 65c6df56b..01894ec17 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (128) +#define OPENTHREAD_API_VERSION (129) /** * @addtogroup api-instance diff --git a/include/openthread/udp.h b/include/openthread/udp.h index 02773197d..344373aea 100644 --- a/include/openthread/udp.h +++ b/include/openthread/udp.h @@ -160,6 +160,17 @@ otMessage *otUdpNewMessage(otInstance *aInstance, const otMessageSettings *aSett */ otError otUdpOpen(otInstance *aInstance, otUdpSocket *aSocket, otUdpReceive aCallback, void *aContext); +/** + * Check if a UDP socket is open. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * @param[in] aSocket A pointer to a UDP socket structure. + * + * @returns Whether the UDP socket is open. + * + */ +bool otUdpIsOpen(otInstance *aInstance, const otUdpSocket *aSocket); + /** * Close a UDP/IPv6 socket. * diff --git a/src/cli/cli_udp.cpp b/src/cli/cli_udp.cpp index eae8582d2..02d3e1219 100644 --- a/src/cli/cli_udp.cpp +++ b/src/cli/cli_udp.cpp @@ -109,7 +109,13 @@ otError UdpExample::ProcessOpen(uint8_t aArgsLength, Arg aArgs[]) OT_UNUSED_VARIABLE(aArgsLength); OT_UNUSED_VARIABLE(aArgs); - return otUdpOpen(mInterpreter.mInstance, &mSocket, HandleUdpReceive, this); + otError error; + + VerifyOrExit(!otUdpIsOpen(mInterpreter.mInstance, &mSocket), error = OT_ERROR_ALREADY); + error = otUdpOpen(mInterpreter.mInstance, &mSocket, HandleUdpReceive, this); + +exit: + return error; } otError UdpExample::ProcessSend(uint8_t aArgsLength, Arg aArgs[]) diff --git a/src/core/api/udp_api.cpp b/src/core/api/udp_api.cpp index 567a027cc..deaaf8940 100644 --- a/src/core/api/udp_api.cpp +++ b/src/core/api/udp_api.cpp @@ -56,6 +56,13 @@ otError otUdpOpen(otInstance *aInstance, otUdpSocket *aSocket, otUdpReceive aCal return instance.Get().Open(*static_cast(aSocket), aCallback, aContext); } +bool otUdpIsOpen(otInstance *aInstance, const otUdpSocket *aSocket) +{ + Instance &instance = *static_cast(aInstance); + + return instance.Get().IsOpen(*static_cast(aSocket)); +} + otError otUdpClose(otInstance *aInstance, otUdpSocket *aSocket) { Instance &instance = *static_cast(aInstance); diff --git a/src/core/net/dhcp6_server.cpp b/src/core/net/dhcp6_server.cpp index 8f1ca54a2..5f2e23310 100644 --- a/src/core/net/dhcp6_server.cpp +++ b/src/core/net/dhcp6_server.cpp @@ -133,8 +133,13 @@ Error Server::UpdateService(void) void Server::Start(void) { + VerifyOrExit(!mSocket.IsOpen()); + IgnoreError(mSocket.Open(&Server::HandleUdpReceive, this)); IgnoreError(mSocket.Bind(kDhcpServerPort)); + +exit: + return; } void Server::Stop(void) diff --git a/src/core/net/udp6.cpp b/src/core/net/udp6.cpp index 3df27e59c..59c78befc 100644 --- a/src/core/net/udp6.cpp +++ b/src/core/net/udp6.cpp @@ -87,6 +87,11 @@ Error Udp::Socket::Open(otUdpReceive aHandler, void *aContext) return Get().Open(*this, aHandler, aContext); } +bool Udp::Socket::IsOpen(void) const +{ + return Get().IsOpen(*this); +} + Error Udp::Socket::Bind(const SockAddr &aSockAddr, otNetifIdentifier aNetifIdentifier) { return Get().Bind(*this, aSockAddr, aNetifIdentifier); @@ -186,6 +191,8 @@ Error Udp::Open(SocketHandle &aSocket, otUdpReceive aHandler, void *aContext) { Error error = kErrorNone; + OT_ASSERT(!IsOpen(aSocket)); + aSocket.GetSockName().Clear(); aSocket.GetPeerName().Clear(); aSocket.mHandler = aHandler; @@ -308,6 +315,8 @@ Error Udp::Close(SocketHandle &aSocket) { Error error = kErrorNone; + VerifyOrExit(IsOpen(aSocket)); + #if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE error = otPlatUdpClose(&aSocket); #endif diff --git a/src/core/net/udp6.hpp b/src/core/net/udp6.hpp index 428500ae8..93b471882 100644 --- a/src/core/net/udp6.hpp +++ b/src/core/net/udp6.hpp @@ -171,6 +171,14 @@ public: */ Error Open(otUdpReceive aHandler, void *aContext); + /** + * This method returns if the UDP socket is open. + * + * @returns If the UDP socket is open. + * + */ + bool IsOpen(void) const; + /** * This method binds the UDP socket. * @@ -446,6 +454,16 @@ public: */ Error Open(SocketHandle &aSocket, otUdpReceive aHandler, void *aContext); + /** + * This method returns if a UDP socket is open. + * + * @param[in] aSocket A reference to the socket. + * + * @returns If the UDP socket is open. + * + */ + bool IsOpen(const SocketHandle &aSocket) const { return mSockets.Contains(aSocket); } + /** * This method binds a UDP socket. *