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 | /*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <logging/log.h>
LOG_MODULE_REGISTER(net_gptp_sample, LOG_LEVEL_DBG);
#include <zephyr.h>
#include <errno.h>
#include <net/net_core.h>
#include <net/net_l2.h>
#include <net/net_if.h>
#include <net/ethernet.h>
#include <net/gptp.h>
static struct gptp_phase_dis_cb phase_dis;
#if defined(CONFIG_NET_GPTP_VLAN)
/* User data for the interface callback */
struct ud {
struct net_if *first;
struct net_if *second;
struct net_if *third;
};
static void iface_cb(struct net_if *iface, void *user_data)
{
struct ud *ud = user_data;
if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
return;
}
if (!ud->first) {
ud->first = iface;
return;
}
if (!ud->second) {
ud->second = iface;
return;
}
if (!ud->third) {
ud->third = iface;
return;
}
}
static int setup_iface(struct net_if *iface, const char *ipv6_addr,
const char *ipv4_addr, u16_t vlan_tag)
{
struct net_if_addr *ifaddr;
struct in_addr addr4;
struct in6_addr addr6;
int ret;
ret = net_eth_vlan_enable(iface, vlan_tag);
if (ret < 0) {
LOG_ERR("Cannot enable VLAN for tag %d (%d)", vlan_tag, ret);
}
if (net_addr_pton(AF_INET6, ipv6_addr, &addr6)) {
LOG_ERR("Invalid address: %s", ipv6_addr);
return -EINVAL;
}
ifaddr = net_if_ipv6_addr_add(iface, &addr6, NET_ADDR_MANUAL, 0);
if (!ifaddr) {
LOG_ERR("Cannot add %s to interface %p", ipv6_addr, iface);
return -EINVAL;
}
if (net_addr_pton(AF_INET, ipv4_addr, &addr4)) {
LOG_ERR("Invalid address: %s", ipv6_addr);
return -EINVAL;
}
ifaddr = net_if_ipv4_addr_add(iface, &addr4, NET_ADDR_MANUAL, 0);
if (!ifaddr) {
LOG_ERR("Cannot add %s to interface %p", ipv4_addr, iface);
return -EINVAL;
}
LOG_DBG("Interface %p VLAN tag %d setup done.", iface, vlan_tag);
return 0;
}
static int init_vlan(void)
{
struct ud ud;
int ret;
(void)memset(&ud, 0, sizeof(ud));
net_if_foreach(iface_cb, &ud);
/* This sample has two VLANs. For the second one we need to manually
* create IP address for this test. But first the VLAN needs to be
* added to the interface so that IPv6 DAD can work properly.
*/
ret = setup_iface(ud.second,
CONFIG_NET_SAMPLE_IFACE2_MY_IPV6_ADDR,
CONFIG_NET_SAMPLE_IFACE2_MY_IPV4_ADDR,
CONFIG_NET_SAMPLE_IFACE2_VLAN_TAG);
if (ret < 0) {
return ret;
}
ret = setup_iface(ud.third,
CONFIG_NET_SAMPLE_IFACE3_MY_IPV6_ADDR,
CONFIG_NET_SAMPLE_IFACE3_MY_IPV4_ADDR,
CONFIG_NET_SAMPLE_IFACE3_VLAN_TAG);
if (ret < 0) {
return ret;
}
return 0;
}
#endif /* CONFIG_NET_GPTP_VLAN */
static void gptp_phase_dis_cb(u8_t *gm_identity,
u16_t *time_base,
struct gptp_scaled_ns *last_gm_ph_change,
double *last_gm_freq_change)
{
char output[sizeof("xx:xx:xx:xx:xx:xx:xx:xx")];
static u8_t id[8];
if (memcmp(id, gm_identity, sizeof(id))) {
memcpy(id, gm_identity, sizeof(id));
LOG_DBG("GM %s last phase %d.%lld",
log_strdup(gptp_sprint_clock_id(gm_identity, output,
sizeof(output))),
last_gm_ph_change->high,
last_gm_ph_change->low);
}
}
static int init_app(void)
{
#if defined(CONFIG_NET_GPTP_VLAN)
if (init_vlan() < 0) {
LOG_ERR("Cannot setup VLAN");
}
#endif
gptp_register_phase_dis_cb(&phase_dis, gptp_phase_dis_cb);
return 0;
}
void main(void)
{
init_app();
}
|