This will be needed for notifications. Only implemented for UDS. Signed-off-by: Jiri Benc <jb...@redhat.com> --- port.c | 14 ++++++++++++++ port.h | 22 ++++++++++++++++++++++ transport.c | 17 +++++++++++++++++ transport.h | 25 +++++++++++++++++++++++++ transport_private.h | 5 +++++ uds.c | 26 ++++++++++++++++++++++---- 6 files changed, 105 insertions(+), 4 deletions(-)
diff --git a/port.c b/port.c index 568bd30c8815..d8974ed1156b 100644 --- a/port.c +++ b/port.c @@ -2182,6 +2182,20 @@ int port_prepare_and_send(struct port *p, struct ptp_message *msg, int event) return cnt <= 0 ? -1 : 0; } +int port_recv_addr(struct port *p, uint8_t *addr) +{ + return transport_recv_addr(p->trp, addr); +} + +int port_forward_to(struct port *p, struct ptp_message *msg, int msglen, + uint8_t *addr, int addrlen) +{ + int cnt; + + cnt = transport_sendto(p->trp, &p->fda, msg, msglen, addr, addrlen); + return cnt <= 0 ? -1 : 0; +} + struct PortIdentity port_identity(struct port *p) { return p->portIdentity; diff --git a/port.h b/port.h index 9d1ddc9e94a3..8d78370992ca 100644 --- a/port.h +++ b/port.h @@ -105,6 +105,28 @@ int port_forward(struct port *p, struct ptp_message *msg, int msglen); int port_prepare_and_send(struct port *p, struct ptp_message *msg, int event); /** + * Get the source address of the last received message. + * @param p A pointer previously obtained via port_open(). + * @param addr Buffer large enough (at least TRANSPORT_RECV_ADDR_LEN + * bytes). + * @return The number of bytes written to the buffer (address + * length). + */ +int port_recv_addr(struct port *p, uint8_t *addr); + +/** + * Forward a message on a given port to the given address. + * @param p A pointer previously obtained via port_open(). + * @param msg The message to send. Must be in network byte order. + * @param msglen The length of the message in bytes. + * @param addr The address to send the message to. + * @param addrlen The length of the address in bytes. + * @return Zero on success, non-zero otherwise. + */ +int port_forward_to(struct port *p, struct ptp_message *msg, int msglen, + uint8_t *addr, int addrlen); + +/** * Obtain a port's identity. * @param p A pointer previously obtained via port_open(). * @return The port identity of 'p'. diff --git a/transport.c b/transport.c index b5346e5e51f4..7b8df79b19a7 100644 --- a/transport.c +++ b/transport.c @@ -53,6 +53,15 @@ int transport_peer(struct transport *t, struct fdarray *fda, int event, return t->send(t, fda, event, 1, buf, buflen, hwts); } +int transport_sendto(struct transport *t, struct fdarray *fda, + void *buf, int buflen, uint8_t *addr, int addrlen) +{ + if (t->sendto) { + return t->sendto(t, fda, buf, buflen, addr, addrlen); + } + return -1; +} + int transport_physical_addr(struct transport *t, uint8_t *addr) { if (t->physical_addr) { @@ -69,6 +78,14 @@ int transport_protocol_addr(struct transport *t, uint8_t *addr) return 0; } +int transport_recv_addr(struct transport *t, uint8_t *addr) +{ + if (t->recv_addr) { + return t->recv_addr(t, addr); + } + return 0; +} + enum transport_type transport_type(struct transport *t) { return t->type; diff --git a/transport.h b/transport.h index aa2018b4ecdf..fb7243f1fb16 100644 --- a/transport.h +++ b/transport.h @@ -76,6 +76,20 @@ int transport_send(struct transport *t, struct fdarray *fda, int event, int transport_peer(struct transport *t, struct fdarray *fda, int event, void *buf, int buflen, struct hw_timestamp *hwts); +/* + * Send message to the given address. This is intended for management + * messages only, thus goes always to the general port. + * @param t The transport. + * @param fda Array of file descriptors to use. + * @param buf Buffer with the message. + * @param buflen Length of the buffer. + * @param addr Destination address. + * @param addrlen Length of the destination address. + * @return Number of bytes sent or -1 in case of error. + */ +int transport_sendto(struct transport *t, struct fdarray *fda, + void *buf, int buflen, uint8_t *addr, int addrlen); + /** * Returns the transport's type. */ @@ -101,6 +115,17 @@ int transport_physical_addr(struct transport *t, uint8_t *addr); */ int transport_protocol_addr(struct transport *t, uint8_t *addr); +#define TRANSPORT_RECV_ADDR_LEN 128 + +/** + * Gets the source address of the last received message. + * @param t The transport. + * @param addr The address will be written to this buffer. + * @return The number of bytes written to the buffer. Will be 0-110 + * bytes. + */ +int transport_recv_addr(struct transport *t, uint8_t *addr); + /** * Allocate an instance of the specified transport. * @param type Which transport to obtain. diff --git a/transport_private.h b/transport_private.h index 7124f94af424..745fb17069d2 100644 --- a/transport_private.h +++ b/transport_private.h @@ -39,11 +39,16 @@ struct transport { int (*send)(struct transport *t, struct fdarray *fda, int event, int peer, void *buf, int buflen, struct hw_timestamp *hwts); + int (*sendto)(struct transport *t, struct fdarray *fda, + void *buf, int buflen, uint8_t *addr, int addrlen); + void (*release)(struct transport *t); int (*physical_addr)(struct transport *t, uint8_t *addr); int (*protocol_addr)(struct transport *t, uint8_t *addr); + + int (*recv_addr)(struct transport *t, uint8_t *addr); }; #endif diff --git a/uds.c b/uds.c index 35f5eccf0545..dc0dc756f85a 100644 --- a/uds.c +++ b/uds.c @@ -98,24 +98,40 @@ static int uds_recv(struct transport *t, int fd, void *buf, int buflen, return cnt; } -static int uds_send(struct transport *t, struct fdarray *fda, int event, - int peer, void *buf, int buflen, struct hw_timestamp *hwts) +static int uds_sendto(struct transport *t, struct fdarray *fda, + void *buf, int buflen, uint8_t *addr, int addrlen) { int cnt, fd = fda->fd[FD_GENERAL]; - struct uds *uds = container_of(t, struct uds, t); - cnt = sendto(fd, buf, buflen, 0, (struct sockaddr *) &uds->sa, uds->len); + + cnt = sendto(fd, buf, buflen, 0, (struct sockaddr *)addr, addrlen); if (cnt <= 0) { pr_err("uds: sendto failed: %m"); } return cnt; } +static int uds_send(struct transport *t, struct fdarray *fda, int event, + int peer, void *buf, int buflen, struct hw_timestamp *hwts) +{ + struct uds *uds = container_of(t, struct uds, t); + + return uds_sendto(t, fda, buf, buflen, (uint8_t *)&uds->sa, uds->len); +} + static void uds_release(struct transport *t) { struct uds *uds = container_of(t, struct uds, t); free(uds); } +int uds_recv_addr(struct transport *t, uint8_t *addr) +{ + struct uds *uds = container_of(t, struct uds, t); + + memcpy(addr, &uds->sa, uds->len); + return uds->len; +} + struct transport *uds_transport_create(void) { struct uds *uds; @@ -126,7 +142,9 @@ struct transport *uds_transport_create(void) uds->t.open = uds_open; uds->t.recv = uds_recv; uds->t.send = uds_send; + uds->t.sendto = uds_sendto; uds->t.release = uds_release; + uds->t.recv_addr = uds_recv_addr; return &uds->t; } -- 1.7.6.5 ------------------------------------------------------------------------------ Learn Graph Databases - Download FREE O'Reilly Book "Graph Databases" is the definitive new guide to graph databases and their applications. Written by three acclaimed leaders in the field, this first edition is now available. Download your free book today! http://p.sf.net/sfu/13534_NeoTech _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel