flexPTP 1.0
An IEEE 1588 PTP implementation designed for microcontrollers
Loading...
Searching...
No Matches
nsd_etherlib.c
Go to the documentation of this file.
1#include "../../network_stack_driver.h"
2
3#include "../../ptp_defs.h"
4#include "../../ptp_types.h"
5#include "../../task_ptp.h"
6
7#include "etherlib/cbd_table.h"
8#include "etherlib/connection_block.h"
9#include "etherlib/eth_interface.h"
10#include "etherlib/global_state.h"
11#include "etherlib/prefab/conn_blocks/custom_ethertype_connblock.h"
12#include "etherlib/prefab/conn_blocks/igmp_connblock.h"
13#include "etherlib/prefab/packet_parsers/ethernet_frame.h"
14#include "etherlib/prefab/packet_parsers/ipv4_types.h"
15#include "etherlib/timestamping.h"
16
17#include <stdbool.h>
18#include <string.h>
19
20// initialize connection blocks to invalid states
21static cbd PTP_L4_PRIMARY_EVENT = 0;
23static cbd PTP_L4_PDELAY_EVENT = 0;
24static cbd PTP_L4_PDELAY_GENERAL = 0;
25static cbd PTP_L2 = 0;
26
27// store current settings
28static PtpTransportType TP = -1;
31static uint8_t custom_p2p_8023_primary_dest[6] = {};
33static uint8_t custom_p2p_8023_pdel_dest[6] = {};
34
35static const uint8_t zero_mac[6] = {};
36
37static void ptp_transmit_cb(uint32_t ts_s, uint32_t ts_ns, uint32_t tag);
38static int ptp_receive_cb(const Pckt *packet, PcktSieveLayerTag tag);
39
40void ptp_nsd_igmp_join_leave(bool join) {
41 // only join IGMP if Transport Type is IP
42 if (TP == PTP_TP_IPv4) {
43 ConnBlock cb = igmp_new_connblock(get_default_interface()); // open IGMP
44
45 void (*igmp_fn)(ConnBlock *, ip4_addr) = join ? igmp_report_membership : igmp_leave_group; // join or leave
46
47 igmp_fn(&cb, PTP_IGMP_PRIMARY); // join/leave PRIMARY messaging group group
48
49 if (DM == PTP_DM_P2P) { // with P2P delay mechanism...
50 igmp_fn(&cb, PTP_IGMP_PEER_DELAY); // join PDELAY* message group
51 }
52
53 connb_remove(&cb); // close IGMP
54 }
55}
56
57#define CLOSE_CONNECTION_IF_EXISTS(d) \
58 if (d >= CBD_LOWEST_DESCRIPTOR) { \
59 close_connection(d); \
60 d = 0; \
61 }
62
63void ptp_nsd_init(const NsdInitSettings *init) {
64 // leave current IGMP group if applicable
66
67 // first, close all open connection blocks (zero CBDs won't cause trouble)
73
74 // calling either parameter with -1 just closes connections
75 if ((init->tp == -1) || (init->dm == -1)) {
76 // message transmission and reception is turned off
77 TP = -1;
78 DM = -1;
79 return;
80 }
81
82 // open only the necessary ones
83 EthInterface *intf = get_default_interface();
84
85 switch (init->tp) {
86 case PTP_TP_IPv4: {
87 // open event and general PRIMARY connections
90
91 // set transmit callbacks
92 ts_set_tx_callback(PTP_L4_PRIMARY_EVENT, ptp_transmit_cb);
93 ts_set_tx_callback(PTP_L4_PRIMARY_GENERAL, ptp_transmit_cb);
94
95 // open event and general PDELAY* connections
96 if (init->dm == PTP_DM_P2P) {
99
100 // set transmit callbacks
101 ts_set_tx_callback(PTP_L4_PDELAY_EVENT, ptp_transmit_cb);
102 ts_set_tx_callback(PTP_L4_PDELAY_GENERAL, ptp_transmit_cb);
103 }
104
105 } break;
106 case PTP_TP_802_3:
107 PTP_L2 = cet_new_connblock(intf, ETHERTYPE_PTP, ptp_receive_cb); // open connection
108 ts_set_tx_callback(PTP_L2, ptp_transmit_cb); // set transmit callback
109 break;
110 }
111
112 // if custom P2P 802.3 destination are given, store them
113 uint8_t mac_size = sizeof(zero_mac);
114 if (memcmp(init->primary_p2p_8023_dest, zero_mac, mac_size)) {
115 memcpy(custom_p2p_8023_primary_dest, &init->primary_p2p_8023_dest, mac_size);
117 }
118 if (memcmp(init->pdelay_p2p_8023_dest, zero_mac, mac_size)) {
119 memcpy(custom_p2p_8023_pdel_dest, &init->pdelay_p2p_8023_dest, mac_size);
121 }
122
123 // store settings
124 TP = init->tp;
125 DM = init->dm;
126
127 // join new IGMP group
129}
130
131static int ptp_receive_cb(const Pckt *packet, PcktSieveLayerTag tag) {
132 // put msg into the queue
133 int tp = -1;
134 uint16_t pcktClass = packet->header->props.ownPacketClass;
135 switch (pcktClass) {
136 case ETH_UDP_PACKET_CLASS:
137 tp = PTP_TP_IPv4;
138 break;
139 case 0:
140 tp = PTP_TP_802_3;
141 break;
142 default:
143 break;
144 }
145
146 if (tp != -1) {
147 ptp_receive_enqueue(packet->payload, packet->payloadSize, packet->time_s, packet->time_ns, tp);
148 } else {
149 MSG("Unknown PTP packet class: '%d'!\n", tp);
150 }
151
152 return 0;
153}
154
155static void ptp_transmit_cb(uint32_t ts_s, uint32_t ts_ns, uint32_t tag) {
156 ptp_transmit_timestamp_cb(tag, ts_s, ts_ns);
157}
158
159void ptp_nsd_transmit_msg(RawPtpMessage *pMsg, uint32_t uid) {
160 PtpMessageClass mc = pMsg->tx_mc;
161 PtpMessageType mt = pMsg->tx_mt;
162
163 // is it a Peer Delay Mechanism related message?
164 bool isPDel_ = (mt == PTP_MT_PDelay_Req) || (mt == PTP_MT_PDelay_Resp) || (mt == PTP_MT_PDelay_Resp_Follow_Up);
165
166 // narrow down by transport type
167 if (TP == PTP_TP_IPv4) {
168 cbd conn = (mc == PTP_MC_EVENT) ? PTP_L4_PRIMARY_EVENT : PTP_L4_PRIMARY_GENERAL; // select connection by message type
169 uint16_t port = (mc == PTP_MC_EVENT) ? PTP_PORT_EVENT : PTP_PORT_GENERAL; // select port by message class
170 ip_addr_t ipaddr = isPDel_ ? PTP_IGMP_PEER_DELAY : PTP_IGMP_PRIMARY; // select destination IP-address by PDel*/primary message types
171 udp_sendto_arg(conn, pMsg->data, pMsg->size, ipaddr, port, uid); // send packet
172 } else if (TP == PTP_TP_802_3) {
173 const uint8_t *ethaddr = isPDel_ ? (custom_p2p_8023_pdel_dest_valid ? custom_p2p_8023_pdel_dest : PTP_ETHERNET_PEER_DELAY) : (custom_p2p_8023_primary_dest_valid ? custom_p2p_8023_primary_dest : PTP_ETHERNET_PRIMARY); // select destination address by PDel*/primary message types
174 cet_send_arg(PTP_L2, ethaddr, pMsg->data, pMsg->size, uid); // send frame
175 }
176}
177
179 memcpy(hwa, get_default_interface()->mac, ETH_HW_ADDR_LEN);
180}
static int ptp_receive_cb(const Pckt *packet, PcktSieveLayerTag tag)
Definition: nsd_etherlib.c:131
static cbd PTP_L4_PDELAY_GENERAL
Definition: nsd_etherlib.c:24
void ptp_nsd_transmit_msg(RawPtpMessage *pMsg, uint32_t uid)
Definition: nsd_etherlib.c:159
static cbd PTP_L4_PRIMARY_EVENT
Definition: nsd_etherlib.c:21
void ptp_nsd_init(const NsdInitSettings *init)
Definition: nsd_etherlib.c:63
#define CLOSE_CONNECTION_IF_EXISTS(d)
Definition: nsd_etherlib.c:57
static PtpDelayMechanism DM
Definition: nsd_etherlib.c:29
static cbd PTP_L4_PDELAY_EVENT
Definition: nsd_etherlib.c:23
void ptp_nsd_igmp_join_leave(bool join)
Definition: nsd_etherlib.c:40
static bool custom_p2p_8023_primary_dest_valid
Definition: nsd_etherlib.c:30
void ptp_nsd_get_interface_address(uint8_t *hwa)
Definition: nsd_etherlib.c:178
static uint8_t custom_p2p_8023_primary_dest[6]
Definition: nsd_etherlib.c:31
static bool custom_p2p_8023_pdel_dest_valid
Definition: nsd_etherlib.c:32
static cbd PTP_L2
Definition: nsd_etherlib.c:25
static cbd PTP_L4_PRIMARY_GENERAL
Definition: nsd_etherlib.c:22
static PtpTransportType TP
Definition: nsd_etherlib.c:28
static void ptp_transmit_cb(uint32_t ts_s, uint32_t ts_ns, uint32_t tag)
Definition: nsd_etherlib.c:155
static const uint8_t zero_mac[6]
Definition: nsd_etherlib.c:35
static uint8_t custom_p2p_8023_pdel_dest[6]
Definition: nsd_etherlib.c:33
const uint8_t PTP_ETHERNET_PEER_DELAY[6]
PTP's L2 Peer_Delay Ethernet address.
Definition: ptp_defs.c:4
const uint8_t PTP_ETHERNET_PRIMARY[6]
PTP's L2 Primary Ethernet address.
Definition: ptp_defs.c:3
const ip_addr_t PTP_IGMP_PRIMARY
Primary IGMP address.
#define ETHERTYPE_PTP
(for lwIP conformity)
Definition: ptp_defs.h:38
#define PTP_PORT_EVENT
PTP event message port.
Definition: ptp_defs.h:45
#define PTP_PORT_GENERAL
PTP general message port.
Definition: ptp_defs.h:46
ip4_addr ip_addr_t
Definition: ptp_defs.h:30
const ip_addr_t PTP_IGMP_PEER_DELAY
Peer_Delay IGMP address.
PtpTransportType
PTP transport type enumeration.
Definition: ptp_types.h:136
@ PTP_TP_IPv4
IPv4 Transport Type.
Definition: ptp_types.h:137
@ PTP_TP_802_3
Ethernet Transport Type.
Definition: ptp_types.h:138
PtpMessageClass
Enumeration for different PTP message classes.
Definition: ptp_types.h:160
@ PTP_MC_EVENT
Event Message Class.
Definition: ptp_types.h:161
PtpMessageType
PTP packet type enumeration.
Definition: ptp_types.h:37
@ PTP_MT_PDelay_Resp
Peer Delay Response.
Definition: ptp_types.h:41
@ PTP_MT_PDelay_Req
Peer Delay Request.
Definition: ptp_types.h:40
@ PTP_MT_PDelay_Resp_Follow_Up
Peer Delay Response Follow Up.
Definition: ptp_types.h:44
PtpDelayMechanism
PTP Delay mechanism enumeration.
Definition: ptp_types.h:144
@ PTP_DM_P2P
Peer-to-Peer Delay Mechanism.
Definition: ptp_types.h:146
Network Stack Driver initialization object.
uint8_t primary_p2p_8023_dest[6]
Destination address for primary P2P messages over Ethernet.
uint8_t pdelay_p2p_8023_dest[6]
Destination address for PDel* P2P messages over Ethernet.
PtpDelayMechanism dm
Delay Mechanism.
PtpTransportType tp
Transport Type.
PtpMessageClass tx_mc
transmit message class
Definition: ptp_types.h:195
PtpMessageType tx_mt
transmit message type
Definition: ptp_types.h:196
uint32_t size
Packet size.
Definition: ptp_types.h:188
uint8_t data[(128)]
raw packet data
Definition: ptp_types.h:199
void ptp_receive_enqueue(const void *pPayload, uint32_t len, uint32_t ts_sec, uint32_t ts_ns, int tp)
Definition: task_ptp.c:474
void ptp_transmit_timestamp_cb(uint32_t uid, uint32_t seconds, uint32_t nanoseconds)
Definition: task_ptp.c:604