use the appropriate sys_randX_get() instead of always sys_rand32_get(). Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
181 lines
4.6 KiB
C
181 lines
4.6 KiB
C
/* main.c - Application main entry point */
|
|
|
|
/*
|
|
* Copyright (c) 2020 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/linker/sections.h>
|
|
#include <zephyr/pm/device.h>
|
|
#include <zephyr/ztest.h>
|
|
#include <zephyr/random/random.h>
|
|
|
|
#include <zephyr/net/ethernet.h>
|
|
#include <zephyr/net/dummy.h>
|
|
#include <zephyr/net/net_if.h>
|
|
#include <zephyr/net/socket.h>
|
|
|
|
struct fake_dev_context {
|
|
uint8_t mac_addr[sizeof(struct net_eth_addr)];
|
|
struct net_if *iface;
|
|
};
|
|
|
|
static int fake_dev_pm_action(const struct device *dev,
|
|
enum pm_device_action action)
|
|
{
|
|
struct fake_dev_context *ctx = dev->data;
|
|
int ret;
|
|
|
|
switch (action) {
|
|
case PM_DEVICE_ACTION_SUSPEND:
|
|
ret = net_if_suspend(ctx->iface);
|
|
if (ret == -EBUSY) {
|
|
goto out;
|
|
}
|
|
break;
|
|
case PM_DEVICE_ACTION_RESUME:
|
|
ret = net_if_resume(ctx->iface);
|
|
break;
|
|
default:
|
|
ret = -ENOTSUP;
|
|
break;
|
|
}
|
|
|
|
out:
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
static int fake_dev_send(const struct device *dev, struct net_pkt *pkt)
|
|
{
|
|
ARG_UNUSED(dev);
|
|
ARG_UNUSED(pkt);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static uint8_t *fake_dev_get_mac(struct fake_dev_context *ctx)
|
|
{
|
|
if (ctx->mac_addr[2] == 0x00) {
|
|
/* 00-00-5E-00-53-xx Documentation RFC 7042 */
|
|
ctx->mac_addr[0] = 0x00;
|
|
ctx->mac_addr[1] = 0x00;
|
|
ctx->mac_addr[2] = 0x5E;
|
|
ctx->mac_addr[3] = 0x00;
|
|
ctx->mac_addr[4] = 0x53;
|
|
ctx->mac_addr[5] = sys_rand8_get();
|
|
}
|
|
|
|
return ctx->mac_addr;
|
|
}
|
|
|
|
static void fake_dev_iface_init(struct net_if *iface)
|
|
{
|
|
const struct device *dev = net_if_get_device(iface);
|
|
struct fake_dev_context *ctx = dev->data;
|
|
uint8_t *mac = fake_dev_get_mac(ctx);
|
|
|
|
net_if_set_link_addr(iface, mac, 6, NET_LINK_ETHERNET);
|
|
|
|
ctx->iface = iface;
|
|
}
|
|
|
|
struct fake_dev_context fake_dev_context_data;
|
|
|
|
static struct dummy_api fake_dev_if_api = {
|
|
.iface_api.init = fake_dev_iface_init,
|
|
.send = fake_dev_send,
|
|
};
|
|
|
|
#define _ETH_L2_LAYER DUMMY_L2
|
|
#define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
|
|
|
|
PM_DEVICE_DEFINE(fake_dev, fake_dev_pm_action);
|
|
|
|
NET_DEVICE_INIT(fake_dev, "fake_dev",
|
|
NULL, PM_DEVICE_GET(fake_dev),
|
|
&fake_dev_context_data, NULL,
|
|
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
|
|
&fake_dev_if_api, _ETH_L2_LAYER, _ETH_L2_CTX_TYPE, 127);
|
|
|
|
void *test_setup(void)
|
|
{
|
|
struct net_if *iface;
|
|
struct in_addr in4addr_my = { { { 192, 168, 0, 2 } } };
|
|
struct net_if_addr *ifaddr;
|
|
|
|
iface = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
|
|
|
|
net_if_up(iface);
|
|
|
|
ifaddr = net_if_ipv4_addr_add(iface, &in4addr_my, NET_ADDR_MANUAL, 0);
|
|
zassert_not_null(ifaddr, "Could not add iface address");
|
|
return NULL;
|
|
}
|
|
|
|
ZTEST(test_net_pm_test_suite, test_pm)
|
|
{
|
|
struct net_if *iface =
|
|
net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
|
|
const struct device *dev = net_if_get_device(iface);
|
|
char data[] = "some data";
|
|
struct sockaddr_in addr4;
|
|
int sock;
|
|
int ret;
|
|
|
|
addr4.sin_family = AF_INET;
|
|
addr4.sin_port = htons(12345);
|
|
zsock_inet_pton(AF_INET, "192.168.0.1", &addr4.sin_addr);
|
|
|
|
sock = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
zassert_true(sock >= 0, "Could not open socket");
|
|
|
|
zassert_false(net_if_is_suspended(iface), "net iface is not suspended");
|
|
|
|
/* Let's send some data, it should go through */
|
|
ret = zsock_sendto(sock, data, ARRAY_SIZE(data), 0,
|
|
(struct sockaddr *)&addr4, sizeof(struct sockaddr_in));
|
|
zassert_true(ret > 0, "Could not send data");
|
|
|
|
/* Let's make sure net stack's thread gets ran, or setting PM state
|
|
* might return -EBUSY instead
|
|
*/
|
|
k_yield();
|
|
|
|
ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND);
|
|
zassert_true(ret == 0, "Could not set state");
|
|
|
|
zassert_true(net_if_is_suspended(iface), "net iface is not suspended");
|
|
|
|
/* Let's try to suspend it again, it should fail relevantly */
|
|
ret = pm_device_action_run(dev, PM_DEVICE_ACTION_SUSPEND);
|
|
zassert_true(ret == -EALREADY, "Could change state");
|
|
|
|
zassert_true(net_if_is_suspended(iface), "net iface is not suspended");
|
|
|
|
/* Let's send some data, it should fail relevantly */
|
|
ret = zsock_sendto(sock, data, ARRAY_SIZE(data), 0,
|
|
(struct sockaddr *)&addr4, sizeof(struct sockaddr_in));
|
|
zassert_true(ret < 0, "Could send data");
|
|
|
|
ret = pm_device_action_run(dev, PM_DEVICE_ACTION_RESUME);
|
|
zassert_true(ret == 0, "Could not set state");
|
|
|
|
zassert_false(net_if_is_suspended(iface), "net iface is suspended");
|
|
|
|
ret = pm_device_action_run(dev, PM_DEVICE_ACTION_RESUME);
|
|
zassert_true(ret == -EALREADY, "Could change state");
|
|
|
|
/* Let's send some data, it should go through */
|
|
ret = zsock_sendto(sock, data, ARRAY_SIZE(data), 0,
|
|
(struct sockaddr *)&addr4, sizeof(struct sockaddr_in));
|
|
zassert_true(ret > 0, "Could not send data");
|
|
|
|
zsock_close(sock);
|
|
}
|
|
|
|
ZTEST_SUITE(test_net_pm_test_suite, NULL, test_setup, NULL, NULL, NULL);
|