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_EVENT = 0;
22static cbd PTP_L4_GENERAL = 0;
23static cbd PTP_L2 = 0;
24
25// store current settings
26static PtpTransportType TP = -1;
28
29static void ptp_transmit_cb(uint32_t ts_s, uint32_t ts_ns, uint32_t tag);
30static int ptp_receive_cb(const Pckt *packet, PcktSieveLayerTag tag);
31
32void ptp_nsd_igmp_join_leave(bool join) {
33 // only join IGMP if Transport Type is IP
34 if (TP == PTP_TP_IPv4) {
35 ConnBlock cb = igmp_new_connblock(get_default_interface()); // open IGMP
36
37 void (*igmp_fn)(ConnBlock *, ip4_addr) = join ? igmp_report_membership : igmp_leave_group; // join or leave
38
39 if (DM == PTP_DM_E2E) {
40 igmp_fn(&cb, PTP_IGMP_PRIMARY); // join E2E DM message group
41 } else if (DM == PTP_DM_P2P) {
42 igmp_fn(&cb, PTP_IGMP_PEER_DELAY); // join P2P DM message group
43 }
44 connb_remove(&cb); // close IGMP
45 }
46}
47
48#define CLOSE_CONNECTION_IF_EXISTS(d) if (d >= CBD_LOWEST_DESCRIPTOR) { close_connection(d); d = 0; }
49
51 // leave current IGMP group if applicable
53
54 // first, close all open connection blocks (zero CBDs won't cause trouble)
58
59 // calling either parameter with -1 just closes connections
60 if ((tp == -1) || (dm == -1)) {
61 // message transmission and reception is turned off
62 TP = -1;
63 DM = -1;
64 return;
65 }
66
67 // open only the necessary ones
68 EthInterface *intf = get_default_interface();
69
70 switch (tp) {
71 case PTP_TP_IPv4: {
72 // open event and general connections
73 ip4_addr addr = (dm == PTP_DM_E2E) ? PTP_IGMP_PRIMARY : PTP_IGMP_PEER_DELAY;
74 PTP_L4_EVENT = udp_new_connblock(intf, addr, PTP_PORT_EVENT, ptp_receive_cb);
75 PTP_L4_GENERAL = udp_new_connblock(intf, addr, PTP_PORT_GENERAL, ptp_receive_cb);
76
77 // set transmit callbacks
78 ts_set_tx_callback(PTP_L4_EVENT, ptp_transmit_cb);
79 ts_set_tx_callback(PTP_L4_GENERAL, ptp_transmit_cb);
80 } break;
81 case PTP_TP_802_3:
82 PTP_L2 = cet_new_connblock(intf, ETHERTYPE_PTP, ptp_receive_cb); // open connection
83 ts_set_tx_callback(PTP_L2, ptp_transmit_cb); // set transmit callback
84 break;
85 }
86
87 // store settings
88 TP = tp;
89 DM = dm;
90
91 // join new IGMP group
93}
94
95static int ptp_receive_cb(const Pckt *packet, PcktSieveLayerTag tag) {
96 // put msg into the queue
97 int tp = -1;
98 uint16_t pcktClass = packet->header->props.ownPacketClass;
99 switch (pcktClass) {
100 case ETH_UDP_PACKET_CLASS:
101 tp = PTP_TP_IPv4;
102 break;
103 case 0:
104 tp = PTP_TP_802_3;
105 break;
106 default:
107 break;
108 }
109
110 if (tp != -1) {
111 ptp_receive_enqueue(packet->payload, packet->payloadSize, packet->time_s, packet->time_ns, tp);
112 } else {
113 MSG("Unknown PTP packet class: '%d'!\n", tp);
114 }
115
116 return 0;
117}
118
119static void ptp_transmit_cb(uint32_t ts_s, uint32_t ts_ns, uint32_t tag) {
120 RawPtpMessage *pMsg = (RawPtpMessage *)tag;
121 pMsg->ts.sec = ts_s;
122 pMsg->ts.nanosec = ts_ns;
123 if (pMsg->pTs != NULL) {
124 pMsg->pTs->sec = ts_s;
125 pMsg->pTs->nanosec = ts_ns;
126 }
127 if (pMsg->pTxCb) {
128 pMsg->pTxCb(pMsg);
129 }
130
131 // free buffer
133}
134
136 PtpMessageClass mc = pMsg->tx_mc;
137
138 // narrow down by transport type
139 if (TP == PTP_TP_IPv4) {
140 cbd conn = (mc == PTP_MC_EVENT) ? PTP_L4_EVENT : PTP_L4_GENERAL; // select connection by message type
141 uint16_t port = (mc == PTP_MC_EVENT) ? PTP_PORT_EVENT : PTP_PORT_GENERAL; // select port by message class
142 ip_addr_t ipaddr = (DM == PTP_DM_E2E) ? PTP_IGMP_PRIMARY : PTP_IGMP_PEER_DELAY; // select destination IP-address by delmech.
143 udp_sendto_arg(conn, pMsg->data, pMsg->size, ipaddr, port, (uint32_t)pMsg); // send packet
144 } else if (TP == PTP_TP_802_3) {
145 const uint8_t *ethaddr = (DM == PTP_DM_E2E) ? PTP_ETHERNET_PRIMARY : PTP_ETHERNET_PEER_DELAY; // select destination address by delmech.
146 cet_send_arg(PTP_L2, ethaddr, pMsg->data, pMsg->size, (uint32_t)pMsg); // send frame
147 }
148}
149
150void ptp_nsd_get_interface_address(uint8_t * hwa) {
151 memcpy(hwa, get_default_interface()->mac, ETH_HW_ADDR_LEN);
152}
PtpCircBuf gRawTxMsgBuf
Output circular buffers.
static int ptp_receive_cb(const Pckt *packet, PcktSieveLayerTag tag)
Definition: nsd_etherlib.c:95
void ptp_nsd_transmit_msg(RawPtpMessage *pMsg)
Definition: nsd_etherlib.c:135
#define CLOSE_CONNECTION_IF_EXISTS(d)
Definition: nsd_etherlib.c:48
static PtpDelayMechanism DM
Definition: nsd_etherlib.c:27
void ptp_nsd_igmp_join_leave(bool join)
Definition: nsd_etherlib.c:32
void ptp_nsd_init(PtpTransportType tp, PtpDelayMechanism dm)
Definition: nsd_etherlib.c:50
void ptp_nsd_get_interface_address(uint8_t *hwa)
Definition: nsd_etherlib.c:150
static cbd PTP_L4_GENERAL
Definition: nsd_etherlib.c:22
static cbd PTP_L4_EVENT
Definition: nsd_etherlib.c:21
static cbd PTP_L2
Definition: nsd_etherlib.c:23
static PtpTransportType TP
Definition: nsd_etherlib.c:26
static void ptp_transmit_cb(uint32_t ts_s, uint32_t ts_ns, uint32_t tag)
Definition: nsd_etherlib.c:119
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:30
#define PTP_PORT_EVENT
PTP event message port.
Definition: ptp_defs.h:37
#define PTP_PORT_GENERAL
PTP general message port.
Definition: ptp_defs.h:38
ip4_addr ip_addr_t
Definition: ptp_defs.h:22
const ip_addr_t PTP_IGMP_PEER_DELAY
Peer_Delay IGMP address.
void ptp_circ_buf_free(PtpCircBuf *pCircBuf)
PtpTransportType
PTP transport type enumeration.
Definition: ptp_types.h:128
@ PTP_TP_IPv4
IPv4 Transport Type.
Definition: ptp_types.h:129
@ PTP_TP_802_3
Ethernet Transport Type.
Definition: ptp_types.h:130
PtpMessageClass
Enumeration for different PTP message classes.
Definition: ptp_types.h:152
@ PTP_MC_EVENT
Event Message Class.
Definition: ptp_types.h:153
PtpDelayMechanism
PTP Delay mechanism enumeration.
Definition: ptp_types.h:136
@ PTP_DM_E2E
End-to-End Delay Mechanism.
Definition: ptp_types.h:137
@ PTP_DM_P2P
Peer-to-Peer Delay Mechanism.
Definition: ptp_types.h:138
Raw PTP message structure.
Definition: ptp_types.h:162
TimestampI ts
Timestamp.
Definition: ptp_types.h:163
PtpMessageClass tx_mc
transmit message class
Definition: ptp_types.h:170
void(* pTxCb)(const struct RawPtpMessage_ *pMsg)
transmit callback function
Definition: ptp_types.h:168
uint32_t size
Packet size.
Definition: ptp_types.h:164
TimestampI * pTs
pointer to timestamp
Definition: ptp_types.h:167
uint8_t data[(128)]
raw packet data
Definition: ptp_types.h:173
int32_t nanosec
nanoseconds
Definition: timeutils.h:31
int64_t sec
seconds
Definition: timeutils.h:30
void ptp_receive_enqueue(const void *pPayload, uint32_t len, uint32_t ts_sec, uint32_t ts_ns, int tp)
Definition: task_ptp.c:141