Skip to content

Commit

Permalink
[simulation] Adding simulation tests framework for tcat.
Browse files Browse the repository at this point in the history
This commit adds simulation framework for tcat based on posix udp
sockets.
  • Loading branch information
Przemyslaw Bida committed Mar 15, 2024
1 parent 9d6321b commit 6b02c0d
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 8 deletions.
162 changes: 154 additions & 8 deletions examples/platforms/simulation/ble.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,50 +26,196 @@
* POSSIBILITY OF SUCH DAMAGE.
*/

#include "platform-simulation.h"

#include <errno.h>

#include <stdio.h>
#include <stdlib.h>
#include <openthread/platform/ble.h>

#include "openthread/error.h"
#include "utils/code_utils.h"

#define PLAT_BLE_MSG_DATA_MAX 512
static uint8_t sBleBuffer[PLAT_BLE_MSG_DATA_MAX];

static int sFd = -1;

static const uint16_t kPortBase = 10000;
static uint16_t sPort = 0;
struct sockaddr_in sSockaddr;

static void initFds(void)
{
int fd;
int one = 1;
struct sockaddr_in sockaddr;

memset(&sockaddr, 0, sizeof(sockaddr));

sPort = (uint16_t)(kPortBase + gNodeId);
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons(sPort);
sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

otEXPECT_ACTION((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) != -1, perror("socket(sFd)"));

otEXPECT_ACTION(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != -1,
perror("setsockopt(sFd, SO_REUSEADDR)"));
otEXPECT_ACTION(setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) != -1,
perror("setsockopt(sFd, SO_REUSEPORT)"));

otEXPECT_ACTION(bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != -1, perror("bind(sFd)"));

// Fd is successfully initialized.
sFd = fd;

exit:
if (sFd == -1)
{
exit(EXIT_FAILURE);
}
}

static void deinitFds(void)
{
if (sFd != -1)
{
close(sFd);
sFd = -1;
}
}

otError otPlatBleEnable(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return OT_ERROR_NOT_IMPLEMENTED;
initFds();
return OT_ERROR_NONE;
}

otError otPlatBleDisable(otInstance *aInstance)
{
deinitFds();
OT_UNUSED_VARIABLE(aInstance);
return OT_ERROR_NOT_IMPLEMENTED;
return OT_ERROR_NONE;
}

otError otPlatBleGapAdvStart(otInstance *aInstance, uint16_t aInterval)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aInterval);
return OT_ERROR_NOT_IMPLEMENTED;
return OT_ERROR_NONE;
}

otError otPlatBleGapAdvStop(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return OT_ERROR_NOT_IMPLEMENTED;
return OT_ERROR_NONE;
}

otError otPlatBleGapDisconnect(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
return OT_ERROR_NOT_IMPLEMENTED;
return OT_ERROR_NONE;
}

otError otPlatBleGattMtuGet(otInstance *aInstance, uint16_t *aMtu)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aMtu);
return OT_ERROR_NOT_IMPLEMENTED;
*aMtu = PLAT_BLE_MSG_DATA_MAX - 1;
return OT_ERROR_NONE;
}

otError otPlatBleGattServerIndicate(otInstance *aInstance, uint16_t aHandle, const otBleRadioPacket *aPacket)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aHandle);

ssize_t rval;
otError error = OT_ERROR_NONE;

otEXPECT_ACTION(sFd != -1, error = OT_ERROR_INVALID_STATE);

rval = sendto(sFd, (const char *)aPacket->mValue, 1 + aPacket->mLength, 0, (struct sockaddr *)&sSockaddr,
sizeof(sSockaddr));

if (rval)
{
perror("BLE simulation sendto failed.");
}

exit:
return error;
}

void platformBleDeinit(void) { deinitFds(); }

void platformBleUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, struct timeval *aTimeout, int *aMaxFd)
{
OT_UNUSED_VARIABLE(aTimeout);
OT_UNUSED_VARIABLE(aWriteFdSet);

if (aReadFdSet != NULL && sFd != -1)
{
FD_SET(sFd, aReadFdSet);

if (aMaxFd != NULL && *aMaxFd < sFd)
{
*aMaxFd = sFd;
}
}
}

void platformBleProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet)
{
OT_UNUSED_VARIABLE(aReadFdSet);
OT_UNUSED_VARIABLE(aWriteFdSet);

otEXPECT(sFd != -1);

if (FD_ISSET(sFd, aReadFdSet))
{
socklen_t len = sizeof(sSockaddr);
ssize_t rval;

memset(&sSockaddr, 0, sizeof(sSockaddr));
rval = recvfrom(sFd, sBleBuffer, sizeof(sBleBuffer), 0, (struct sockaddr *)&sSockaddr, &len);

if (rval > 0)
{
otBleRadioPacket myPacket;
myPacket.mValue = sBleBuffer;
myPacket.mLength = (uint16_t)rval;
myPacket.mPower = 0;
otPlatBleGattServerOnWriteRequest(
aInstance, 0,
&myPacket); // TODO consider passing otPlatBleGattServerOnWriteRequest as a callback function
}
else if (rval == 0)
{
// socket is closed, which should not happen
assert(false);
}
else if (errno != EINTR && errno != EAGAIN)
{
perror("recvfrom BLE simulation failed");
exit(EXIT_FAILURE);
}
}
exit:
return;
}

OT_TOOL_WEAK void otPlatBleGattServerOnWriteRequest(otInstance *aInstance,
uint16_t aHandle,
const otBleRadioPacket *aPacket)
{
OT_UNUSED_VARIABLE(aInstance);
OT_UNUSED_VARIABLE(aHandle);
OT_UNUSED_VARIABLE(aPacket);
return OT_ERROR_NOT_IMPLEMENTED;

/* In case of rcp there is a problem with linking to otPlatBleGattServerOnWriteRequest
* which is available in FTD/MTD library.
*/
}
27 changes: 27 additions & 0 deletions examples/platforms/simulation/platform-simulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,31 @@ void platformInfraIfProcess(otInstance *aInstance, const fd_set *aReadFdSet, con

#endif // OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE

/**
* Shuts down the BLE service used by OpenThread.
*
*/
void platformBleDeinit(void);

/**
* Updates the file descriptor sets with file descriptors used by the radio driver.
*
* @param[in,out] aReadFdSet A pointer to the read file descriptors.
* @param[in,out] aWriteFdSet A pointer to the write file descriptors.
* @param[in,out] aTimeout A pointer to the timeout.
* @param[in,out] aMaxFd A pointer to the max file descriptor.
*
*/
void platformBleUpdateFdSet(fd_set *aReadFdSet, fd_set *aWriteFdSet, struct timeval *aTimeout, int *aMaxFd);

/**
* Performs BLE driver processing.
*
* @param[in] aInstance The OpenThread instance structure.
* @param[in] aReadFdSet A pointer to the read file descriptors.
* @param[in] aWriteFdSet A pointer to the write file descriptors.
*
*/
void platformBleProcess(otInstance *aInstance, const fd_set *aReadFdSet, const fd_set *aWriteFdSet);

#endif // PLATFORM_SIMULATION_H_
8 changes: 8 additions & 0 deletions examples/platforms/simulation/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ void otSysProcessDrivers(otInstance *aInstance)
platformInfraIfUpdateFdSet(&read_fds, &write_fds, &max_fd);
#endif

#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
platformBleUpdateFdSet(&read_fds, &write_fds, &timeout, &max_fd);
#endif

if (otTaskletsArePending(aInstance))
{
timeout.tv_sec = 0;
Expand Down Expand Up @@ -323,6 +327,10 @@ void otSysProcessDrivers(otInstance *aInstance)
platformInfraIfProcess(aInstance, &read_fds, &write_fds);
#endif

#if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
platformBleProcess(aInstance, &read_fds, &write_fds);
#endif

if (gTerminate)
{
exit(0);
Expand Down
1 change: 1 addition & 0 deletions script/cmake-build
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ OT_POSIX_SIM_COMMON_OPTIONS=(
"-DOT_SRP_CLIENT=ON"
"-DOT_SRP_SERVER=ON"
"-DOT_UPTIME=ON"
"-DOT_BLE_TCAT=ON"
)
readonly OT_POSIX_SIM_COMMON_OPTIONS

Expand Down
40 changes: 40 additions & 0 deletions tests/scripts/expect/cli-tcat.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/expect -f
#
# Copyright (c) 2022, 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.
#

source "tests/scripts/expect/_common.exp"

spawn_node 1 "cli"


switch_node 1
send "tcat start \n"
expect_line "Done"

send "tcat stop \n"
expect_line "Done"

0 comments on commit 6b02c0d

Please sign in to comment.