[posix] make platform udp as mainloop source (#6663)

This commit is contained in:
Yakun Xu
2021-06-07 21:36:46 -07:00
committed by GitHub
parent 87e6cf5991
commit 1fceb4c490
5 changed files with 109 additions and 55 deletions
+2 -1
View File
@@ -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();
-26
View File
@@ -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,
+5 -7
View File
@@ -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
View File
@@ -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
+54
View File
@@ -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_