Make the transport layer more opaque.
Although the UDP/IPv4 layer does not need any state per instance (other than the two file descriptors), the raw Ethernet layer will need this. Signed-off-by: Richard Cochran <richardcochran@gmail.com>master
parent
7421e74aca
commit
29463cd306
25
port.c
25
port.c
|
@ -40,7 +40,7 @@
|
||||||
struct port {
|
struct port {
|
||||||
char *name;
|
char *name;
|
||||||
struct clock *clock;
|
struct clock *clock;
|
||||||
struct transport *transport;
|
struct transport *trp;
|
||||||
enum timestamp_type timestamping;
|
enum timestamp_type timestamping;
|
||||||
struct fdarray fda;
|
struct fdarray fda;
|
||||||
struct foreign_clock *best;
|
struct foreign_clock *best;
|
||||||
|
@ -351,7 +351,7 @@ static int port_delay_request(struct port *p)
|
||||||
if (msg_pre_send(msg))
|
if (msg_pre_send(msg))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
cnt = p->transport->send(&p->fda, 1, msg, pdulen, &msg->hwts);
|
cnt = transport_send(p->trp, &p->fda, 1, msg, pdulen, &msg->hwts);
|
||||||
if (cnt <= 0) {
|
if (cnt <= 0) {
|
||||||
pr_err("port %hu: send delay request failed", portnum(p));
|
pr_err("port %hu: send delay request failed", portnum(p));
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -420,7 +420,7 @@ static int port_tx_announce(struct port *p)
|
||||||
err = -1;
|
err = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
cnt = p->transport->send(&p->fda, 0, msg, pdulen, &msg->hwts);
|
cnt = transport_send(p->trp, &p->fda, 0, msg, pdulen, &msg->hwts);
|
||||||
if (cnt <= 0) {
|
if (cnt <= 0) {
|
||||||
pr_err("port %hu: send announce failed", portnum(p));
|
pr_err("port %hu: send announce failed", portnum(p));
|
||||||
err = -1;
|
err = -1;
|
||||||
|
@ -464,7 +464,7 @@ static int port_tx_sync(struct port *p)
|
||||||
err = -1;
|
err = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
cnt = p->transport->send(&p->fda, 1, msg, pdulen, &msg->hwts);
|
cnt = transport_send(p->trp, &p->fda, 1, msg, pdulen, &msg->hwts);
|
||||||
if (cnt <= 0) {
|
if (cnt <= 0) {
|
||||||
pr_err("port %hu: send sync failed", portnum(p));
|
pr_err("port %hu: send sync failed", portnum(p));
|
||||||
err = -1;
|
err = -1;
|
||||||
|
@ -497,7 +497,7 @@ static int port_tx_sync(struct port *p)
|
||||||
err = -1;
|
err = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
cnt = p->transport->send(&p->fda, 0, fup, pdulen, &fup->hwts);
|
cnt = transport_send(p->trp, &p->fda, 0, fup, pdulen, &fup->hwts);
|
||||||
if (cnt <= 0) {
|
if (cnt <= 0) {
|
||||||
pr_err("port %hu: send follow up failed", portnum(p));
|
pr_err("port %hu: send follow up failed", portnum(p));
|
||||||
err = -1;
|
err = -1;
|
||||||
|
@ -531,7 +531,7 @@ static int port_initialize(struct port *p)
|
||||||
goto no_timers;
|
goto no_timers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (p->transport->open(p->name, &p->fda, p->timestamping))
|
if (transport_open(p->trp, p->name, &p->fda, p->timestamping))
|
||||||
goto no_tropen;
|
goto no_tropen;
|
||||||
|
|
||||||
for (i = 0; i < N_TIMER_FDS; i++) {
|
for (i = 0; i < N_TIMER_FDS; i++) {
|
||||||
|
@ -546,7 +546,7 @@ static int port_initialize(struct port *p)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
no_tmo:
|
no_tmo:
|
||||||
p->transport->close(&p->fda);
|
transport_close(p->trp, &p->fda);
|
||||||
no_tropen:
|
no_tropen:
|
||||||
no_timers:
|
no_timers:
|
||||||
for (i = 0; i < N_TIMER_FDS; i++) {
|
for (i = 0; i < N_TIMER_FDS; i++) {
|
||||||
|
@ -646,7 +646,7 @@ static int process_delay_req(struct port *p, struct ptp_message *m)
|
||||||
err = -1;
|
err = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
cnt = p->transport->send(&p->fda, 0, msg, pdulen, NULL);
|
cnt = transport_send(p->trp, &p->fda, 0, msg, pdulen, NULL);
|
||||||
if (cnt <= 0) {
|
if (cnt <= 0) {
|
||||||
pr_err("port %hu: send delay response failed", portnum(p));
|
pr_err("port %hu: send delay response failed", portnum(p));
|
||||||
err = -1;
|
err = -1;
|
||||||
|
@ -782,7 +782,8 @@ static void process_sync(struct port *p, struct ptp_message *m)
|
||||||
void port_close(struct port *p)
|
void port_close(struct port *p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
p->transport->close(&p->fda);
|
transport_close(p->trp, &p->fda);
|
||||||
|
transport_destroy(p->trp);
|
||||||
for (i = 0; i < N_TIMER_FDS; i++) {
|
for (i = 0; i < N_TIMER_FDS; i++) {
|
||||||
close(p->fda.fd[FD_ANNOUNCE_TIMER + i]);
|
close(p->fda.fd[FD_ANNOUNCE_TIMER + i]);
|
||||||
}
|
}
|
||||||
|
@ -915,7 +916,7 @@ enum fsm_event port_event(struct port *p, int fd_index)
|
||||||
|
|
||||||
msg->hwts.type = p->timestamping;
|
msg->hwts.type = p->timestamping;
|
||||||
|
|
||||||
cnt = p->transport->recv(fd, msg, sizeof(*msg), &msg->hwts);
|
cnt = transport_recv(p->trp, fd, msg, sizeof(*msg), &msg->hwts);
|
||||||
if (cnt <= 0) {
|
if (cnt <= 0) {
|
||||||
pr_err("port %hu: recv message failed", portnum(p));
|
pr_err("port %hu: recv message failed", portnum(p));
|
||||||
msg_put(msg);
|
msg_put(msg);
|
||||||
|
@ -979,8 +980,8 @@ struct port *port_open(struct port_defaults *pod,
|
||||||
p->pod = *pod;
|
p->pod = *pod;
|
||||||
p->name = name;
|
p->name = name;
|
||||||
p->clock = clock;
|
p->clock = clock;
|
||||||
p->transport = transport_find(transport);
|
p->trp = transport_create(transport);
|
||||||
if (!p->transport) {
|
if (!p->trp) {
|
||||||
free(p);
|
free(p);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
38
transport.c
38
transport.c
|
@ -18,20 +18,37 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
|
#include "transport_private.h"
|
||||||
#include "udp.h"
|
#include "udp.h"
|
||||||
|
|
||||||
static struct transport udp = {
|
int transport_close(struct transport *t, struct fdarray *fda)
|
||||||
.close = udp_close,
|
{
|
||||||
.open = udp_open,
|
return t->close(t, fda);
|
||||||
.recv = udp_recv,
|
}
|
||||||
.send = udp_send,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct transport *transport_find(enum transport_type type)
|
int transport_open(struct transport *t, char *name,
|
||||||
|
struct fdarray *fda, enum timestamp_type tt)
|
||||||
|
{
|
||||||
|
return t->open(t, name, fda, tt);
|
||||||
|
}
|
||||||
|
|
||||||
|
int transport_recv(struct transport *t, int fd,
|
||||||
|
void *buf, int buflen, struct hw_timestamp *hwts)
|
||||||
|
{
|
||||||
|
return t->recv(t, fd, buf, buflen, hwts);
|
||||||
|
}
|
||||||
|
|
||||||
|
int transport_send(struct transport *t, struct fdarray *fda, int event,
|
||||||
|
void *buf, int buflen, struct hw_timestamp *hwts)
|
||||||
|
{
|
||||||
|
return t->send(t, fda, event, buf, buflen, hwts);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct transport *transport_create(enum transport_type type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TRANS_UDP_IPV4:
|
case TRANS_UDP_IPV4:
|
||||||
return &udp;
|
return udp_transport_create();
|
||||||
case TRANS_UDP_IPV6:
|
case TRANS_UDP_IPV6:
|
||||||
case TRANS_IEEE_802_3:
|
case TRANS_IEEE_802_3:
|
||||||
case TRANS_DEVICENET:
|
case TRANS_DEVICENET:
|
||||||
|
@ -41,3 +58,8 @@ struct transport *transport_find(enum transport_type type)
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void transport_destroy(struct transport *t)
|
||||||
|
{
|
||||||
|
t->release(t);
|
||||||
|
}
|
||||||
|
|
31
transport.h
31
transport.h
|
@ -44,19 +44,30 @@ struct hw_timestamp {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct transport {
|
struct transport;
|
||||||
int (*close)(struct fdarray *fda);
|
|
||||||
int (*open)(char *name, struct fdarray *fda, enum timestamp_type tt);
|
int transport_close(struct transport *t, struct fdarray *fda);
|
||||||
int (*recv)(int fd, void *buf, int buflen, struct hw_timestamp *hwts);
|
|
||||||
int (*send)(struct fdarray *fda, int event,
|
int transport_open(struct transport *t, char *name,
|
||||||
void *buf, int buflen, struct hw_timestamp *hwts);
|
struct fdarray *fda, enum timestamp_type tt);
|
||||||
};
|
|
||||||
|
int transport_recv(struct transport *t, int fd,
|
||||||
|
void *buf, int buflen, struct hw_timestamp *hwts);
|
||||||
|
|
||||||
|
int transport_send(struct transport *t, struct fdarray *fda, int event,
|
||||||
|
void *buf, int buflen, struct hw_timestamp *hwts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain a pointer to the specified transport.
|
* Allocate an instance of the specified transport.
|
||||||
* @param type Which transport to obtain.
|
* @param type Which transport to obtain.
|
||||||
* @return Pointer to a static global.
|
* @return Pointer to a transport instance on success, NULL otherwise.
|
||||||
*/
|
*/
|
||||||
struct transport *transport_find(enum transport_type type);
|
struct transport *transport_create(enum transport_type type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free an instance of a transport.
|
||||||
|
* @param t Pointer obtained by calling transport_create().
|
||||||
|
*/
|
||||||
|
void transport_destroy(struct transport *t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* @file transport_private.h
|
||||||
|
* @brief Defines a private interface for the abstract transport layer.
|
||||||
|
* @note Copyright (C) 2012 Richard Cochran <richardcochran@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
#ifndef HAVE_TRANSPORT_PRIVATE_H
|
||||||
|
#define HAVE_TRANSPORT_PRIVATE_H
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "fd.h"
|
||||||
|
#include "transport.h"
|
||||||
|
|
||||||
|
struct transport {
|
||||||
|
int (*close)(struct transport *t, struct fdarray *fda);
|
||||||
|
|
||||||
|
int (*open)(struct transport *t, char *name, struct fdarray *fda,
|
||||||
|
enum timestamp_type tt);
|
||||||
|
|
||||||
|
int (*recv)(struct transport *t, int fd, void *buf, int buflen,
|
||||||
|
struct hw_timestamp *hwts);
|
||||||
|
|
||||||
|
int (*send)(struct transport *t, struct fdarray *fda, int event,
|
||||||
|
void *buf, int buflen, struct hw_timestamp *hwts);
|
||||||
|
|
||||||
|
void (*release)(struct transport *t);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
31
udp.c
31
udp.c
|
@ -33,6 +33,7 @@
|
||||||
#include <linux/sockios.h>
|
#include <linux/sockios.h>
|
||||||
|
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
|
#include "transport_private.h"
|
||||||
#include "udp.h"
|
#include "udp.h"
|
||||||
|
|
||||||
#define EVENT_PORT 319
|
#define EVENT_PORT 319
|
||||||
|
@ -162,7 +163,7 @@ static int mcast_join(int fd, int index, const struct sockaddr *grp,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int udp_close(struct fdarray *fda)
|
static int udp_close(struct transport *t, struct fdarray *fda)
|
||||||
{
|
{
|
||||||
close(fda->fd[0]);
|
close(fda->fd[0]);
|
||||||
close(fda->fd[1]);
|
close(fda->fd[1]);
|
||||||
|
@ -216,7 +217,8 @@ no_socket:
|
||||||
|
|
||||||
static struct in_addr mc_addr;
|
static struct in_addr mc_addr;
|
||||||
|
|
||||||
int udp_open(char *name, struct fdarray *fda, enum timestamp_type ts_type)
|
static int udp_open(struct transport *t, char *name, struct fdarray *fda,
|
||||||
|
enum timestamp_type ts_type)
|
||||||
{
|
{
|
||||||
int efd, gfd;
|
int efd, gfd;
|
||||||
|
|
||||||
|
@ -316,13 +318,14 @@ static int receive(int fd, void *buf, int buflen,
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
int udp_recv(int fd, void *buf, int buflen, struct hw_timestamp *hwts)
|
static int udp_recv(struct transport *t, int fd, void *buf, int buflen,
|
||||||
|
struct hw_timestamp *hwts)
|
||||||
{
|
{
|
||||||
return receive(fd, buf, buflen, hwts, 0);
|
return receive(fd, buf, buflen, hwts, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int udp_send(struct fdarray *fda, int event,
|
static int udp_send(struct transport *t, struct fdarray *fda, int event,
|
||||||
void *buf, int len, struct hw_timestamp *hwts)
|
void *buf, int len, struct hw_timestamp *hwts)
|
||||||
{
|
{
|
||||||
ssize_t cnt;
|
ssize_t cnt;
|
||||||
int fd = event ? fda->fd[FD_EVENT] : fda->fd[FD_GENERAL];
|
int fd = event ? fda->fd[FD_EVENT] : fda->fd[FD_GENERAL];
|
||||||
|
@ -344,6 +347,24 @@ int udp_send(struct fdarray *fda, int event,
|
||||||
return event ? receive(fd, junk, len, hwts, MSG_ERRQUEUE) : cnt;
|
return event ? receive(fd, junk, len, hwts, MSG_ERRQUEUE) : cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct transport the_udp_transport = {
|
||||||
|
.close = udp_close,
|
||||||
|
.open = udp_open,
|
||||||
|
.recv = udp_recv,
|
||||||
|
.send = udp_send,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct transport *udp_transport_create(void)
|
||||||
|
{
|
||||||
|
/* No need for any per-instance allocation. */
|
||||||
|
return &the_udp_transport;
|
||||||
|
}
|
||||||
|
|
||||||
|
void udp_transport_destroy(struct transport *t)
|
||||||
|
{
|
||||||
|
/* No need for any per-instance deallocation. */
|
||||||
|
}
|
||||||
|
|
||||||
int udp_interface_macaddr(char *name, unsigned char *mac, int len)
|
int udp_interface_macaddr(char *name, unsigned char *mac, int len)
|
||||||
{
|
{
|
||||||
struct ifreq ifreq;
|
struct ifreq ifreq;
|
||||||
|
|
18
udp.h
18
udp.h
|
@ -23,12 +23,6 @@
|
||||||
#include "fd.h"
|
#include "fd.h"
|
||||||
#include "transport.h"
|
#include "transport.h"
|
||||||
|
|
||||||
int udp_close(struct fdarray *fda);
|
|
||||||
int udp_open(char *name, struct fdarray *fda, enum timestamp_type ts_type);
|
|
||||||
int udp_recv(int fd, void *buf, int buflen, struct hw_timestamp *hwts);
|
|
||||||
int udp_send(struct fdarray *fda, int event,
|
|
||||||
void *buf, int buflen, struct hw_timestamp *hwts);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the MAC address of a network interface.
|
* Obtain the MAC address of a network interface.
|
||||||
* @param name The name of the interface
|
* @param name The name of the interface
|
||||||
|
@ -38,4 +32,16 @@ int udp_send(struct fdarray *fda, int event,
|
||||||
*/
|
*/
|
||||||
int udp_interface_macaddr(char *name, unsigned char *mac, int len);
|
int udp_interface_macaddr(char *name, unsigned char *mac, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate an instance of a UDP/IPv4 transport.
|
||||||
|
* @return Pointer to a new transport instance on success, NULL otherwise.
|
||||||
|
*/
|
||||||
|
struct transport *udp_transport_create(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free an instance of a UDP/IPv4 transport.
|
||||||
|
* @param t Pointer obtained by calling udp_transport_create().
|
||||||
|
*/
|
||||||
|
void udp_transport_destroy(struct transport *t);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue