[posix-app] integrate with platform network interface (#3180)

This commit is contained in:
Yakun Xu
2019-01-03 09:13:29 -08:00
committed by Jonathan Hui
parent ae2b01947d
commit 2a9f8797f7
13 changed files with 663 additions and 42 deletions
+34 -20
View File
@@ -37,22 +37,25 @@ die() {
at_exit() {
EXIT_CODE=$?
sudo killall wpantund || true
sudo killall expect || true
killall socat || true
exit $EXIT_CODE
}
build() {
./bootstrap
COVERAGE=1 make -f examples/Makefile-posix
COVERAGE=1 make -f src/posix/Makefile-posix PLATFORM_UDP=1
COVERAGE=1 make -f src/posix/Makefile-posix PLATFORM_NETIF=1 PLATFORM_UDP=1
}
check() {
trap at_exit INT TERM EXIT
SOCAT_OUTPUT=/tmp/ot-socat
socat -d -d pty,raw,b115200,echo=0 pty,raw,b115200,echo=0 > /dev/null 2> $SOCAT_OUTPUT &
OT_OUTPUT=/tmp/ot-output
socat -d -d pty,raw,echo=0 pty,raw,echo=0 > /dev/null 2> $SOCAT_OUTPUT &
while true; do
if test $(head -n2 $SOCAT_OUTPUT | wc -l) = 2; then
RADIO_PTY=$(head -n1 $SOCAT_OUTPUT | grep -o '/dev/.\+')
@@ -67,37 +70,48 @@ check() {
RADIO_NCP_PATH="$(pwd)/$(ls output/*linux*/bin/ot-ncp-radio)"
$RADIO_NCP_PATH 1 > $RADIO_PTY < $RADIO_PTY &
OT_NCP_PATH="$(pwd)/$(ls output/posix/*linux*/bin/ot-ncp)"
PLATFORM_NETIF=wpan0 sudo -E wpantund -I wpan0 -o Thread:Config:FilterRLOCAddresses 0 -s "system:${OT_NCP_PATH} ${CORE_PTY}" &
OT_CLI_PATH="$(pwd)/$(ls output/posix/*linux*/bin/ot-cli)"
sudo expect <<EOF > $OT_OUTPUT &
spawn $OT_CLI_PATH ${OT_NCP_PATH} ${CORE_PTY}
send "panid 0xface\r\n"
expect "Done"
send "ifconfig up\r\n"
expect "Done"
send "thread start\r\n"
expect "Done"
sleep 5
send "state\r\n"
expect "leader"
expect "Done"
send "extaddr\r\n"
expect "Done"
send "ipaddr\r\n"
expect "Done"
wait
EOF
# wait until the node becomes leader
while true; do
sleep 5
if sudo wpanctl status; then
if grep -q leader $OT_OUTPUT; then
break
else
echo 'Still waiting for wpantund'
echo 'Still waiting for leader'
fi
done
sudo wpanctl leave || true
sudo wpanctl form -c 18 OpenThreadTest
mleid=$(sudo wpanctl status | grep MeshLocalAddress | cut -d'"' -f4)
echo "ML-EID is: ${mleid}"
netstat -an | grep -q 61631 || die 'TMF port is not available!'
xaddress=$(sudo wpanctl get 'NCP:ExtendedAddress' | cut -d= -f2 | tr -d ' []')
echo "Extended address is: ${xaddress}"
extaddr=$(awk '/extaddr/{getline; print}' $OT_OUTPUT | tr -d '\r\n')
echo "Extended address is: ${extaddr}"
LEADER_ALOC=fdde:ad00:beef::ff:fe00:fc00
# Retrievie extended address through network diagnostic get
coap_response=$(echo -n '120100' | xxd -r -p | coap-client -m POST coap://[${mleid}]:61631/d/dg -f- | xxd -p -u | grep 0008)
coap_response=$(echo -n '120100' | xxd -r -p | coap-client -m POST coap://[${LEADER_ALOC}]:61631/d/dg -f- | xxd -p | grep 0008)
echo "CoAP response is: ${coap_response}"
# Verify CoAP response contains the extended address
[[ "${coap_response}" = *${xaddress}* ]] || die 'failed to get extended address'
# Leave so that code coverage will be flushed
sudo wpanctl leave || true
[[ "${coap_response}" = *${extaddr}* ]] && echo 'Success' || die 'failed to get extended address'
}
main() {
+29
View File
@@ -861,6 +861,35 @@ AC_SUBST(OPENTHREAD_ENABLE_PLATFORM_UDP)
AM_CONDITIONAL([OPENTHREAD_ENABLE_PLATFORM_UDP], [test "${enable_platform_udp}" = "yes"])
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_PLATFORM_UDP], [${OPENTHREAD_ENABLE_PLATFORM_UDP}], [Define to 1 to enable platform UDP.])
#
# Platform Netif
#
AC_ARG_ENABLE(platform_netif,
[AS_HELP_STRING([--enable-platform-netif],[Enable platform Netif support @<:@default=no@:>@.])],
[
case "${enableval}" in
no|yes)
enable_platform_netif=${enableval}
;;
*)
AC_MSG_ERROR([Invalid value ${enable_platform_netif} for --enable-platform-netif])
;;
esac
],
[enable_platform_netif=no])
if test "$enable_platform_netif" = "yes"; then
OPENTHREAD_ENABLE_PLATFORM_NETIF=1
else
OPENTHREAD_ENABLE_PLATFORM_NETIF=0
fi
AC_MSG_RESULT(${enable_platform_netif})
AC_SUBST(OPENTHREAD_ENABLE_PLATFORM_NETIF)
AM_CONDITIONAL([OPENTHREAD_ENABLE_PLATFORM_NETIF], [test "${enable_platform_netif}" = 'yes'])
AC_DEFINE_UNQUOTED([OPENTHREAD_ENABLE_PLATFORM_NETIF], [${OPENTHREAD_ENABLE_PLATFORM_NETIF}], [Define to 1 to enable platform Netif.])
#
# Thread Commissioner
#
+4
View File
@@ -84,6 +84,10 @@ ifeq ($(DISABLE_EXECUTABLE), 1)
configure_OPTIONS += --enable-executable=no
endif
ifeq ($(PLATFORM_NETIF),1)
configure_OPTIONS += --enable-platform-netif
endif
ifeq (${SNTP_CLIENT}, 1)
configure_OPTIONS += --enable-sntp-client
endif
+3
View File
@@ -85,6 +85,9 @@ int main(int argc, char *argv[])
#if OPENTHREAD_POSIX_APP == OPENTHREAD_POSIX_APP_NCP
otNcpInit(instance);
#elif OPENTHREAD_POSIX_APP == OPENTHREAD_POSIX_APP_CLI
#if OPENTHREAD_ENABLE_PLATFORM_NETIF
otSysInitNetif(instance);
#endif
otCliUartInit(instance);
#endif
+1
View File
@@ -44,6 +44,7 @@ libopenthread_posix_a_SOURCES = \
hdlc_interface.cpp \
logging.c \
misc.c \
netif.cpp \
radio_spinel.cpp \
random.c \
settings.cpp \
+1 -1
View File
@@ -34,7 +34,7 @@
#ifndef POSIX_APP_HDLC_INTERFACE_HPP_
#define POSIX_APP_HDLC_INTERFACE_HPP_
#include "openthread-core-config.h"
#include "platform-posix.h"
#include "hdlc.hpp"
-1
View File
@@ -32,7 +32,6 @@
#include <assert.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <syslog.h>
+519
View File
@@ -0,0 +1,519 @@
/*
* Copyright (c) 2018, 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.
*/
/**
* @file
* This file implements the platform network on Linux.
*/
#include "platform-posix.h"
#include <arpa/inet.h>
#include <assert.h>
#include <fcntl.h>
#include <ifaddrs.h>
#if __linux__
#include <linux/if_tun.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#endif
#include <net/if.h>
#include <net/if_arp.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <openthread/instance.h>
#include <openthread/ip6.h>
#include <openthread/message.h>
#include "common/code_utils.hpp"
#include "common/logging.hpp"
#include "net/ip6_address.hpp"
#if OPENTHREAD_ENABLE_PLATFORM_NETIF
#ifndef OPENTHREAD_POSIX_TUN_DEVICE
#define OPENTHREAD_POSIX_TUN_DEVICE "/dev/net/tun"
#endif // OPENTHREAD_TUN_DEVICE
// from linux/ipv6.h
struct in6_ifreq
{
struct in6_addr ifr6_addr;
__u32 ifr6_prefixlen;
int ifr6_ifindex;
};
static otInstance * sInstance = NULL;
static int sTunFd = -1; ///< Used to exchange IPv6 packets.
static int sIpFd = -1; ///< Used to manage IPv6 stack on Thread interface.
static int sNetlinkFd = -1; ///< Used to receive netlink events.
static unsigned int sTunIndex = 0;
static char sTunName[IFNAMSIZ];
static const size_t kMaxIp6Size = 1536;
static const uint8_t kMulticastPrefixLength = 128;
static void UpdateUnicast(otInstance *aInstance, const otIp6Address &aAddress, uint8_t aPrefixLength, bool aIsAdded)
{
struct in6_ifreq ifr6;
otError error = OT_ERROR_NONE;
assert(sInstance == aInstance);
VerifyOrExit(sIpFd > 0, error = OT_ERROR_INVALID_STATE);
memcpy(&ifr6.ifr6_addr, &aAddress, sizeof(ifr6.ifr6_addr));
ifr6.ifr6_ifindex = sTunIndex;
ifr6.ifr6_prefixlen = aPrefixLength;
VerifyOrExit(ioctl(sIpFd, (aIsAdded ? SIOCSIFADDR : SIOCDIFADDR), &ifr6) == 0, perror("ioctl");
error = OT_ERROR_FAILED);
exit:
if (error == OT_ERROR_NONE)
{
otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
}
else
{
otLogCritPlat("%s: %s", __func__, otThreadErrorToString(error));
exit(OT_EXIT_FAILURE);
}
}
static void UpdateMulticast(otInstance *aInstance, const otIp6Address &aAddress, bool aIsAdded)
{
struct ipv6_mreq mreq;
otError error = OT_ERROR_NONE;
assert(sInstance == aInstance);
VerifyOrExit(sIpFd > 0);
memcpy(&mreq.ipv6mr_multiaddr, &aAddress, sizeof(mreq.ipv6mr_multiaddr));
mreq.ipv6mr_interface = sTunIndex;
VerifyOrExit(
setsockopt(sIpFd, IPPROTO_IPV6, (aIsAdded ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP), &mreq, sizeof(mreq)) == 0,
perror("setsockopt");
error = OT_ERROR_FAILED);
exit:
if (error == OT_ERROR_NONE)
{
otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
}
else
{
otLogCritPlat("%s: %s", __func__, otThreadErrorToString(error));
exit(OT_EXIT_FAILURE);
}
}
static void UpdateLink(otInstance *aInstance)
{
otError error = OT_ERROR_NONE;
struct ifreq ifr;
assert(sInstance == aInstance);
VerifyOrExit(sIpFd > 0);
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, sTunName, sizeof(ifr.ifr_name));
VerifyOrExit(ioctl(sIpFd, SIOCGIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
if (otIp6IsEnabled(aInstance))
{
ifr.ifr_flags |= IFF_UP;
}
else
{
ifr.ifr_flags &= ~IFF_UP;
}
VerifyOrExit(ioctl(sIpFd, SIOCSIFFLAGS, &ifr) == 0, perror("ioctl"); error = OT_ERROR_FAILED);
exit:
if (error == OT_ERROR_NONE)
{
otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
}
else
{
otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
}
}
static void processAddressChange(const otIp6Address *aAddress, uint8_t aPrefixLength, bool aIsAdded, void *aContext)
{
if (aAddress->mFields.m8[0] == 0xff)
{
UpdateMulticast(static_cast<otInstance *>(aContext), *aAddress, aIsAdded);
}
else
{
UpdateUnicast(static_cast<otInstance *>(aContext), *aAddress, aPrefixLength, aIsAdded);
}
}
static void processStateChange(otChangedFlags aFlags, void *aContext)
{
if (OT_CHANGED_THREAD_NETIF_STATE | aFlags)
{
UpdateLink(static_cast<otInstance *>(aContext));
}
}
static void processReceive(otMessage *aMessage, void *aContext)
{
char packet[kMaxIp6Size];
otError error = OT_ERROR_NONE;
uint16_t length = otMessageGetLength(aMessage);
assert(sInstance == aContext);
VerifyOrExit(sTunFd > 0);
VerifyOrExit(otMessageRead(aMessage, 0, packet, sizeof(packet)) == length, error = OT_ERROR_NO_BUFS);
VerifyOrExit(write(sTunFd, packet, length) == length, perror("write"); error = OT_ERROR_FAILED);
exit:
otMessageFree(aMessage);
if (error == OT_ERROR_NONE)
{
otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
}
else
{
otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
}
}
static void processTransmit(otInstance *aInstance)
{
otMessage *message = NULL;
ssize_t rval;
char packet[kMaxIp6Size];
otError error = OT_ERROR_NONE;
assert(sInstance == aInstance);
rval = read(sTunFd, packet, sizeof(packet));
VerifyOrExit(rval > 0, error = OT_ERROR_FAILED);
message = otIp6NewMessage(aInstance, NULL);
VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS);
SuccessOrExit(error = otMessageAppend(message, packet, rval));
error = otIp6Send(aInstance, message);
message = NULL;
exit:
if (message != NULL)
{
otMessageFree(message);
}
if (error == OT_ERROR_NONE)
{
otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
}
else
{
otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
}
}
static void processNetifAddrEvent(otInstance *aInstance, struct nlmsghdr *aNetlinkMessage)
{
struct ifaddrmsg *ifaddr = reinterpret_cast<struct ifaddrmsg *>(NLMSG_DATA(aNetlinkMessage));
size_t rtaLength;
otError error = OT_ERROR_NONE;
VerifyOrExit(ifaddr->ifa_index == static_cast<unsigned int>(sTunIndex) && ifaddr->ifa_family == AF_INET6);
rtaLength = IFA_PAYLOAD(aNetlinkMessage);
for (struct rtattr *rta = reinterpret_cast<struct rtattr *>(IFA_RTA(ifaddr)); RTA_OK(rta, rtaLength);
rta = RTA_NEXT(rta, rtaLength))
{
switch (rta->rta_type)
{
case IFA_ADDRESS:
case IFA_LOCAL:
case IFA_BROADCAST:
case IFA_ANYCAST:
{
ot::Ip6::Address addr;
memcpy(&addr, RTA_DATA(rta), sizeof(addr));
if (aNetlinkMessage->nlmsg_type == RTM_NEWADDR)
{
if (!addr.IsMulticast())
{
otNetifAddress netAddr;
netAddr.mAddress = addr;
netAddr.mPrefixLength = ifaddr->ifa_prefixlen;
SuccessOrExit(error = otIp6AddUnicastAddress(aInstance, &netAddr));
}
else
{
SuccessOrExit(error = otIp6SubscribeMulticastAddress(aInstance, &addr));
}
}
else if (aNetlinkMessage->nlmsg_type == RTM_DELADDR)
{
if (!addr.IsMulticast())
{
otIp6RemoveUnicastAddress(aInstance, &addr);
}
else
{
otIp6UnsubscribeMulticastAddress(aInstance, &addr);
}
}
else
{
continue;
}
break;
}
default:
break;
}
}
exit:
if (error == OT_ERROR_NONE)
{
otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
}
else
{
otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
}
}
static void processNetifLinkEvent(otInstance *aInstance, struct nlmsghdr *aNetlinkMessage)
{
struct ifinfomsg *ifinfo = reinterpret_cast<struct ifinfomsg *>(NLMSG_DATA(aNetlinkMessage));
otError error = OT_ERROR_NONE;
VerifyOrExit(ifinfo->ifi_index == static_cast<int>(sTunIndex));
SuccessOrExit(error = otIp6SetEnabled(aInstance, ifinfo->ifi_flags & IFF_UP));
exit:
if (error == OT_ERROR_NONE)
{
otLogInfoPlat("%s: %s", __func__, otThreadErrorToString(error));
}
else
{
otLogWarnPlat("%s: %s", __func__, otThreadErrorToString(error));
}
}
static void processNetifEvent(otInstance *aInstance)
{
const size_t kMaxNetifEvent = 8192;
ssize_t length;
char buffer[kMaxNetifEvent];
length = recv(sNetlinkFd, buffer, sizeof(buffer), 0);
VerifyOrExit(length > 0);
for (struct nlmsghdr *msg = reinterpret_cast<struct nlmsghdr *>(buffer); NLMSG_OK(msg, length);
msg = NLMSG_NEXT(msg, length))
{
switch (msg->nlmsg_type)
{
case RTM_NEWADDR:
case RTM_DELADDR:
processNetifAddrEvent(aInstance, msg);
break;
case RTM_NEWLINK:
case RTM_DELLINK:
processNetifLinkEvent(aInstance, msg);
break;
default:
break;
}
}
exit:
return;
}
void platformNetifInit(otInstance *aInstance)
{
struct ifreq ifr;
sIpFd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);
VerifyOrExit(sIpFd > 0);
sNetlinkFd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
VerifyOrExit(sNetlinkFd > 0);
{
struct sockaddr_nl sa;
memset(&sa, 0, sizeof(sa));
sa.nl_family = AF_NETLINK;
sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV6_IFADDR;
VerifyOrExit(bind(sNetlinkFd, reinterpret_cast<struct sockaddr *>(&sa), sizeof(sa)) == 0);
}
sTunFd = open(OPENTHREAD_POSIX_TUN_DEVICE, O_RDWR);
VerifyOrExit(sTunFd > 0, otLogCritPlat("Unable to open tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
strncpy(ifr.ifr_name, "wpan%d", IFNAMSIZ);
VerifyOrExit(ioctl(sTunFd, TUNSETIFF, static_cast<void *>(&ifr)) == 0,
otLogCritPlat("Unable to configure tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));
#if defined(ARPHRD_6LOWPAN)
VerifyOrExit(ioctl(sTunFd, TUNSETLINK, ARPHRD_6LOWPAN) == 0,
otLogCritPlat("Unable to set link type of tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));
#else
VerifyOrExit(ioctl(sTunFd, TUNSETLINK, ARPHRD_ETHER) == 0,
otLogCritPlat("Unable to set link type of tun device %s", OPENTHREAD_POSIX_TUN_DEVICE));
#endif
sTunIndex = if_nametoindex(ifr.ifr_name);
VerifyOrExit(sTunIndex > 0);
strncpy(sTunName, ifr.ifr_name, sizeof(sTunName));
#if OPENTHREAD_ENABLE_PLATFORM_UDP
platformUdpInit(sTunName);
#endif
otIp6SetReceiveCallback(aInstance, processReceive, aInstance);
otIp6SetAddressCallback(aInstance, processAddressChange, aInstance);
otSetStateChangedCallback(aInstance, processStateChange, aInstance);
sInstance = aInstance;
exit:
if (sTunIndex == 0)
{
if (sTunFd != -1)
{
close(sTunFd);
sTunFd = -1;
}
if (sIpFd != -1)
{
close(sIpFd);
sIpFd = -1;
}
if (sNetlinkFd != -1)
{
close(sNetlinkFd);
sNetlinkFd = -1;
}
exit(OT_EXIT_FAILURE);
}
}
void platformNetifUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd)
{
OT_UNUSED_VARIABLE(aWriteFdSet);
VerifyOrExit(sTunIndex > 0);
assert(sTunFd > 0);
assert(sNetlinkFd > 0);
assert(sIpFd > 0);
FD_SET(sTunFd, aReadFdSet);
FD_SET(sTunFd, aErrorFdSet);
FD_SET(sNetlinkFd, aReadFdSet);
FD_SET(sNetlinkFd, aErrorFdSet);
if (sTunFd > *aMaxFd)
{
*aMaxFd = sTunFd;
}
if (sNetlinkFd > *aMaxFd)
{
*aMaxFd = sNetlinkFd;
}
exit:
return;
}
void platformNetifProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet)
{
OT_UNUSED_VARIABLE(aWriteFdSet);
VerifyOrExit(sTunIndex > 0);
if (FD_ISSET(sTunFd, aErrorFdSet))
{
close(sTunFd);
exit(OT_EXIT_FAILURE);
}
if (FD_ISSET(sNetlinkFd, aErrorFdSet))
{
close(sNetlinkFd);
exit(OT_EXIT_FAILURE);
}
if (FD_ISSET(sTunFd, aReadFdSet))
{
processTransmit(sInstance);
}
if (FD_ISSET(sNetlinkFd, aReadFdSet))
{
processNetifEvent(sInstance);
}
exit:
return;
}
#endif // OPENTHREAD_ENABLE_PLATFORM_NETIF
@@ -42,14 +42,4 @@
*/
#define OPENTHREAD_CONFIG_PLATFORM_INFO "POSIX-APP"
/**
* @def OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
*
* Define as 1 to enable PTY device support in POSIX app.
*
*/
#ifndef OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
#define OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE 1
#endif
#endif // OPENTHREAD_CORE_POSIX_CONFIG_H_
+8
View File
@@ -55,6 +55,14 @@ extern "C" {
*/
otInstance *otSysInit(int argc, char *argv[]);
/**
* This function performs platform network interface initialization.
*
* @param[in] aInstance A pointer to the OpenThread instance.
*
*/
void otSysInitNetif(otInstance *aInstance);
/**
* This function performs all platform-specific deinitialization for OpenThread's drivers.
*
+41 -5
View File
@@ -35,15 +35,20 @@
#ifndef PLATFORM_POSIX_H_
#define PLATFORM_POSIX_H_
#include <openthread-core-config.h>
#include <openthread/config.h>
#include <sys/select.h>
#include <sys/time.h>
#include <openthread/instance.h>
#include "openthread-core-config.h"
/**
* @def OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
*
* Define as 1 to enable PTY device support in POSIX app.
*
*/
#ifndef OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE
#define OPENTHREAD_CONFIG_POSIX_APP_ENABLE_PTY_DEVICE 1
#endif
#ifdef __cplusplus
extern "C" {
@@ -231,6 +236,35 @@ void platformUartUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aE
*/
void platformUartProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet);
/**
* This function initializes platform netif.
*
* @param[in] aInstance A pointer to the OpenThread instance.
*
*/
void platformNetifInit(otInstance *aInstance);
/**
* This function updates the file descriptor sets with file descriptors used by platform netif module.
*
* @param[inout] aReadFdSet A pointer to the read file descriptors.
* @param[inout] aWriteFdSet A pointer to the write file descriptors.
* @param[inout] aErrorFdSet A pointer to the error file descriptors.
* @param[inout] aMaxFd A pointer to the max file descriptor.
*
*/
void platformNetifUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, fd_set *aErrorFdSet, int *aMaxFd);
/**
* This function performs platform netif processing.
*
* @param[in] aReadFdSet A pointer to the read file descriptors.
* @param[in] aWriteFdSet A pointer to the write file descriptors.
* @param[in] aErrorFdSet A pointer to the error file descriptors.
*
*/
void platformNetifProcess(const fd_set *aReadFdSet, const fd_set *aWriteFdSet, const fd_set *aErrorFdSet);
/**
* This function restores the Uart.
*
@@ -337,8 +371,10 @@ void otSimRadioSpinelProcess(otInstance *aInstance, const struct Event *aEvent);
/**
* This function initializes platform UDP driver.
*
* @param[in] aIfName The name of Thread's platform network interface.
*
*/
void platformUdpInit(void);
void platformUdpInit(const char *aIfName);
/**
* This function performs platform UDP driver processing.
+16 -2
View File
@@ -44,6 +44,7 @@
#include <stdlib.h>
#include <string.h>
#include <openthread-core-config.h>
#include <openthread/tasklet.h>
#include <openthread/platform/alarm-milli.h>
#include <openthread/platform/radio.h>
@@ -144,8 +145,8 @@ otInstance *otSysInit(int aArgCount, char *aArgVector[])
platformAlarmInit(speedUpFactor);
platformRadioInit(radioFile, radioConfig);
platformRandomInit();
#if OPENTHREAD_ENABLE_PLATFORM_UDP
platformUdpInit();
#if OPENTHREAD_ENABLE_PLATFORM_UDP && OPENTHREAD_ENABLE_PLATFORM_NETIF == 0
platformUdpInit(getenv("PLATFORM_NETIF"));
#endif
instance = otInstanceInitSingle();
@@ -164,6 +165,13 @@ otInstance *otSysInit(int aArgCount, char *aArgVector[])
return instance;
}
#if OPENTHREAD_ENABLE_PLATFORM_NETIF
void otSysInitNetif(otInstance *aInstance)
{
platformNetifInit(aInstance);
}
#endif
void otSysDeinit(void)
{
#if OPENTHREAD_POSIX_VIRTUAL_TIME
@@ -223,6 +231,9 @@ void otSysProcessDrivers(otInstance *aInstance)
#if OPENTHREAD_ENABLE_PLATFORM_UDP
platformUdpUpdateFdSet(aInstance, &readFdSet, &maxFd);
#endif
#if OPENTHREAD_ENABLE_PLATFORM_NETIF
platformNetifUpdateFdSet(&readFdSet, &writeFdSet, &errorFdSet, &maxFd);
#endif
#if OPENTHREAD_POSIX_VIRTUAL_TIME
otSimUpdateFdSet(&readFdSet, &writeFdSet, &errorFdSet, &maxFd, &timeout);
#else
@@ -284,6 +295,9 @@ void otSysProcessDrivers(otInstance *aInstance)
#endif
platformUartProcess(&readFdSet, &writeFdSet, &errorFdSet);
platformAlarmProcess(aInstance);
#if OPENTHREAD_ENABLE_PLATFORM_NETIF
platformNetifProcess(&readFdSet, &writeFdSet, &errorFdSet);
#endif
#if OPENTHREAD_ENABLE_PLATFORM_UDP
platformUdpProcess(aInstance, &readFdSet);
#endif
+7 -3
View File
@@ -379,10 +379,14 @@ exit:
return;
}
void platformUdpInit(void)
void platformUdpInit(const char *aIfName)
{
const char *platformNetif = getenv("PLATFORM_NETIF");
sPlatNetifIndex = if_nametoindex(platformNetif);
if (aIfName == NULL)
{
exit(OT_EXIT_INVALID_ARGUMENTS);
}
sPlatNetifIndex = if_nametoindex(aIfName);
if (sPlatNetifIndex == 0)
{