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 {
|
||||
char *name;
|
||||
struct clock *clock;
|
||||
struct transport *transport;
|
||||
struct transport *trp;
|
||||
enum timestamp_type timestamping;
|
||||
struct fdarray fda;
|
||||
struct foreign_clock *best;
|
||||
|
@ -351,7 +351,7 @@ static int port_delay_request(struct port *p)
|
|||
if (msg_pre_send(msg))
|
||||
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) {
|
||||
pr_err("port %hu: send delay request failed", portnum(p));
|
||||
goto out;
|
||||
|
@ -420,7 +420,7 @@ static int port_tx_announce(struct port *p)
|
|||
err = -1;
|
||||
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) {
|
||||
pr_err("port %hu: send announce failed", portnum(p));
|
||||
err = -1;
|
||||
|
@ -464,7 +464,7 @@ static int port_tx_sync(struct port *p)
|
|||
err = -1;
|
||||
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) {
|
||||
pr_err("port %hu: send sync failed", portnum(p));
|
||||
err = -1;
|
||||
|
@ -497,7 +497,7 @@ static int port_tx_sync(struct port *p)
|
|||
err = -1;
|
||||
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) {
|
||||
pr_err("port %hu: send follow up failed", portnum(p));
|
||||
err = -1;
|
||||
|
@ -531,7 +531,7 @@ static int port_initialize(struct port *p)
|
|||
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;
|
||||
|
||||
for (i = 0; i < N_TIMER_FDS; i++) {
|
||||
|
@ -546,7 +546,7 @@ static int port_initialize(struct port *p)
|
|||
return 0;
|
||||
|
||||
no_tmo:
|
||||
p->transport->close(&p->fda);
|
||||
transport_close(p->trp, &p->fda);
|
||||
no_tropen:
|
||||
no_timers:
|
||||
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;
|
||||
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) {
|
||||
pr_err("port %hu: send delay response failed", portnum(p));
|
||||
err = -1;
|
||||
|
@ -782,7 +782,8 @@ static void process_sync(struct port *p, struct ptp_message *m)
|
|||
void port_close(struct port *p)
|
||||
{
|
||||
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++) {
|
||||
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;
|
||||
|
||||
cnt = p->transport->recv(fd, msg, sizeof(*msg), &msg->hwts);
|
||||
cnt = transport_recv(p->trp, fd, msg, sizeof(*msg), &msg->hwts);
|
||||
if (cnt <= 0) {
|
||||
pr_err("port %hu: recv message failed", portnum(p));
|
||||
msg_put(msg);
|
||||
|
@ -979,8 +980,8 @@ struct port *port_open(struct port_defaults *pod,
|
|||
p->pod = *pod;
|
||||
p->name = name;
|
||||
p->clock = clock;
|
||||
p->transport = transport_find(transport);
|
||||
if (!p->transport) {
|
||||
p->trp = transport_create(transport);
|
||||
if (!p->trp) {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
|
38
transport.c
38
transport.c
|
@ -18,20 +18,37 @@
|
|||
*/
|
||||
|
||||
#include "transport.h"
|
||||
#include "transport_private.h"
|
||||
#include "udp.h"
|
||||
|
||||
static struct transport udp = {
|
||||
.close = udp_close,
|
||||
.open = udp_open,
|
||||
.recv = udp_recv,
|
||||
.send = udp_send,
|
||||
};
|
||||
int transport_close(struct transport *t, struct fdarray *fda)
|
||||
{
|
||||
return t->close(t, fda);
|
||||
}
|
||||
|
||||
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) {
|
||||
case TRANS_UDP_IPV4:
|
||||
return &udp;
|
||||
return udp_transport_create();
|
||||
case TRANS_UDP_IPV6:
|
||||
case TRANS_IEEE_802_3:
|
||||
case TRANS_DEVICENET:
|
||||
|
@ -41,3 +58,8 @@ struct transport *transport_find(enum transport_type type)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void transport_destroy(struct transport *t)
|
||||
{
|
||||
t->release(t);
|
||||
}
|
||||
|
|
29
transport.h
29
transport.h
|
@ -44,19 +44,30 @@ struct hw_timestamp {
|
|||
struct timespec ts;
|
||||
};
|
||||
|
||||
struct transport {
|
||||
int (*close)(struct fdarray *fda);
|
||||
int (*open)(char *name, struct fdarray *fda, enum timestamp_type tt);
|
||||
int (*recv)(int fd, void *buf, int buflen, struct hw_timestamp *hwts);
|
||||
int (*send)(struct fdarray *fda, int event,
|
||||
struct transport;
|
||||
|
||||
int transport_close(struct transport *t, struct fdarray *fda);
|
||||
|
||||
int transport_open(struct transport *t, char *name,
|
||||
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.
|
||||
* @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
|
||||
|
|
|
@ -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
|
29
udp.c
29
udp.c
|
@ -33,6 +33,7 @@
|
|||
#include <linux/sockios.h>
|
||||
|
||||
#include "print.h"
|
||||
#include "transport_private.h"
|
||||
#include "udp.h"
|
||||
|
||||
#define EVENT_PORT 319
|
||||
|
@ -162,7 +163,7 @@ static int mcast_join(int fd, int index, const struct sockaddr *grp,
|
|||
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[1]);
|
||||
|
@ -216,7 +217,8 @@ no_socket:
|
|||
|
||||
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;
|
||||
|
||||
|
@ -316,12 +318,13 @@ static int receive(int fd, void *buf, int buflen,
|
|||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ssize_t cnt;
|
||||
|
@ -344,6 +347,24 @@ int udp_send(struct fdarray *fda, int event,
|
|||
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)
|
||||
{
|
||||
struct ifreq ifreq;
|
||||
|
|
18
udp.h
18
udp.h
|
@ -23,12 +23,6 @@
|
|||
#include "fd.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.
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
Loading…
Reference in New Issue