mirror of
https://github.com/espressif/openthread.git
synced 2026-08-03 09:27:47 +00:00
[posix] make platform udp as mainloop source (#6663)
This commit is contained in:
@@ -146,6 +146,7 @@ extern int
|
||||
#include "common/code_utils.hpp"
|
||||
#include "common/logging.hpp"
|
||||
#include "net/ip6_address.hpp"
|
||||
#include "posix/platform/udp.hpp"
|
||||
|
||||
unsigned int gNetifIndex = 0;
|
||||
char gNetifName[IFNAMSIZ];
|
||||
@@ -1475,7 +1476,7 @@ void platformNetifInit(otInstance *aInstance, const char *aInterfaceName)
|
||||
VerifyOrDie(gNetifIndex > 0, OT_EXIT_FAILURE);
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
platformUdpInit(gNetifName);
|
||||
ot::Posix::Udp::Get().Init(aInstance, gNetifName);
|
||||
#endif
|
||||
#if OPENTHREAD_POSIX_USE_MLD_MONITOR
|
||||
mldListenerInit();
|
||||
|
||||
@@ -359,32 +359,6 @@ void virtualTimeSendSleepEvent(const struct timeval *aTimeout);
|
||||
*/
|
||||
void virtualTimeRadioSpinelProcess(otInstance *aInstance, const struct VirtualTimeEvent *aEvent);
|
||||
|
||||
/**
|
||||
* This function initializes platform UDP driver.
|
||||
*
|
||||
* @param[in] aIfName The name of Thread's platform network interface.
|
||||
*
|
||||
*/
|
||||
void platformUdpInit(const char *aIfName);
|
||||
|
||||
/**
|
||||
* This function performs platform UDP driver processing.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[in] aReadFdSet A pointer to the read file descriptors.
|
||||
*
|
||||
*/
|
||||
void platformUdpProcess(otInstance *aInstance, const fd_set *aReadSet);
|
||||
|
||||
/**
|
||||
* This function updates the file descriptor sets with file descriptors used by the platform UDP driver.
|
||||
*
|
||||
* @param[in] aInstance The OpenThread instance structure.
|
||||
* @param[inout] aReadFdSet A pointer to the read file descriptors.
|
||||
* @param[inout] aMaxFd A pointer to the max file descriptor.
|
||||
*/
|
||||
void platformUdpUpdateFdSet(otInstance *aInstance, fd_set *aReadFdSet, int *aMaxFd);
|
||||
|
||||
enum SocketBlockOption
|
||||
{
|
||||
kSocketBlock,
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "posix/platform/infra_if.hpp"
|
||||
#include "posix/platform/mainloop.hpp"
|
||||
#include "posix/platform/radio_url.hpp"
|
||||
#include "posix/platform/udp.hpp"
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE || OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
static void processStateChange(otChangedFlags aFlags, void *aContext)
|
||||
@@ -139,7 +140,7 @@ otInstance *otSysInit(otPlatformConfig *aPlatformConfig)
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
|
||||
platformNetifInit(instance, aPlatformConfig->mInterfaceName);
|
||||
#elif OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
platformUdpInit(aPlatformConfig->mInterfaceName);
|
||||
ot::Posix::Udp::Init(instance, aPlatformConfig->mInterfaceName);
|
||||
#else
|
||||
gNetifName[0] = '\0';
|
||||
#endif
|
||||
@@ -163,6 +164,9 @@ void otSysDeinit(void)
|
||||
virtualTimeDeinit();
|
||||
#endif
|
||||
platformRadioDeinit();
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
ot::Posix::Udp::Get().Deinit();
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
|
||||
platformNetifDeinit();
|
||||
#endif
|
||||
@@ -213,9 +217,6 @@ void otSysMainloopUpdate(otInstance *aInstance, otSysMainloopContext *aMainloop)
|
||||
ot::Posix::Mainloop::Manager::Get().Update(*aMainloop);
|
||||
|
||||
platformAlarmUpdateTimeout(&aMainloop->mTimeout);
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
platformUdpUpdateFdSet(aInstance, &aMainloop->mReadFdSet, &aMainloop->mMaxFd);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
|
||||
platformNetifUpdateFdSet(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet,
|
||||
&aMainloop->mMaxFd);
|
||||
@@ -296,9 +297,6 @@ void otSysMainloopProcess(otInstance *aInstance, const otSysMainloopContext *aMa
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_NETIF_ENABLE
|
||||
platformNetifProcess(&aMainloop->mReadFdSet, &aMainloop->mWriteFdSet, &aMainloop->mErrorFdSet);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
platformUdpProcess(aInstance, &aMainloop->mReadFdSet);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_OTNS_ENABLE
|
||||
|
||||
+48
-21
@@ -56,32 +56,36 @@
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
|
||||
#include "posix/platform/ip6_utils.hpp"
|
||||
#include "posix/platform/mainloop.hpp"
|
||||
#include "posix/platform/udp.hpp"
|
||||
|
||||
using namespace ot::Posix::Ip6Utils;
|
||||
|
||||
static const size_t kMaxUdpSize = 1280;
|
||||
namespace {
|
||||
|
||||
static void *FdToHandle(int aFd)
|
||||
constexpr size_t kMaxUdpSize = 1280;
|
||||
|
||||
void *FdToHandle(int aFd)
|
||||
{
|
||||
return reinterpret_cast<void *>(aFd);
|
||||
}
|
||||
|
||||
static int FdFromHandle(void *aHandle)
|
||||
int FdFromHandle(void *aHandle)
|
||||
{
|
||||
return static_cast<int>(reinterpret_cast<long>(aHandle));
|
||||
}
|
||||
|
||||
static bool IsLinkLocal(const struct in6_addr &aAddress)
|
||||
bool IsLinkLocal(const struct in6_addr &aAddress)
|
||||
{
|
||||
return aAddress.s6_addr[0] == 0xfe && aAddress.s6_addr[1] == 0x80;
|
||||
}
|
||||
|
||||
static bool IsMulticast(const otIp6Address &aAddress)
|
||||
bool IsMulticast(const otIp6Address &aAddress)
|
||||
{
|
||||
return aAddress.mFields.m8[0] == 0xff;
|
||||
}
|
||||
|
||||
static otError transmitPacket(int aFd, uint8_t *aPayload, uint16_t aLength, const otMessageInfo &aMessageInfo)
|
||||
otError transmitPacket(int aFd, uint8_t *aPayload, uint16_t aLength, const otMessageInfo &aMessageInfo)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
// use fixed value for CMSG_SPACE is not a constant expression on macOS
|
||||
@@ -122,18 +126,16 @@ static otError transmitPacket(int aFd, uint8_t *aPayload, uint16_t aLength, cons
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
|
||||
{
|
||||
int hopLimit = (aMessageInfo.mHopLimit ? aMessageInfo.mHopLimit : OPENTHREAD_CONFIG_IP6_HOP_LIMIT_DEFAULT);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_level = IPPROTO_IPV6;
|
||||
cmsg->cmsg_type = IPV6_HOPLIMIT;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
|
||||
memcpy(CMSG_DATA(cmsg), &hopLimit, sizeof(int));
|
||||
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg);
|
||||
controlLength += CMSG_SPACE(sizeof(int));
|
||||
}
|
||||
|
||||
@@ -142,6 +144,7 @@ static otError transmitPacket(int aFd, uint8_t *aPayload, uint16_t aLength, cons
|
||||
{
|
||||
struct in6_pktinfo pktinfo;
|
||||
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg);
|
||||
cmsg->cmsg_level = IPPROTO_IPV6;
|
||||
cmsg->cmsg_type = IPV6_PKTINFO;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(pktinfo));
|
||||
@@ -152,7 +155,6 @@ static otError transmitPacket(int aFd, uint8_t *aPayload, uint16_t aLength, cons
|
||||
memcpy(CMSG_DATA(cmsg), &pktinfo, sizeof(pktinfo));
|
||||
|
||||
controlLength += CMSG_SPACE(sizeof(pktinfo));
|
||||
cmsg = CMSG_NXTHDR(&msg, cmsg);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -175,7 +177,7 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
static otError receivePacket(int aFd, uint8_t *aPayload, uint16_t &aLength, otMessageInfo &aMessageInfo)
|
||||
otError receivePacket(int aFd, uint8_t *aPayload, uint16_t &aLength, otMessageInfo &aMessageInfo)
|
||||
{
|
||||
struct sockaddr_in6 peerAddr;
|
||||
uint8_t control[kMaxUdpSize];
|
||||
@@ -228,6 +230,8 @@ exit:
|
||||
return rval > 0 ? OT_ERROR_NONE : OT_ERROR_FAILED;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
otError otPlatUdpSocket(otUdpSocket *aUdpSocket)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -539,11 +543,14 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void platformUdpUpdateFdSet(otInstance *aInstance, fd_set *aReadFdSet, int *aMaxFd)
|
||||
namespace ot {
|
||||
namespace Posix {
|
||||
|
||||
void Udp::Update(otSysMainloopContext &aContext)
|
||||
{
|
||||
VerifyOrExit(gNetifIndex != 0);
|
||||
|
||||
for (otUdpSocket *socket = otUdpGetSockets(aInstance); socket != nullptr; socket = socket->mNext)
|
||||
for (otUdpSocket *socket = otUdpGetSockets(mInstance); socket != nullptr; socket = socket->mNext)
|
||||
{
|
||||
int fd;
|
||||
|
||||
@@ -553,11 +560,11 @@ void platformUdpUpdateFdSet(otInstance *aInstance, fd_set *aReadFdSet, int *aMax
|
||||
}
|
||||
|
||||
fd = FdFromHandle(socket->mHandle);
|
||||
FD_SET(fd, aReadFdSet);
|
||||
FD_SET(fd, &aContext.mReadFdSet);
|
||||
|
||||
if (aMaxFd != nullptr && *aMaxFd < fd)
|
||||
if (aContext.mMaxFd < fd)
|
||||
{
|
||||
*aMaxFd = fd;
|
||||
aContext.mMaxFd = fd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,7 +572,7 @@ exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void platformUdpInit(const char *aIfName)
|
||||
void Udp::Init(otInstance *aInstance, const char *aIfName)
|
||||
{
|
||||
if (aIfName == nullptr)
|
||||
{
|
||||
@@ -582,17 +589,35 @@ void platformUdpInit(const char *aIfName)
|
||||
}
|
||||
|
||||
assert(gNetifIndex != 0);
|
||||
|
||||
mInstance = aInstance;
|
||||
Mainloop::Manager::Get().Add(*this);
|
||||
}
|
||||
|
||||
void platformUdpProcess(otInstance *aInstance, const fd_set *aReadFdSet)
|
||||
void Udp::Deinit(void)
|
||||
{
|
||||
// TODO All platform sockets should be closed
|
||||
|
||||
mInstance = nullptr;
|
||||
Mainloop::Manager::Get().Remove(*this);
|
||||
}
|
||||
|
||||
Udp &Udp::Get(void)
|
||||
{
|
||||
static Udp sInstance;
|
||||
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
void Udp::Process(const otSysMainloopContext &aContext)
|
||||
{
|
||||
otMessageSettings msgSettings = {false, OT_MESSAGE_PRIORITY_NORMAL};
|
||||
|
||||
for (otUdpSocket *socket = otUdpGetSockets(aInstance); socket != nullptr; socket = socket->mNext)
|
||||
for (otUdpSocket *socket = otUdpGetSockets(mInstance); socket != nullptr; socket = socket->mNext)
|
||||
{
|
||||
int fd = FdFromHandle(socket->mHandle);
|
||||
|
||||
if (fd > 0 && FD_ISSET(fd, aReadFdSet))
|
||||
if (fd > 0 && FD_ISSET(fd, &aContext.mReadFdSet))
|
||||
{
|
||||
otMessageInfo messageInfo;
|
||||
otMessage * message = nullptr;
|
||||
@@ -607,7 +632,7 @@ void platformUdpProcess(otInstance *aInstance, const fd_set *aReadFdSet)
|
||||
continue;
|
||||
}
|
||||
|
||||
message = otUdpNewMessage(aInstance, &msgSettings);
|
||||
message = otUdpNewMessage(mInstance, &msgSettings);
|
||||
|
||||
if (message == nullptr)
|
||||
{
|
||||
@@ -630,4 +655,6 @@ void platformUdpProcess(otInstance *aInstance, const fd_set *aReadFdSet)
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace Posix
|
||||
} // namespace ot
|
||||
#endif // #if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2021, The OpenThread Authors.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef OT_POSIX_PLATFORM_UDP_HPP_
|
||||
#define OT_POSIX_PLATFORM_UDP_HPP_
|
||||
|
||||
#include "core/common/non_copyable.hpp"
|
||||
#include "posix/platform/mainloop.hpp"
|
||||
|
||||
namespace ot {
|
||||
namespace Posix {
|
||||
|
||||
class Udp : public Mainloop::Source, private NonCopyable
|
||||
{
|
||||
public:
|
||||
static Udp &Get(void);
|
||||
|
||||
void Init(otInstance *aInstance, const char *aIfName);
|
||||
void Deinit(void);
|
||||
void Update(otSysMainloopContext &aContext) override;
|
||||
void Process(const otSysMainloopContext &aContext) override;
|
||||
|
||||
private:
|
||||
otInstance *mInstance = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Posix
|
||||
} // namespace ot
|
||||
|
||||
#endif // OT_POSIX_PLATFORM_UDP_HPP_
|
||||
Reference in New Issue
Block a user