mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-10 08:21:03 -04:00
module-avb: add transport abstraction for pluggable network backends
Introduce struct avb_transport_ops vtable with setup/send_packet/ make_socket/destroy callbacks. The existing raw AF_PACKET socket code becomes the default "raw" transport. avdecc_server_new() defaults to avb_transport_raw if no transport is set, and avdecc_server_free() delegates cleanup through the transport ops. This enables alternative transports (e.g. loopback for testing) without modifying protocol handler code. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d9821d09c7
commit
a73988d38d
2 changed files with 52 additions and 9 deletions
|
|
@ -84,7 +84,7 @@ static void on_socket_data(void *data, int fd, uint32_t mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int avb_server_send_packet(struct server *server, const uint8_t dest[6],
|
static int raw_send_packet(struct server *server, const uint8_t dest[6],
|
||||||
uint16_t type, void *data, size_t size)
|
uint16_t type, void *data, size_t size)
|
||||||
{
|
{
|
||||||
struct avb_ethernet_header *hdr = (struct avb_ethernet_header*)data;
|
struct avb_ethernet_header *hdr = (struct avb_ethernet_header*)data;
|
||||||
|
|
@ -101,6 +101,12 @@ int avb_server_send_packet(struct server *server, const uint8_t dest[6],
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int avb_server_send_packet(struct server *server, const uint8_t dest[6],
|
||||||
|
uint16_t type, void *data, size_t size)
|
||||||
|
{
|
||||||
|
return server->transport->send_packet(server, dest, type, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
static int load_filter(int fd, uint16_t eth, const uint8_t dest[6], const uint8_t mac[6])
|
static int load_filter(int fd, uint16_t eth, const uint8_t dest[6], const uint8_t mac[6])
|
||||||
{
|
{
|
||||||
struct sock_fprog filter;
|
struct sock_fprog filter;
|
||||||
|
|
@ -136,7 +142,7 @@ static int load_filter(int fd, uint16_t eth, const uint8_t dest[6], const uint8_
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int avb_server_make_socket(struct server *server, uint16_t type, const uint8_t mac[6])
|
static int raw_make_socket(struct server *server, uint16_t type, const uint8_t mac[6])
|
||||||
{
|
{
|
||||||
int fd, res;
|
int fd, res;
|
||||||
struct ifreq req;
|
struct ifreq req;
|
||||||
|
|
@ -209,13 +215,20 @@ error_close:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_socket(struct server *server)
|
int avb_server_make_socket(struct server *server, uint16_t type, const uint8_t mac[6])
|
||||||
|
{
|
||||||
|
if (server->transport && server->transport->make_socket)
|
||||||
|
return server->transport->make_socket(server, type, mac);
|
||||||
|
return raw_make_socket(server, type, mac);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int raw_transport_setup(struct server *server)
|
||||||
{
|
{
|
||||||
struct impl *impl = server->impl;
|
struct impl *impl = server->impl;
|
||||||
int fd, res;
|
int fd, res;
|
||||||
static const uint8_t bmac[6] = AVB_BROADCAST_MAC;
|
static const uint8_t bmac[6] = AVB_BROADCAST_MAC;
|
||||||
|
|
||||||
fd = avb_server_make_socket(server, AVB_TSN_ETH, bmac);
|
fd = raw_make_socket(server, AVB_TSN_ETH, bmac);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
|
|
@ -244,6 +257,21 @@ error_no_source:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void raw_transport_destroy(struct server *server)
|
||||||
|
{
|
||||||
|
struct impl *impl = server->impl;
|
||||||
|
if (server->source)
|
||||||
|
pw_loop_destroy_source(impl->loop, server->source);
|
||||||
|
server->source = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct avb_transport_ops avb_transport_raw = {
|
||||||
|
.setup = raw_transport_setup,
|
||||||
|
.send_packet = raw_send_packet,
|
||||||
|
.make_socket = raw_make_socket,
|
||||||
|
.destroy = raw_transport_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
struct server *avdecc_server_new(struct impl *impl, struct spa_dict *props)
|
struct server *avdecc_server_new(struct impl *impl, struct spa_dict *props)
|
||||||
{
|
{
|
||||||
struct server *server;
|
struct server *server;
|
||||||
|
|
@ -269,7 +297,10 @@ struct server *avdecc_server_new(struct impl *impl, struct spa_dict *props)
|
||||||
|
|
||||||
server->debug_messages = false;
|
server->debug_messages = false;
|
||||||
|
|
||||||
if ((res = setup_socket(server)) < 0)
|
if (server->transport == NULL)
|
||||||
|
server->transport = &avb_transport_raw;
|
||||||
|
|
||||||
|
if ((res = server->transport->setup(server)) < 0)
|
||||||
goto error_free;
|
goto error_free;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -315,12 +346,10 @@ void avdecc_server_add_listener(struct server *server, struct spa_hook *listener
|
||||||
|
|
||||||
void avdecc_server_free(struct server *server)
|
void avdecc_server_free(struct server *server)
|
||||||
{
|
{
|
||||||
struct impl *impl = server->impl;
|
|
||||||
|
|
||||||
server_destroy_descriptors(server);
|
server_destroy_descriptors(server);
|
||||||
spa_list_remove(&server->link);
|
spa_list_remove(&server->link);
|
||||||
if (server->source)
|
if (server->transport)
|
||||||
pw_loop_destroy_source(impl->loop, server->source);
|
server->transport->destroy(server);
|
||||||
pw_timer_queue_cancel(&server->timer);
|
pw_timer_queue_cancel(&server->timer);
|
||||||
spa_hook_list_clean(&server->listener_list);
|
spa_hook_list_clean(&server->listener_list);
|
||||||
free(server->ifname);
|
free(server->ifname);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,15 @@ struct avb_mrp;
|
||||||
#define AVB_TSN_ETH 0x22f0
|
#define AVB_TSN_ETH 0x22f0
|
||||||
#define AVB_BROADCAST_MAC { 0x91, 0xe0, 0xf0, 0x01, 0x00, 0x00 };
|
#define AVB_BROADCAST_MAC { 0x91, 0xe0, 0xf0, 0x01, 0x00, 0x00 };
|
||||||
|
|
||||||
|
struct avb_transport_ops {
|
||||||
|
int (*setup)(struct server *server);
|
||||||
|
int (*send_packet)(struct server *server, const uint8_t dest[6],
|
||||||
|
uint16_t type, void *data, size_t size);
|
||||||
|
int (*make_socket)(struct server *server, uint16_t type,
|
||||||
|
const uint8_t mac[6]);
|
||||||
|
void (*destroy)(struct server *server);
|
||||||
|
};
|
||||||
|
|
||||||
struct impl {
|
struct impl {
|
||||||
struct pw_loop *loop;
|
struct pw_loop *loop;
|
||||||
struct pw_timer_queue *timer_queue;
|
struct pw_timer_queue *timer_queue;
|
||||||
|
|
@ -77,6 +86,9 @@ struct server {
|
||||||
uint64_t entity_id;
|
uint64_t entity_id;
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
|
||||||
|
const struct avb_transport_ops *transport;
|
||||||
|
void *transport_data;
|
||||||
|
|
||||||
struct spa_source *source;
|
struct spa_source *source;
|
||||||
struct pw_timer timer;
|
struct pw_timer timer;
|
||||||
|
|
||||||
|
|
@ -144,6 +156,8 @@ void avdecc_server_free(struct server *server);
|
||||||
void avdecc_server_add_listener(struct server *server, struct spa_hook *listener,
|
void avdecc_server_add_listener(struct server *server, struct spa_hook *listener,
|
||||||
const struct server_events *events, void *data);
|
const struct server_events *events, void *data);
|
||||||
|
|
||||||
|
extern const struct avb_transport_ops avb_transport_raw;
|
||||||
|
|
||||||
int avb_server_make_socket(struct server *server, uint16_t type, const uint8_t mac[6]);
|
int avb_server_make_socket(struct server *server, uint16_t type, const uint8_t mac[6]);
|
||||||
|
|
||||||
int avb_server_send_packet(struct server *server, const uint8_t dest[6],
|
int avb_server_send_packet(struct server *server, const uint8_t dest[6],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue