Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | /* main.c - Application main entry point */
/*
* Copyright (c) 2020 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <linker/sections.h>
#include <ztest.h>
#include <random/rand32.h>
#include <net/ethernet.h>
#include <net/dummy.h>
#include <net/net_if.h>
#include <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_control(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_rand32_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;
}
int fake_dev_init(const struct device *dev)
{
ARG_UNUSED(dev);
return 0;
}
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)
NET_DEVICE_INIT(fake_dev, "fake_dev",
fake_dev_init, fake_dev_pm_control,
&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");
}
void test_pm(void)
{
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);
inet_pton(AF_INET, "192.168.0.1", &addr4.sin_addr);
sock = 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 = 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_state_set(dev, PM_DEVICE_STATE_SUSPENDED);
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_state_set(dev, PM_DEVICE_STATE_SUSPENDED);
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 = sendto(sock, data, ARRAY_SIZE(data), 0,
(struct sockaddr *)&addr4, sizeof(struct sockaddr_in));
zassert_true(ret < 0, "Could send data");
ret = pm_device_state_set(dev, PM_DEVICE_STATE_ACTIVE);
zassert_true(ret == 0, "Could not set state");
zassert_false(net_if_is_suspended(iface), "net iface is suspended");
ret = pm_device_state_set(dev, PM_DEVICE_STATE_ACTIVE);
zassert_true(ret == -EALREADY, "Could change state");
/* Let's send some data, it should go through */
ret = sendto(sock, data, ARRAY_SIZE(data), 0,
(struct sockaddr *)&addr4, sizeof(struct sockaddr_in));
zassert_true(ret > 0, "Could not send data");
close(sock);
}
void test_main(void)
{
ztest_test_suite(test_net_pm,
ztest_unit_test(test_setup),
ztest_unit_test(test_pm));
ztest_run_test_suite(test_net_pm);
}
|