mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-09 08:21:08 -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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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])
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
struct ifreq req;
|
||||
|
|
@ -209,13 +215,20 @@ error_close:
|
|||
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;
|
||||
int fd, res;
|
||||
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)
|
||||
return fd;
|
||||
|
||||
|
|
@ -244,6 +257,21 @@ error_no_source:
|
|||
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 *server;
|
||||
|
|
@ -269,7 +297,10 @@ struct server *avdecc_server_new(struct impl *impl, struct spa_dict *props)
|
|||
|
||||
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;
|
||||
|
||||
|
||||
|
|
@ -315,12 +346,10 @@ void avdecc_server_add_listener(struct server *server, struct spa_hook *listener
|
|||
|
||||
void avdecc_server_free(struct server *server)
|
||||
{
|
||||
struct impl *impl = server->impl;
|
||||
|
||||
server_destroy_descriptors(server);
|
||||
spa_list_remove(&server->link);
|
||||
if (server->source)
|
||||
pw_loop_destroy_source(impl->loop, server->source);
|
||||
if (server->transport)
|
||||
server->transport->destroy(server);
|
||||
pw_timer_queue_cancel(&server->timer);
|
||||
spa_hook_list_clean(&server->listener_list);
|
||||
free(server->ifname);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,15 @@ struct avb_mrp;
|
|||
#define AVB_TSN_ETH 0x22f0
|
||||
#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 pw_loop *loop;
|
||||
struct pw_timer_queue *timer_queue;
|
||||
|
|
@ -77,6 +86,9 @@ struct server {
|
|||
uint64_t entity_id;
|
||||
int ifindex;
|
||||
|
||||
const struct avb_transport_ops *transport;
|
||||
void *transport_data;
|
||||
|
||||
struct spa_source *source;
|
||||
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,
|
||||
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_send_packet(struct server *server, const uint8_t dest[6],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue