diff --git a/src/daemon/pipewire-avb.conf.in b/src/daemon/pipewire-avb.conf.in index 6cf786ab1..96dfbd579 100644 --- a/src/daemon/pipewire-avb.conf.in +++ b/src/daemon/pipewire-avb.conf.in @@ -35,7 +35,7 @@ context.modules = [ } { name = libpipewire-module-client-device } { name = libpipewire-module-adapter } - { name = libpipewire-module-avbtp + { name = libpipewire-module-avb args = { # contents of avb.properties can also be placed here # to have config per server. diff --git a/src/modules/meson.build b/src/modules/meson.build index c5a926f31..04d59d889 100644 --- a/src/modules/meson.build +++ b/src/modules/meson.build @@ -5,7 +5,7 @@ subdir('spa') module_sources = [ 'module-access.c', 'module-adapter.c', - 'module-avbtp.c', + 'module-avb.c', 'module-client-device.c', 'module-client-node.c', 'module-echo-cancel.c', @@ -518,22 +518,22 @@ pipewire_module_fallback_sink = shared_library('pipewire-module-fallback-sink', dependencies : [mathlib, dl_lib, rt_lib, pipewire_dep], ) -build_module_avbtp = get_option('avb').allowed() -if build_module_avbtp -pipewire_module_avbtp = shared_library('pipewire-module-avbtp', - [ 'module-avbtp.c', - 'module-avbtp/avb.c', - 'module-avbtp/adp.c', - 'module-avbtp/acmp.c', - 'module-avbtp/aecp.c', - 'module-avbtp/aecp-aem.c', - 'module-avbtp/avdecc.c', - 'module-avbtp/maap.c', - 'module-avbtp/mmrp.c', - 'module-avbtp/mrp.c', - 'module-avbtp/msrp.c', - 'module-avbtp/mvrp.c', - 'module-avbtp/srp.c' +build_module_avb = get_option('avb').allowed() +if build_module_avb +pipewire_module_avb = shared_library('pipewire-module-avb', + [ 'module-avb.c', + 'module-avb/avb.c', + 'module-avb/adp.c', + 'module-avb/acmp.c', + 'module-avb/aecp.c', + 'module-avb/aecp-aem.c', + 'module-avb/avdecc.c', + 'module-avb/maap.c', + 'module-avb/mmrp.c', + 'module-avb/mrp.c', + 'module-avb/msrp.c', + 'module-avb/mvrp.c', + 'module-avb/srp.c' ], include_directories : [configinc], install : true, @@ -542,4 +542,4 @@ pipewire_module_avbtp = shared_library('pipewire-module-avbtp', dependencies : [mathlib, dl_lib, rt_lib, pipewire_dep], ) endif -summary({'avbtp': build_module_avbtp}, bool_yn: true, section: 'Optional Modules') +summary({'avb': build_module_avb}, bool_yn: true, section: 'Optional Modules') diff --git a/src/modules/module-avb/aaf.h b/src/modules/module-avb/aaf.h new file mode 100644 index 000000000..3d6273f4b --- /dev/null +++ b/src/modules/module-avb/aaf.h @@ -0,0 +1,140 @@ +/* AVB support + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AVB_AAF_H +#define AVB_AAF_H + +struct avb_packet_aaf { + struct avb_ethernet_header hdr; + uint8_t subtype; +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned sv:1; + unsigned version:3; + unsigned mr:1; + unsigned _r1:1; + unsigned gv:1; + unsigned tv:1; + + uint8_t seq_number; + + unsigned _r2:7; + unsigned tu:1; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + unsigned tv:1; + unsigned gv:1; + unsigned _r1:1; + unsigned mr:1; + unsigned version:3; + unsigned sv:1; + + uint8_t seq_num; + + unsigned tu:1; + unsigned _r2:7; +#endif + uint64_t stream_id; + uint32_t timestamp; +#define AVB_AAF_FORMAT_USER 0x00 +#define AVB_AAF_FORMAT_FLOAT_32BIT 0x01 +#define AVB_AAF_FORMAT_INT_32BIT 0x02 +#define AVB_AAF_FORMAT_INT_24BIT 0x03 +#define AVB_AAF_FORMAT_INT_16BIT 0x04 +#define AVB_AAF_FORMAT_AES3_32BIT 0x05 + uint8_t format; + +#define AVB_AAF_PCM_NSR_USER 0x00 +#define AVB_AAF_PCM_NSR_8KHZ 0x01 +#define AVB_AAF_PCM_NSR_16KHZ 0x02 +#define AVB_AAF_PCM_NSR_32KHZ 0x03 +#define AVB_AAF_PCM_NSR_44_1KHZ 0x04 +#define AVB_AAF_PCM_NSR_48KHZ 0x05 +#define AVB_AAF_PCM_NSR_88_2KHZ 0x06 +#define AVB_AAF_PCM_NSR_96KHZ 0x07 +#define AVB_AAF_PCM_NSR_176_4KHZ 0x08 +#define AVB_AAF_PCM_NSR_192KHZ 0x09 +#define AVB_AAF_PCM_NSR_24KHZ 0x0A +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned nsr:4; + unsigned _r3:4; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + unsigned _r3:4; + unsigned nsr:4; +#endif + uint8_t chan_per_frame; + uint8_t bit_depth; + uint16_t data_len; + +#define AVB_AAF_PCM_SP_NORMAL 0x00 +#define AVB_AAF_PCM_SP_SPARSE 0x01 +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned _r4:3; + unsigned sp:1; + unsigned event:4; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + unsigned event:4; + unsigned sp:1; + unsigned _r4:3; +#endif + uint8_t _r5; + uint8_t payload[0]; +} __attribute__ ((__packed__)); + +#define AVB_PACKET_AAF_SET_SUBTYPE(p,v) ((p)->subtype = (v)) +#define AVB_PACKET_AAF_SET_SV(p,v) ((p)->sv = (v)) +#define AVB_PACKET_AAF_SET_VERSION(p,v) ((p)->version = (v)) +#define AVB_PACKET_AAF_SET_MR(p,v) ((p)->mr = (v)) +#define AVB_PACKET_AAF_SET_GV(p,v) ((p)->gv = (v)) +#define AVB_PACKET_AAF_SET_TV(p,v) ((p)->tv = (v)) +#define AVB_PACKET_AAF_SET_SEQ_NUM(p,v) ((p)->seq_num = (v)) +#define AVB_PACKET_AAF_SET_TU(p,v) ((p)->tu = (v)) +#define AVB_PACKET_AAF_SET_STREAM_ID(p,v) ((p)->stream_id = htobe64(v)) +#define AVB_PACKET_AAF_SET_TIMESTAMP(p,v) ((p)->timestamp = htonl(v)) +#define AVB_PACKET_AAF_SET_DATA_LEN(p,v) ((p)->data_len = htons(v)) +#define AVB_PACKET_AAF_SET_FORMAT(p,v) ((p)->format = (v)) +#define AVB_PACKET_AAF_SET_NSR(p,v) ((p)->nsr = (v)) +#define AVB_PACKET_AAF_SET_CHAN_PER_FRAME(p,v) ((p)->chan_per_frame = (v)) +#define AVB_PACKET_AAF_SET_BIT_DEPTH(p,v) ((p)->bit_depth = (v)) +#define AVB_PACKET_AAF_SET_SP(p,v) ((p)->sp = (v)) +#define AVB_PACKET_AAF_SET_EVENT(p,v) ((p)->event = (v)) + +#define AVB_PACKET_AAF_GET_SUBTYPE(p) ((p)->subtype) +#define AVB_PACKET_AAF_GET_SV(p) ((p)->sv) +#define AVB_PACKET_AAF_GET_VERSION(p) ((p)->version) +#define AVB_PACKET_AAF_GET_MR(p) ((p)->mr) +#define AVB_PACKET_AAF_GET_GV(p) ((p)->gv) +#define AVB_PACKET_AAF_GET_TV(p) ((p)->tv) +#define AVB_PACKET_AAF_GET_SEQ_NUM(p) ((p)->seq_num) +#define AVB_PACKET_AAF_GET_TU(p) ((p)->tu) +#define AVB_PACKET_AAF_GET_STREAM_ID(p) be64toh((p)->stream_id) +#define AVB_PACKET_AAF_GET_TIMESTAMP(p) ntohl((p)->timestamp) +#define AVB_PACKET_AAF_GET_DATA_LEN(p) ntohs((p)->data_len) +#define AVB_PACKET_AAF_GET_FORMAT(p) ((p)->format) +#define AVB_PACKET_AAF_GET_NSR(p) ((p)->nsr) +#define AVB_PACKET_AAF_GET_CHAN_PER_FRAME(p) ((p)->chan_per_frame) +#define AVB_PACKET_AAF_GET_BIT_DEPTH(p) ((p)->bit_depth) +#define AVB_PACKET_AAF_GET_SP(p) ((p)->sp) +#define AVB_PACKET_AAF_GET_EVENT(p) ((p)->event) + + +#endif /* AVB_AAF_H */ diff --git a/src/modules/module-avbtp/acmp.c b/src/modules/module-avb/acmp.c similarity index 66% rename from src/modules/module-avbtp/acmp.c rename to src/modules/module-avb/acmp.c index e8c8f4c96..c06a48938 100644 --- a/src/modules/module-avbtp/acmp.c +++ b/src/modules/module-avb/acmp.c @@ -54,15 +54,15 @@ struct acmp { struct spa_list pending[3]; uint16_t sequence_id[3]; - struct avbtp_msrp_attribute *listener_attr; - struct avbtp_msrp_attribute *talker_attr; + struct avb_msrp_attribute *listener_attr; + struct avb_msrp_attribute *talker_attr; }; static void *pending_new(struct acmp *acmp, uint32_t type, uint64_t now, uint32_t timeout_ms, - const struct avbtp_packet_acmp *m, size_t size) + const struct avb_packet_acmp *m, size_t size) { struct pending *p; - struct avbtp_packet_acmp *pm; + struct avb_packet_acmp *pm; p = calloc(1, sizeof(*p) + size); if (p == NULL) return NULL; @@ -105,22 +105,22 @@ static int reply_not_supported(struct acmp *acmp, const void *m, int len) { struct server *server = acmp->server; uint8_t buf[len]; - struct avbtp_packet_acmp *reply = (struct avbtp_packet_acmp*)buf; + struct avb_packet_acmp *reply = (struct avb_packet_acmp*)buf; memcpy(reply, m, len); - AVBTP_PACKET_ACMP_SET_STATUS(reply, AVBTP_ACMP_STATUS_NOT_SUPPORTED); + AVB_PACKET_ACMP_SET_STATUS(reply, AVB_ACMP_STATUS_NOT_SUPPORTED); - return avbtp_server_send_packet(server, reply->hdr.eth.src, + return avb_server_send_packet(server, reply->hdr.eth.src, AVB_TSN_ETH, reply, len); } static int retry_pending(struct acmp *acmp, uint64_t now, struct pending *p) { struct server *server = acmp->server; - struct avbtp_packet_acmp *cmd = p->ptr; + struct avb_packet_acmp *cmd = p->ptr; p->retry++; p->last_time = now; - return avbtp_server_send_packet(server, cmd->hdr.eth.dest, + return avb_server_send_packet(server, cmd->hdr.eth.dest, AVB_TSN_ETH, cmd, p->size); } @@ -128,25 +128,25 @@ static int handle_connect_tx_command(struct acmp *acmp, uint64_t now, const void { struct server *server = acmp->server; uint8_t buf[len]; - const struct avbtp_packet_acmp *p = m; - struct avbtp_packet_acmp *reply = (struct avbtp_packet_acmp*)buf; + const struct avb_packet_acmp *p = m; + struct avb_packet_acmp *reply = (struct avb_packet_acmp*)buf; if (be64toh(p->talker_guid) != server->entity_id) return 0; memcpy(reply, m, len); - AVBTP_PACKET_ACMP_SET_MESSAGE_TYPE(reply, AVBTP_ACMP_MESSAGE_TYPE_CONNECT_TX_RESPONSE); - AVBTP_PACKET_ACMP_SET_STATUS(reply, AVBTP_ACMP_STATUS_SUCCESS); + AVB_PACKET_ACMP_SET_MESSAGE_TYPE(reply, AVB_ACMP_MESSAGE_TYPE_CONNECT_TX_RESPONSE); + AVB_PACKET_ACMP_SET_STATUS(reply, AVB_ACMP_STATUS_SUCCESS); - return avbtp_server_send_packet(server, reply->hdr.eth.dest, + return avb_server_send_packet(server, reply->hdr.eth.dest, AVB_TSN_ETH, reply, len); } static int handle_connect_tx_response(struct acmp *acmp, uint64_t now, const void *m, int len) { struct server *server = acmp->server; - const struct avbtp_packet_acmp *resp = m; - struct avbtp_packet_acmp *reply; + const struct avb_packet_acmp *resp = m; + struct avb_packet_acmp *reply; struct pending *pending; uint16_t sequence_id; int res; @@ -163,17 +163,17 @@ static int handle_connect_tx_response(struct acmp *acmp, uint64_t now, const voi reply = pending->ptr; memcpy(reply, resp, SPA_MIN((int)pending->size, len)); reply->sequence_id = htons(pending->old_sequence_id); - AVBTP_PACKET_ACMP_SET_MESSAGE_TYPE(reply, AVBTP_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE); + AVB_PACKET_ACMP_SET_MESSAGE_TYPE(reply, AVB_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE); acmp->listener_attr->attr.listener.stream_id = reply->stream_id; - acmp->listener_attr->param = AVBTP_MSRP_LISTENER_PARAM_READY; - avbtp_mrp_mad_begin(server->mrp, now, acmp->listener_attr->mrp); - avbtp_mrp_mad_join(server->mrp, now, acmp->listener_attr->mrp, true); + acmp->listener_attr->param = AVB_MSRP_LISTENER_PARAM_READY; + avb_mrp_mad_begin(server->mrp, now, acmp->listener_attr->mrp); + avb_mrp_mad_join(server->mrp, now, acmp->listener_attr->mrp, true); acmp->talker_attr->attr.talker.stream_id = reply->stream_id; - avbtp_mrp_mad_begin(server->mrp, now, acmp->talker_attr->mrp); + avb_mrp_mad_begin(server->mrp, now, acmp->talker_attr->mrp); - res = avbtp_server_send_packet(server, reply->hdr.eth.dest, + res = avb_server_send_packet(server, reply->hdr.eth.dest, AVB_TSN_ETH, reply, pending->size); pending_free(acmp, pending); @@ -185,25 +185,25 @@ static int handle_disconnect_tx_command(struct acmp *acmp, uint64_t now, const v { struct server *server = acmp->server; uint8_t buf[len]; - const struct avbtp_packet_acmp *p = m; - struct avbtp_packet_acmp *reply = (struct avbtp_packet_acmp*)buf; + const struct avb_packet_acmp *p = m; + struct avb_packet_acmp *reply = (struct avb_packet_acmp*)buf; if (be64toh(p->talker_guid) != server->entity_id) return 0; memcpy(reply, m, len); - AVBTP_PACKET_ACMP_SET_MESSAGE_TYPE(reply, AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_TX_RESPONSE); - AVBTP_PACKET_ACMP_SET_STATUS(reply, AVBTP_ACMP_STATUS_SUCCESS); + AVB_PACKET_ACMP_SET_MESSAGE_TYPE(reply, AVB_ACMP_MESSAGE_TYPE_DISCONNECT_TX_RESPONSE); + AVB_PACKET_ACMP_SET_STATUS(reply, AVB_ACMP_STATUS_SUCCESS); - return avbtp_server_send_packet(server, reply->hdr.eth.dest, + return avb_server_send_packet(server, reply->hdr.eth.dest, AVB_TSN_ETH, reply, len); } static int handle_disconnect_tx_response(struct acmp *acmp, uint64_t now, const void *m, int len) { struct server *server = acmp->server; - const struct avbtp_packet_acmp *resp = m; - struct avbtp_packet_acmp *reply; + const struct avb_packet_acmp *resp = m; + struct avb_packet_acmp *reply; struct pending *pending; uint16_t sequence_id; int res; @@ -220,11 +220,11 @@ static int handle_disconnect_tx_response(struct acmp *acmp, uint64_t now, const reply = pending->ptr; memcpy(reply, resp, SPA_MIN((int)pending->size, len)); reply->sequence_id = htons(pending->old_sequence_id); - AVBTP_PACKET_ACMP_SET_MESSAGE_TYPE(reply, AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_RX_RESPONSE); + AVB_PACKET_ACMP_SET_MESSAGE_TYPE(reply, AVB_ACMP_MESSAGE_TYPE_DISCONNECT_RX_RESPONSE); - avbtp_mrp_mad_leave(server->mrp, now, acmp->listener_attr->mrp); + avb_mrp_mad_leave(server->mrp, now, acmp->listener_attr->mrp); - res = avbtp_server_send_packet(server, reply->hdr.eth.dest, + res = avb_server_send_packet(server, reply->hdr.eth.dest, AVB_TSN_ETH, reply, pending->size); pending_free(acmp, pending); @@ -235,21 +235,21 @@ static int handle_disconnect_tx_response(struct acmp *acmp, uint64_t now, const static int handle_connect_rx_command(struct acmp *acmp, uint64_t now, const void *m, int len) { struct server *server = acmp->server; - const struct avbtp_packet_acmp *p = m; - struct avbtp_packet_acmp *cmd; + const struct avb_packet_acmp *p = m; + struct avb_packet_acmp *cmd; if (be64toh(p->listener_guid) != server->entity_id) return 0; cmd = pending_new(acmp, PENDING_TALKER, now, - AVBTP_ACMP_TIMEOUT_CONNECT_TX_COMMAND_MS, m, len); + AVB_ACMP_TIMEOUT_CONNECT_TX_COMMAND_MS, m, len); if (cmd == NULL) return -errno; - AVBTP_PACKET_ACMP_SET_MESSAGE_TYPE(cmd, AVBTP_ACMP_MESSAGE_TYPE_CONNECT_TX_COMMAND); - AVBTP_PACKET_ACMP_SET_STATUS(cmd, AVBTP_ACMP_STATUS_SUCCESS); + AVB_PACKET_ACMP_SET_MESSAGE_TYPE(cmd, AVB_ACMP_MESSAGE_TYPE_CONNECT_TX_COMMAND); + AVB_PACKET_ACMP_SET_STATUS(cmd, AVB_ACMP_STATUS_SUCCESS); - return avbtp_server_send_packet(server, cmd->hdr.eth.dest, + return avb_server_send_packet(server, cmd->hdr.eth.dest, AVB_TSN_ETH, cmd, len); } @@ -261,21 +261,21 @@ static int handle_connect_rx_response(struct acmp *acmp, uint64_t now, const voi static int handle_disconnect_rx_command(struct acmp *acmp, uint64_t now, const void *m, int len) { struct server *server = acmp->server; - const struct avbtp_packet_acmp *p = m; - struct avbtp_packet_acmp *cmd; + const struct avb_packet_acmp *p = m; + struct avb_packet_acmp *cmd; if (be64toh(p->listener_guid) != server->entity_id) return 0; cmd = pending_new(acmp, PENDING_TALKER, now, - AVBTP_ACMP_TIMEOUT_DISCONNECT_TX_COMMAND_MS, m, len); + AVB_ACMP_TIMEOUT_DISCONNECT_TX_COMMAND_MS, m, len); if (cmd == NULL) return -errno; - AVBTP_PACKET_ACMP_SET_MESSAGE_TYPE(cmd, AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_TX_COMMAND); - AVBTP_PACKET_ACMP_SET_STATUS(cmd, AVBTP_ACMP_STATUS_SUCCESS); + AVB_PACKET_ACMP_SET_MESSAGE_TYPE(cmd, AVB_ACMP_MESSAGE_TYPE_DISCONNECT_TX_COMMAND); + AVB_PACKET_ACMP_SET_STATUS(cmd, AVB_ACMP_STATUS_SUCCESS); - return avbtp_server_send_packet(server, cmd->hdr.eth.dest, + return avb_server_send_packet(server, cmd->hdr.eth.dest, AVB_TSN_ETH, cmd, len); } @@ -285,20 +285,20 @@ static int handle_disconnect_rx_response(struct acmp *acmp, uint64_t now, const } static const struct msg_info msg_info[] = { - { AVBTP_ACMP_MESSAGE_TYPE_CONNECT_TX_COMMAND, "connect-tx-command", handle_connect_tx_command, }, - { AVBTP_ACMP_MESSAGE_TYPE_CONNECT_TX_RESPONSE, "connect-tx-response", handle_connect_tx_response, }, - { AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_TX_COMMAND, "disconnect-tx-command", handle_disconnect_tx_command, }, - { AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_TX_RESPONSE, "disconnect-tx-response", handle_disconnect_tx_response, }, - { AVBTP_ACMP_MESSAGE_TYPE_GET_TX_STATE_COMMAND, "get-tx-state-command", NULL, }, - { AVBTP_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE, "get-tx-state-response", NULL, }, - { AVBTP_ACMP_MESSAGE_TYPE_CONNECT_RX_COMMAND, "connect-rx-command", handle_connect_rx_command, }, - { AVBTP_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE, "connect-rx-response", handle_connect_rx_response, }, - { AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_RX_COMMAND, "disconnect-rx-command", handle_disconnect_rx_command, }, - { AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_RX_RESPONSE, "disconnect-rx-response", handle_disconnect_rx_response, }, - { AVBTP_ACMP_MESSAGE_TYPE_GET_RX_STATE_COMMAND, "get-rx-state-command", NULL, }, - { AVBTP_ACMP_MESSAGE_TYPE_GET_RX_STATE_RESPONSE, "get-rx-state-response", NULL, }, - { AVBTP_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_COMMAND, "get-tx-connection-command", NULL, }, - { AVBTP_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE, "get-tx-connection-response", NULL, }, + { AVB_ACMP_MESSAGE_TYPE_CONNECT_TX_COMMAND, "connect-tx-command", handle_connect_tx_command, }, + { AVB_ACMP_MESSAGE_TYPE_CONNECT_TX_RESPONSE, "connect-tx-response", handle_connect_tx_response, }, + { AVB_ACMP_MESSAGE_TYPE_DISCONNECT_TX_COMMAND, "disconnect-tx-command", handle_disconnect_tx_command, }, + { AVB_ACMP_MESSAGE_TYPE_DISCONNECT_TX_RESPONSE, "disconnect-tx-response", handle_disconnect_tx_response, }, + { AVB_ACMP_MESSAGE_TYPE_GET_TX_STATE_COMMAND, "get-tx-state-command", NULL, }, + { AVB_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE, "get-tx-state-response", NULL, }, + { AVB_ACMP_MESSAGE_TYPE_CONNECT_RX_COMMAND, "connect-rx-command", handle_connect_rx_command, }, + { AVB_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE, "connect-rx-response", handle_connect_rx_response, }, + { AVB_ACMP_MESSAGE_TYPE_DISCONNECT_RX_COMMAND, "disconnect-rx-command", handle_disconnect_rx_command, }, + { AVB_ACMP_MESSAGE_TYPE_DISCONNECT_RX_RESPONSE, "disconnect-rx-response", handle_disconnect_rx_response, }, + { AVB_ACMP_MESSAGE_TYPE_GET_RX_STATE_COMMAND, "get-rx-state-command", NULL, }, + { AVB_ACMP_MESSAGE_TYPE_GET_RX_STATE_RESPONSE, "get-rx-state-response", NULL, }, + { AVB_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_COMMAND, "get-tx-connection-command", NULL, }, + { AVB_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE, "get-tx-connection-response", NULL, }, }; static inline const struct msg_info *find_msg_info(uint16_t type, const char *name) @@ -316,7 +316,7 @@ static int acmp_message(void *data, uint64_t now, const void *message, int len) { struct acmp *acmp = data; struct server *server = acmp->server; - const struct avbtp_packet_acmp *p = message; + const struct avb_packet_acmp *p = message; const struct msg_info *info; int message_type; @@ -326,10 +326,10 @@ static int acmp_message(void *data, uint64_t now, const void *message, int len) memcmp(p->hdr.eth.dest, server->mac_addr, 6) != 0) return 0; - if (AVBTP_PACKET_GET_SUBTYPE(&p->hdr) != AVBTP_SUBTYPE_ACMP) + if (AVB_PACKET_GET_SUBTYPE(&p->hdr) != AVB_SUBTYPE_ACMP) return 0; - message_type = AVBTP_PACKET_ACMP_GET_MESSAGE_TYPE(p); + message_type = AVB_PACKET_ACMP_GET_MESSAGE_TYPE(p); info = find_msg_info(message_type, NULL); if (info == NULL) @@ -403,14 +403,14 @@ static int acmp_command(void *data, uint64_t now, const char *command, const cha } static const struct server_events server_events = { - AVBTP_VERSION_SERVER_EVENTS, + AVB_VERSION_SERVER_EVENTS, .destroy = acmp_destroy, .message = acmp_message, .periodic = acmp_periodic, .command = acmp_command }; -struct avbtp_acmp *avbtp_acmp_register(struct server *server) +struct avb_acmp *avb_acmp_register(struct server *server) { struct acmp *acmp; @@ -423,17 +423,17 @@ struct avbtp_acmp *avbtp_acmp_register(struct server *server) spa_list_init(&acmp->pending[PENDING_LISTENER]); spa_list_init(&acmp->pending[PENDING_CONTROLLER]); - acmp->listener_attr = avbtp_msrp_attribute_new(server->msrp, - AVBTP_MSRP_ATTRIBUTE_TYPE_LISTENER); - acmp->talker_attr = avbtp_msrp_attribute_new(server->msrp, - AVBTP_MSRP_ATTRIBUTE_TYPE_TALKER_ADVERTISE); + acmp->listener_attr = avb_msrp_attribute_new(server->msrp, + AVB_MSRP_ATTRIBUTE_TYPE_LISTENER); + acmp->talker_attr = avb_msrp_attribute_new(server->msrp, + AVB_MSRP_ATTRIBUTE_TYPE_TALKER_ADVERTISE); avdecc_server_add_listener(server, &acmp->server_listener, &server_events, acmp); - return (struct avbtp_acmp*)acmp; + return (struct avb_acmp*)acmp; } -void avbtp_acmp_unregister(struct avbtp_acmp *acmp) +void avb_acmp_unregister(struct avb_acmp *acmp) { acmp_destroy(acmp); } diff --git a/src/modules/module-avb/acmp.h b/src/modules/module-avb/acmp.h new file mode 100644 index 000000000..bcbdc0d92 --- /dev/null +++ b/src/modules/module-avb/acmp.h @@ -0,0 +1,99 @@ +/* AVB support + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AVB_ACMP_H +#define AVB_ACMP_H + +#include "packets.h" +#include "internal.h" + +#define AVB_ACMP_MESSAGE_TYPE_CONNECT_TX_COMMAND 0 +#define AVB_ACMP_MESSAGE_TYPE_CONNECT_TX_RESPONSE 1 +#define AVB_ACMP_MESSAGE_TYPE_DISCONNECT_TX_COMMAND 2 +#define AVB_ACMP_MESSAGE_TYPE_DISCONNECT_TX_RESPONSE 3 +#define AVB_ACMP_MESSAGE_TYPE_GET_TX_STATE_COMMAND 4 +#define AVB_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE 5 +#define AVB_ACMP_MESSAGE_TYPE_CONNECT_RX_COMMAND 6 +#define AVB_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE 7 +#define AVB_ACMP_MESSAGE_TYPE_DISCONNECT_RX_COMMAND 8 +#define AVB_ACMP_MESSAGE_TYPE_DISCONNECT_RX_RESPONSE 9 +#define AVB_ACMP_MESSAGE_TYPE_GET_RX_STATE_COMMAND 10 +#define AVB_ACMP_MESSAGE_TYPE_GET_RX_STATE_RESPONSE 11 +#define AVB_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_COMMAND 12 +#define AVB_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE 13 + +#define AVB_ACMP_STATUS_SUCCESS 0 +#define AVB_ACMP_STATUS_LISTENER_UNKNOWN_ID 1 +#define AVB_ACMP_STATUS_TALKER_UNKNOWN_ID 2 +#define AVB_ACMP_STATUS_TALKER_DEST_MAC_FAIL 3 +#define AVB_ACMP_STATUS_TALKER_NO_STREAM_INDEX 4 +#define AVB_ACMP_STATUS_TALKER_NO_BANDWIDTH 5 +#define AVB_ACMP_STATUS_TALKER_EXCLUSIVE 6 +#define AVB_ACMP_STATUS_LISTENER_TALKER_TIMEOUT 7 +#define AVB_ACMP_STATUS_LISTENER_EXCLUSIVE 8 +#define AVB_ACMP_STATUS_STATE_UNAVAILABLE 9 +#define AVB_ACMP_STATUS_NOT_CONNECTED 10 +#define AVB_ACMP_STATUS_NO_SUCH_CONNECTION 11 +#define AVB_ACMP_STATUS_COULD_NOT_SEND_MESSAGE 12 +#define AVB_ACMP_STATUS_TALKER_MISBEHAVING 13 +#define AVB_ACMP_STATUS_LISTENER_MISBEHAVING 14 +#define AVB_ACMP_STATUS_RESERVED 15 +#define AVB_ACMP_STATUS_CONTROLLER_NOT_AUTHORIZED 16 +#define AVB_ACMP_STATUS_INCOMPATIBLE_REQUEST 17 +#define AVB_ACMP_STATUS_LISTENER_INVALID_CONNECTION 18 +#define AVB_ACMP_STATUS_NOT_SUPPORTED 31 + +#define AVB_ACMP_TIMEOUT_CONNECT_TX_COMMAND_MS 2000 +#define AVB_ACMP_TIMEOUT_DISCONNECT_TX_COMMAND_MS 200 +#define AVB_ACMP_TIMEOUT_GET_TX_STATE_COMMAND 200 +#define AVB_ACMP_TIMEOUT_CONNECT_RX_COMMAND_MS 4500 +#define AVB_ACMP_TIMEOUT_DISCONNECT_RX_COMMAND_MS 500 +#define AVB_ACMP_TIMEOUT_GET_RX_STATE_COMMAND_MS 200 +#define AVB_ACMP_TIMEOUT_GET_TX_CONNECTION_COMMAND 200 + +struct avb_packet_acmp { + struct avb_packet_header hdr; + uint64_t stream_id; + uint64_t controller_guid; + uint64_t talker_guid; + uint64_t listener_guid; + uint16_t talker_unique_id; + uint16_t listener_unique_id; + char stream_dest_mac[6]; + uint16_t connection_count; + uint16_t sequence_id; + uint16_t flags; + uint16_t stream_vlan_id; + uint16_t reserved; +} __attribute__ ((__packed__)); + +#define AVB_PACKET_ACMP_SET_MESSAGE_TYPE(p,v) AVB_PACKET_SET_SUB1(&(p)->hdr, v) +#define AVB_PACKET_ACMP_SET_STATUS(p,v) AVB_PACKET_SET_SUB2(&(p)->hdr, v) + +#define AVB_PACKET_ACMP_GET_MESSAGE_TYPE(p) AVB_PACKET_GET_SUB1(&(p)->hdr) +#define AVB_PACKET_ACMP_GET_STATUS(p) AVB_PACKET_GET_SUB2(&(p)->hdr) + +struct avb_acmp *avb_acmp_register(struct server *server); + +#endif /* AVB_ACMP_H */ diff --git a/src/modules/module-avbtp/adp.c b/src/modules/module-avb/adp.c similarity index 77% rename from src/modules/module-avbtp/adp.c rename to src/modules/module-avb/adp.c index 77f2c095a..5827b5520 100644 --- a/src/modules/module-avbtp/adp.c +++ b/src/modules/module-avb/adp.c @@ -35,7 +35,7 @@ static const uint8_t mac[6] = AVB_BROADCAST_MAC; struct entity { struct spa_list link; - struct avbtp_packet_adp packet; + struct avb_packet_adp packet; uint64_t last_time; unsigned advertise:1; }; @@ -64,31 +64,31 @@ static void entity_free(struct entity *e) static int send_departing(struct adp *adp, uint64_t now, struct entity *e) { - AVBTP_PACKET_ADP_SET_MESSAGE_TYPE(&e->packet, AVBTP_ADP_MESSAGE_TYPE_ENTITY_DEPARTING); + AVB_PACKET_ADP_SET_MESSAGE_TYPE(&e->packet, AVB_ADP_MESSAGE_TYPE_ENTITY_DEPARTING); e->packet.available_index = htonl(adp->available_index++); - avbtp_server_send_packet(adp->server, mac, AVB_TSN_ETH, &e->packet, sizeof(e->packet)); + avb_server_send_packet(adp->server, mac, AVB_TSN_ETH, &e->packet, sizeof(e->packet)); e->last_time = now; return 0; } static int send_advertise(struct adp *adp, uint64_t now, struct entity *e) { - AVBTP_PACKET_ADP_SET_MESSAGE_TYPE(&e->packet, AVBTP_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE); + AVB_PACKET_ADP_SET_MESSAGE_TYPE(&e->packet, AVB_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE); e->packet.available_index = htonl(adp->available_index++); - avbtp_server_send_packet(adp->server, mac, AVB_TSN_ETH, &e->packet, sizeof(e->packet)); + avb_server_send_packet(adp->server, mac, AVB_TSN_ETH, &e->packet, sizeof(e->packet)); e->last_time = now; return 0; } static int send_discover(struct adp *adp, uint64_t entity_id) { - struct avbtp_packet_adp p; + struct avb_packet_adp p; spa_zero(p); - AVBTP_PACKET_SET_SUBTYPE(&p.hdr, AVBTP_SUBTYPE_ADP); - AVBTP_PACKET_SET_LENGTH(&p.hdr, AVBTP_ADP_CONTROL_DATA_LENGTH); - AVBTP_PACKET_ADP_SET_MESSAGE_TYPE(&p, AVBTP_ADP_MESSAGE_TYPE_ENTITY_DISCOVER); + AVB_PACKET_SET_SUBTYPE(&p.hdr, AVB_SUBTYPE_ADP); + AVB_PACKET_SET_LENGTH(&p.hdr, AVB_ADP_CONTROL_DATA_LENGTH); + AVB_PACKET_ADP_SET_MESSAGE_TYPE(&p, AVB_ADP_MESSAGE_TYPE_ENTITY_DISCOVER); p.entity_id = htonl(entity_id); - avbtp_server_send_packet(adp->server, mac, AVB_TSN_ETH, &p, sizeof(p)); + avb_server_send_packet(adp->server, mac, AVB_TSN_ETH, &p, sizeof(p)); return 0; } @@ -96,7 +96,7 @@ static int adp_message(void *data, uint64_t now, const void *message, int len) { struct adp *adp = data; struct server *server = adp->server; - const struct avbtp_packet_adp *p = message; + const struct avb_packet_adp *p = message; struct entity *e; int message_type; char buf[128]; @@ -108,17 +108,17 @@ static int adp_message(void *data, uint64_t now, const void *message, int len) memcmp(p->hdr.eth.dest, server->mac_addr, 6) != 0) return 0; - if (AVBTP_PACKET_GET_SUBTYPE(&p->hdr) != AVBTP_SUBTYPE_ADP || - AVBTP_PACKET_GET_LENGTH(&p->hdr) < AVBTP_ADP_CONTROL_DATA_LENGTH) + if (AVB_PACKET_GET_SUBTYPE(&p->hdr) != AVB_SUBTYPE_ADP || + AVB_PACKET_GET_LENGTH(&p->hdr) < AVB_ADP_CONTROL_DATA_LENGTH) return 0; - message_type = AVBTP_PACKET_ADP_GET_MESSAGE_TYPE(p); + message_type = AVB_PACKET_ADP_GET_MESSAGE_TYPE(p); entity_id = be64toh(p->entity_id); e = find_entity_by_id(adp, entity_id); switch (message_type) { - case AVBTP_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE: + case AVB_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE: if (e == NULL) { e = calloc(1, sizeof(*e)); if (e == NULL) @@ -127,23 +127,23 @@ static int adp_message(void *data, uint64_t now, const void *message, int len) e->packet = *p; spa_list_append(&adp->entities, &e->link); pw_log_info("entity %s available", - avbtp_utils_format_id(buf, sizeof(buf), entity_id)); + avb_utils_format_id(buf, sizeof(buf), entity_id)); } e->last_time = now; break; - case AVBTP_ADP_MESSAGE_TYPE_ENTITY_DEPARTING: + case AVB_ADP_MESSAGE_TYPE_ENTITY_DEPARTING: if (e != NULL) { pw_log_info("entity %s departing", - avbtp_utils_format_id(buf, sizeof(buf), entity_id)); + avb_utils_format_id(buf, sizeof(buf), entity_id)); entity_free(e); } break; - case AVBTP_ADP_MESSAGE_TYPE_ENTITY_DISCOVER: + case AVB_ADP_MESSAGE_TYPE_ENTITY_DISCOVER: if (entity_id == 0UL || (e != NULL && e->advertise && be64toh(e->packet.entity_id) == entity_id)) { pw_log_info("entity %s discover", - avbtp_utils_format_id(buf, sizeof(buf), entity_id)); + avb_utils_format_id(buf, sizeof(buf), entity_id)); send_discover(adp, entity_id); } break; @@ -166,13 +166,13 @@ static void check_timeout(struct adp *adp, uint64_t now) char buf[128]; spa_list_for_each_safe(e, t, &adp->entities, link) { - int valid_time = AVBTP_PACKET_ADP_GET_VALID_TIME(&e->packet); + int valid_time = AVB_PACKET_ADP_GET_VALID_TIME(&e->packet); if (e->last_time + (valid_time + 2) * SPA_NSEC_PER_SEC > now) continue; pw_log_info("entity %s timeout", - avbtp_utils_format_id(buf, sizeof(buf), + avb_utils_format_id(buf, sizeof(buf), be64toh(e->packet.entity_id))); if (e->advertise) @@ -183,7 +183,7 @@ static void check_timeout(struct adp *adp, uint64_t now) } static void check_readvertize(struct adp *adp, uint64_t now, struct entity *e) { - int valid_time = AVBTP_PACKET_ADP_GET_VALID_TIME(&e->packet); + int valid_time = AVB_PACKET_ADP_GET_VALID_TIME(&e->packet); char buf[128]; if (!e->advertise) @@ -193,7 +193,7 @@ static void check_readvertize(struct adp *adp, uint64_t now, struct entity *e) return; pw_log_debug("entity %s readvertise", - avbtp_utils_format_id(buf, sizeof(buf), + avb_utils_format_id(buf, sizeof(buf), be64toh(e->packet.entity_id))); send_advertise(adp, now, e); @@ -203,14 +203,14 @@ static int check_advertise(struct adp *adp, uint64_t now) { struct server *server = adp->server; const struct descriptor *d; - struct avbtp_aem_desc_entity *entity; - struct avbtp_aem_desc_avb_interface *avb_interface; + struct avb_aem_desc_entity *entity; + struct avb_aem_desc_avb_interface *avb_interface; struct entity *e; uint64_t entity_id; - struct avbtp_packet_adp *p; + struct avb_packet_adp *p; char buf[128]; - d = server_find_descriptor(server, AVBTP_AEM_DESC_ENTITY, 0); + d = server_find_descriptor(server, AVB_AEM_DESC_ENTITY, 0); if (d == NULL) return 0; @@ -223,11 +223,11 @@ static int check_advertise(struct adp *adp, uint64_t now) return 0; } - d = server_find_descriptor(server, AVBTP_AEM_DESC_AVB_INTERFACE, 0); + d = server_find_descriptor(server, AVB_AEM_DESC_AVB_INTERFACE, 0); avb_interface = d ? d->ptr : NULL; pw_log_info("entity %s advertise", - avbtp_utils_format_id(buf, sizeof(buf), entity_id)); + avb_utils_format_id(buf, sizeof(buf), entity_id)); e = calloc(1, sizeof(*e)); if (e == NULL) @@ -237,10 +237,10 @@ static int check_advertise(struct adp *adp, uint64_t now) e->last_time = now; p = &e->packet; - AVBTP_PACKET_SET_LENGTH(&p->hdr, AVBTP_ADP_CONTROL_DATA_LENGTH); - AVBTP_PACKET_SET_SUBTYPE(&p->hdr, AVBTP_SUBTYPE_ADP); - AVBTP_PACKET_ADP_SET_MESSAGE_TYPE(p, AVBTP_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE); - AVBTP_PACKET_ADP_SET_VALID_TIME(p, 10); + AVB_PACKET_SET_LENGTH(&p->hdr, AVB_ADP_CONTROL_DATA_LENGTH); + AVB_PACKET_SET_SUBTYPE(&p->hdr, AVB_SUBTYPE_ADP); + AVB_PACKET_ADP_SET_MESSAGE_TYPE(p, AVB_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE); + AVB_PACKET_ADP_SET_VALID_TIME(p, 10); p->entity_id = entity->entity_id; p->entity_model_id = entity->entity_model_id; @@ -303,7 +303,7 @@ static int do_discover(struct adp *adp, const char *args, FILE *out) continue; if (spa_streq(key, "entity-id")) { - if (avbtp_utils_parse_id(value, len, &id_val) >= 0) + if (avb_utils_parse_id(value, len, &id_val) >= 0) entity_id = id_val; } } @@ -332,14 +332,14 @@ static int adp_command(void *data, uint64_t now, const char *command, const char } static const struct server_events server_events = { - AVBTP_VERSION_SERVER_EVENTS, + AVB_VERSION_SERVER_EVENTS, .destroy = adp_destroy, .message = adp_message, .periodic = adp_periodic, .command = adp_command }; -struct avbtp_adp *avbtp_adp_register(struct server *server) +struct avb_adp *avb_adp_register(struct server *server) { struct adp *adp; @@ -352,10 +352,10 @@ struct avbtp_adp *avbtp_adp_register(struct server *server) avdecc_server_add_listener(server, &adp->server_listener, &server_events, adp); - return (struct avbtp_adp*)adp; + return (struct avb_adp*)adp; } -void avbtp_adp_unregister(struct avbtp_adp *adp) +void avb_adp_unregister(struct avb_adp *adp) { adp_destroy(adp); } diff --git a/src/modules/module-avb/adp.h b/src/modules/module-avb/adp.h new file mode 100644 index 000000000..c546088d8 --- /dev/null +++ b/src/modules/module-avb/adp.h @@ -0,0 +1,105 @@ +/* AVB support + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AVB_ADP_H +#define AVB_ADP_H + +#include "packets.h" +#include "internal.h" + +#define AVB_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE 0 +#define AVB_ADP_MESSAGE_TYPE_ENTITY_DEPARTING 1 +#define AVB_ADP_MESSAGE_TYPE_ENTITY_DISCOVER 2 + +#define AVB_ADP_ENTITY_CAPABILITY_EFU_MODE (1u<<0) +#define AVB_ADP_ENTITY_CAPABILITY_ADDRESS_ACCESS_SUPPORTED (1u<<1) +#define AVB_ADP_ENTITY_CAPABILITY_GATEWAY_ENTITY (1u<<2) +#define AVB_ADP_ENTITY_CAPABILITY_AEM_SUPPORTED (1u<<3) +#define AVB_ADP_ENTITY_CAPABILITY_LEGACY_AVC (1u<<4) +#define AVB_ADP_ENTITY_CAPABILITY_ASSOCIATION_ID_SUPPORTED (1u<<5) +#define AVB_ADP_ENTITY_CAPABILITY_ASSOCIATION_ID_VALID (1u<<6) +#define AVB_ADP_ENTITY_CAPABILITY_VENDOR_UNIQUE_SUPPORTED (1u<<7) +#define AVB_ADP_ENTITY_CAPABILITY_CLASS_A_SUPPORTED (1u<<8) +#define AVB_ADP_ENTITY_CAPABILITY_CLASS_B_SUPPORTED (1u<<9) +#define AVB_ADP_ENTITY_CAPABILITY_GPTP_SUPPORTED (1u<<10) +#define AVB_ADP_ENTITY_CAPABILITY_AEM_AUTHENTICATION_SUPPORTED (1u<<11) +#define AVB_ADP_ENTITY_CAPABILITY_AEM_AUTHENTICATION_REQUIRED (1u<<12) +#define AVB_ADP_ENTITY_CAPABILITY_AEM_PERSISTENT_ACQUIRE_SUPPORTED (1u<<13) +#define AVB_ADP_ENTITY_CAPABILITY_AEM_IDENTIFY_CONTROL_INDEX_VALID (1u<<14) +#define AVB_ADP_ENTITY_CAPABILITY_AEM_INTERFACE_INDEX_VALID (1u<<15) +#define AVB_ADP_ENTITY_CAPABILITY_GENERAL_CONTROLLER_IGNORE (1u<<16) +#define AVB_ADP_ENTITY_CAPABILITY_ENTITY_NOT_READY (1u<<17) + +#define AVB_ADP_TALKER_CAPABILITY_IMPLEMENTED (1u<<0) +#define AVB_ADP_TALKER_CAPABILITY_OTHER_SOURCE (1u<<9) +#define AVB_ADP_TALKER_CAPABILITY_CONTROL_SOURCE (1u<<10) +#define AVB_ADP_TALKER_CAPABILITY_MEDIA_CLOCK_SOURCE (1u<<11) +#define AVB_ADP_TALKER_CAPABILITY_SMPTE_SOURCE (1u<<12) +#define AVB_ADP_TALKER_CAPABILITY_MIDI_SOURCE (1u<<13) +#define AVB_ADP_TALKER_CAPABILITY_AUDIO_SOURCE (1u<<14) +#define AVB_ADP_TALKER_CAPABILITY_VIDEO_SOURCE (1u<<15) + +#define AVB_ADP_LISTENER_CAPABILITY_IMPLEMENTED (1u<<0) +#define AVB_ADP_LISTENER_CAPABILITY_OTHER_SINK (1u<<9) +#define AVB_ADP_LISTENER_CAPABILITY_CONTROL_SINK (1u<<10) +#define AVB_ADP_LISTENER_CAPABILITY_MEDIA_CLOCK_SINK (1u<<11) +#define AVB_ADP_LISTENER_CAPABILITY_SMPTE_SINK (1u<<12) +#define AVB_ADP_LISTENER_CAPABILITY_MIDI_SINK (1u<<13) +#define AVB_ADP_LISTENER_CAPABILITY_AUDIO_SINK (1u<<14) +#define AVB_ADP_LISTENER_CAPABILITY_VIDEO_SINK (1u<<15) + +#define AVB_ADP_CONTROLLER_CAPABILITY_IMPLEMENTED (1u<<0) +#define AVB_ADP_CONTROLLER_CAPABILITY_LAYER3_PROXY (1u<<1) + +#define AVB_ADP_CONTROL_DATA_LENGTH 56 + +struct avb_packet_adp { + struct avb_packet_header hdr; + uint64_t entity_id; + uint64_t entity_model_id; + uint32_t entity_capabilities; + uint16_t talker_stream_sources; + uint16_t talker_capabilities; + uint16_t listener_stream_sinks; + uint16_t listener_capabilities; + uint32_t controller_capabilities; + uint32_t available_index; + uint64_t gptp_grandmaster_id; + uint8_t gptp_domain_number; + uint8_t reserved0[3]; + uint16_t identify_control_index; + uint16_t interface_index; + uint64_t association_id; + uint32_t reserved1; +} __attribute__ ((__packed__)); + +#define AVB_PACKET_ADP_SET_MESSAGE_TYPE(p,v) AVB_PACKET_SET_SUB1(&(p)->hdr, v) +#define AVB_PACKET_ADP_SET_VALID_TIME(p,v) AVB_PACKET_SET_SUB2(&(p)->hdr, v) + +#define AVB_PACKET_ADP_GET_MESSAGE_TYPE(p) AVB_PACKET_GET_SUB1(&(p)->hdr) +#define AVB_PACKET_ADP_GET_VALID_TIME(p) AVB_PACKET_GET_SUB2(&(p)->hdr) + +struct avb_adp *avb_adp_register(struct server *server); + +#endif /* AVB_ADP_H */ diff --git a/src/modules/module-avbtp/aecp-aem-descriptors.h b/src/modules/module-avb/aecp-aem-descriptors.h similarity index 59% rename from src/modules/module-avbtp/aecp-aem-descriptors.h rename to src/modules/module-avb/aecp-aem-descriptors.h index e513a353b..101c33168 100644 --- a/src/modules/module-avbtp/aecp-aem-descriptors.h +++ b/src/modules/module-avb/aecp-aem-descriptors.h @@ -22,52 +22,52 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef AVBTP_AECP_AEM_DESCRIPTORS_H -#define AVBTP_AECP_AEM_DESCRIPTORS_H +#ifndef AVB_AECP_AEM_DESCRIPTORS_H +#define AVB_AECP_AEM_DESCRIPTORS_H #include "internal.h" -#define AVBTP_AEM_DESC_ENTITY 0x0000 -#define AVBTP_AEM_DESC_CONFIGURATION 0x0001 -#define AVBTP_AEM_DESC_AUDIO_UNIT 0x0002 -#define AVBTP_AEM_DESC_VIDEO_UNIT 0x0003 -#define AVBTP_AEM_DESC_SENSOR_UNIT 0x0004 -#define AVBTP_AEM_DESC_STREAM_INPUT 0x0005 -#define AVBTP_AEM_DESC_STREAM_OUTPUT 0x0006 -#define AVBTP_AEM_DESC_JACK_INPUT 0x0007 -#define AVBTP_AEM_DESC_JACK_OUTPUT 0x0008 -#define AVBTP_AEM_DESC_AVB_INTERFACE 0x0009 -#define AVBTP_AEM_DESC_CLOCK_SOURCE 0x000a -#define AVBTP_AEM_DESC_MEMORY_OBJECT 0x000b -#define AVBTP_AEM_DESC_LOCALE 0x000c -#define AVBTP_AEM_DESC_STRINGS 0x000d -#define AVBTP_AEM_DESC_STREAM_PORT_INPUT 0x000e -#define AVBTP_AEM_DESC_STREAM_PORT_OUTPUT 0x000f -#define AVBTP_AEM_DESC_EXTERNAL_PORT_INPUT 0x0010 -#define AVBTP_AEM_DESC_EXTERNAL_PORT_OUTPUT 0x0011 -#define AVBTP_AEM_DESC_INTERNAL_PORT_INPUT 0x0012 -#define AVBTP_AEM_DESC_INTERNAL_PORT_OUTPUT 0x0013 -#define AVBTP_AEM_DESC_AUDIO_CLUSTER 0x0014 -#define AVBTP_AEM_DESC_VIDEO_CLUSTER 0x0015 -#define AVBTP_AEM_DESC_SENSOR_CLUSTER 0x0016 -#define AVBTP_AEM_DESC_AUDIO_MAP 0x0017 -#define AVBTP_AEM_DESC_VIDEO_MAP 0x0018 -#define AVBTP_AEM_DESC_SENSOR_MAP 0x0019 -#define AVBTP_AEM_DESC_CONTROL 0x001a -#define AVBTP_AEM_DESC_SIGNAL_SELECTOR 0x001b -#define AVBTP_AEM_DESC_MIXER 0x001c -#define AVBTP_AEM_DESC_MATRIX 0x001d -#define AVBTP_AEM_DESC_MATRIX_SIGNAL 0x001e -#define AVBTP_AEM_DESC_SIGNAL_SPLITTER 0x001f -#define AVBTP_AEM_DESC_SIGNAL_COMBINER 0x0020 -#define AVBTP_AEM_DESC_SIGNAL_DEMULTIPLEXER 0x0021 -#define AVBTP_AEM_DESC_SIGNAL_MULTIPLEXER 0x0022 -#define AVBTP_AEM_DESC_SIGNAL_TRANSCODER 0x0023 -#define AVBTP_AEM_DESC_CLOCK_DOMAIN 0x0024 -#define AVBTP_AEM_DESC_CONTROL_BLOCK 0x0025 -#define AVBTP_AEM_DESC_INVALID 0xffff +#define AVB_AEM_DESC_ENTITY 0x0000 +#define AVB_AEM_DESC_CONFIGURATION 0x0001 +#define AVB_AEM_DESC_AUDIO_UNIT 0x0002 +#define AVB_AEM_DESC_VIDEO_UNIT 0x0003 +#define AVB_AEM_DESC_SENSOR_UNIT 0x0004 +#define AVB_AEM_DESC_STREAM_INPUT 0x0005 +#define AVB_AEM_DESC_STREAM_OUTPUT 0x0006 +#define AVB_AEM_DESC_JACK_INPUT 0x0007 +#define AVB_AEM_DESC_JACK_OUTPUT 0x0008 +#define AVB_AEM_DESC_AVB_INTERFACE 0x0009 +#define AVB_AEM_DESC_CLOCK_SOURCE 0x000a +#define AVB_AEM_DESC_MEMORY_OBJECT 0x000b +#define AVB_AEM_DESC_LOCALE 0x000c +#define AVB_AEM_DESC_STRINGS 0x000d +#define AVB_AEM_DESC_STREAM_PORT_INPUT 0x000e +#define AVB_AEM_DESC_STREAM_PORT_OUTPUT 0x000f +#define AVB_AEM_DESC_EXTERNAL_PORT_INPUT 0x0010 +#define AVB_AEM_DESC_EXTERNAL_PORT_OUTPUT 0x0011 +#define AVB_AEM_DESC_INTERNAL_PORT_INPUT 0x0012 +#define AVB_AEM_DESC_INTERNAL_PORT_OUTPUT 0x0013 +#define AVB_AEM_DESC_AUDIO_CLUSTER 0x0014 +#define AVB_AEM_DESC_VIDEO_CLUSTER 0x0015 +#define AVB_AEM_DESC_SENSOR_CLUSTER 0x0016 +#define AVB_AEM_DESC_AUDIO_MAP 0x0017 +#define AVB_AEM_DESC_VIDEO_MAP 0x0018 +#define AVB_AEM_DESC_SENSOR_MAP 0x0019 +#define AVB_AEM_DESC_CONTROL 0x001a +#define AVB_AEM_DESC_SIGNAL_SELECTOR 0x001b +#define AVB_AEM_DESC_MIXER 0x001c +#define AVB_AEM_DESC_MATRIX 0x001d +#define AVB_AEM_DESC_MATRIX_SIGNAL 0x001e +#define AVB_AEM_DESC_SIGNAL_SPLITTER 0x001f +#define AVB_AEM_DESC_SIGNAL_COMBINER 0x0020 +#define AVB_AEM_DESC_SIGNAL_DEMULTIPLEXER 0x0021 +#define AVB_AEM_DESC_SIGNAL_MULTIPLEXER 0x0022 +#define AVB_AEM_DESC_SIGNAL_TRANSCODER 0x0023 +#define AVB_AEM_DESC_CLOCK_DOMAIN 0x0024 +#define AVB_AEM_DESC_CONTROL_BLOCK 0x0025 +#define AVB_AEM_DESC_INVALID 0xffff -struct avbtp_aem_desc_entity { +struct avb_aem_desc_entity { uint64_t entity_id; uint64_t entity_model_id; uint32_t entity_capabilities; @@ -88,24 +88,24 @@ struct avbtp_aem_desc_entity { uint16_t current_configuration; } __attribute__ ((__packed__)); -struct avbtp_aem_desc_descriptor_count { +struct avb_aem_desc_descriptor_count { uint16_t descriptor_type; uint16_t descriptor_count; } __attribute__ ((__packed__)); -struct avbtp_aem_desc_configuration { +struct avb_aem_desc_configuration { char object_name[64]; uint16_t localized_description; uint16_t descriptor_counts_count; uint16_t descriptor_counts_offset; - struct avbtp_aem_desc_descriptor_count descriptor_counts[0]; + struct avb_aem_desc_descriptor_count descriptor_counts[0]; } __attribute__ ((__packed__)); -struct avbtp_aem_desc_sampling_rate { +struct avb_aem_desc_sampling_rate { uint32_t pull_frequency; } __attribute__ ((__packed__)); -struct avbtp_aem_desc_audio_unit { +struct avb_aem_desc_audio_unit { char object_name[64]; uint16_t localized_description; uint16_t clock_domain_index; @@ -144,21 +144,21 @@ struct avbtp_aem_desc_audio_unit { uint32_t current_sampling_rate; uint16_t sampling_rates_offset; uint16_t sampling_rates_count; - struct avbtp_aem_desc_sampling_rate sampling_rates[0]; + struct avb_aem_desc_sampling_rate sampling_rates[0]; } __attribute__ ((__packed__)); -#define AVBTP_AEM_DESC_STREAM_FLAG_SYNC_SOURCE (1u<<0) -#define AVBTP_AEM_DESC_STREAM_FLAG_CLASS_A (1u<<1) -#define AVBTP_AEM_DESC_STREAM_FLAG_CLASS_B (1u<<2) -#define AVBTP_AEM_DESC_STREAM_FLAG_SUPPORTS_ENCRYPTED (1u<<3) -#define AVBTP_AEM_DESC_STREAM_FLAG_PRIMARY_BACKUP_SUPPORTED (1u<<4) -#define AVBTP_AEM_DESC_STREAM_FLAG_PRIMARY_BACKUP_VALID (1u<<5) -#define AVBTP_AEM_DESC_STREAM_FLAG_SECONDARY_BACKUP_SUPPORTED (1u<<6) -#define AVBTP_AEM_DESC_STREAM_FLAG_SECONDARY_BACKUP_VALID (1u<<7) -#define AVBTP_AEM_DESC_STREAM_FLAG_TERTIARY_BACKUP_SUPPORTED (1u<<8) -#define AVBTP_AEM_DESC_STREAM_FLAG_TERTIARY_BACKUP_VALID (1u<<9) +#define AVB_AEM_DESC_STREAM_FLAG_SYNC_SOURCE (1u<<0) +#define AVB_AEM_DESC_STREAM_FLAG_CLASS_A (1u<<1) +#define AVB_AEM_DESC_STREAM_FLAG_CLASS_B (1u<<2) +#define AVB_AEM_DESC_STREAM_FLAG_SUPPORTS_ENCRYPTED (1u<<3) +#define AVB_AEM_DESC_STREAM_FLAG_PRIMARY_BACKUP_SUPPORTED (1u<<4) +#define AVB_AEM_DESC_STREAM_FLAG_PRIMARY_BACKUP_VALID (1u<<5) +#define AVB_AEM_DESC_STREAM_FLAG_SECONDARY_BACKUP_SUPPORTED (1u<<6) +#define AVB_AEM_DESC_STREAM_FLAG_SECONDARY_BACKUP_VALID (1u<<7) +#define AVB_AEM_DESC_STREAM_FLAG_TERTIARY_BACKUP_SUPPORTED (1u<<8) +#define AVB_AEM_DESC_STREAM_FLAG_TERTIARY_BACKUP_VALID (1u<<9) -struct avbtp_aem_desc_stream { +struct avb_aem_desc_stream { char object_name[64]; uint16_t localized_description; uint16_t clock_domain_index; @@ -179,11 +179,11 @@ struct avbtp_aem_desc_stream { uint64_t stream_formats[0]; } __attribute__ ((__packed__)); -#define AVBTP_AEM_DESC_AVB_INTERFACE_FLAG_GPTP_GRANDMASTER_SUPPORTED (1<<0) -#define AVBTP_AEM_DESC_AVB_INTERFACE_FLAG_GPTP_SUPPORTED (1<<1) -#define AVBTP_AEM_DESC_AVB_INTERFACE_FLAG_SRP_SUPPORTED (1<<2) +#define AVB_AEM_DESC_AVB_INTERFACE_FLAG_GPTP_GRANDMASTER_SUPPORTED (1<<0) +#define AVB_AEM_DESC_AVB_INTERFACE_FLAG_GPTP_SUPPORTED (1<<1) +#define AVB_AEM_DESC_AVB_INTERFACE_FLAG_SRP_SUPPORTED (1<<2) -struct avbtp_aem_desc_avb_interface { +struct avb_aem_desc_avb_interface { char object_name[64]; uint16_t localized_description; uint8_t mac_address[6]; @@ -201,13 +201,13 @@ struct avbtp_aem_desc_avb_interface { uint16_t port_number; } __attribute__ ((__packed__)); -#define AVBTP_AEM_DESC_CLOCK_SOURCE_TYPE_INTERNAL 0x0000 -#define AVBTP_AEM_DESC_CLOCK_SOURCE_TYPE_EXTERNAL 0x0001 -#define AVBTP_AEM_DESC_CLOCK_SOURCE_TYPE_INPUT_STREAM 0x0002 -#define AVBTP_AEM_DESC_CLOCK_SOURCE_TYPE_MEDIA_CLOCK_STREAM 0x0003 -#define AVBTP_AEM_DESC_CLOCK_SOURCE_TYPE_EXPANSION 0xffff +#define AVB_AEM_DESC_CLOCK_SOURCE_TYPE_INTERNAL 0x0000 +#define AVB_AEM_DESC_CLOCK_SOURCE_TYPE_EXTERNAL 0x0001 +#define AVB_AEM_DESC_CLOCK_SOURCE_TYPE_INPUT_STREAM 0x0002 +#define AVB_AEM_DESC_CLOCK_SOURCE_TYPE_MEDIA_CLOCK_STREAM 0x0003 +#define AVB_AEM_DESC_CLOCK_SOURCE_TYPE_EXPANSION 0xffff -struct avbtp_aem_desc_clock_source { +struct avb_aem_desc_clock_source { char object_name[64]; uint16_t localized_description; uint16_t clock_source_flags; @@ -217,13 +217,13 @@ struct avbtp_aem_desc_clock_source { uint16_t clock_source_location_index; } __attribute__ ((__packed__)); -struct avbtp_aem_desc_locale { +struct avb_aem_desc_locale { char locale_identifier[64]; uint16_t number_of_strings; uint16_t base_strings; } __attribute__ ((__packed__)); -struct avbtp_aem_desc_strings { +struct avb_aem_desc_strings { char string_0[64]; char string_1[64]; char string_2[64]; @@ -233,7 +233,7 @@ struct avbtp_aem_desc_strings { char string_6[64]; } __attribute__ ((__packed__)); -struct avbtp_aem_desc_stream_port { +struct avb_aem_desc_stream_port { uint16_t clock_domain_index; uint16_t port_flags; uint16_t number_of_controls; @@ -244,4 +244,4 @@ struct avbtp_aem_desc_stream_port { uint16_t base_map; } __attribute__ ((__packed__)); -#endif /* AVBTP_AECP_AEM_DESCRIPTORS_H */ +#endif /* AVB_AECP_AEM_DESCRIPTORS_H */ diff --git a/src/modules/module-avb/aecp-aem.c b/src/modules/module-avb/aecp-aem.c new file mode 100644 index 000000000..6900648f7 --- /dev/null +++ b/src/modules/module-avb/aecp-aem.c @@ -0,0 +1,283 @@ +/* AVB support + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "aecp-aem.h" +#include "aecp-aem-descriptors.h" + +static int reply_status(struct aecp *aecp, int status, const void *m, int len) +{ + struct server *server = aecp->server; + uint8_t buf[len]; + struct avb_packet_aecp_header *reply = (struct avb_packet_aecp_header*)buf; + + memcpy(reply, m, len); + AVB_PACKET_AECP_SET_MESSAGE_TYPE(reply, AVB_AECP_MESSAGE_TYPE_AEM_RESPONSE); + AVB_PACKET_AECP_SET_STATUS(reply, status); + + return avb_server_send_packet(server, reply->hdr.eth.src, + AVB_TSN_ETH, reply, len); +} + +static int reply_not_implemented(struct aecp *aecp, const void *m, int len) +{ + return reply_status(aecp, AVB_AECP_AEM_STATUS_NOT_IMPLEMENTED, m, len); +} + +static int reply_success(struct aecp *aecp, const void *m, int len) +{ + return reply_status(aecp, AVB_AECP_AEM_STATUS_SUCCESS, m, len); +} + +/* ACQUIRE_ENTITY */ +static int handle_acquire_entity(struct aecp *aecp, const void *m, int len) +{ + struct server *server = aecp->server; + const struct avb_packet_aecp_aem *p = m; + const struct avb_packet_aecp_aem_acquire *ae; + const struct descriptor *desc; + uint16_t desc_type, desc_id; + + ae = (const struct avb_packet_aecp_aem_acquire*)p->payload; + + desc_type = ntohs(ae->descriptor_type); + desc_id = ntohs(ae->descriptor_id); + + desc = server_find_descriptor(server, desc_type, desc_id); + if (desc == NULL) + return reply_status(aecp, AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len); + + if (desc_type != AVB_AEM_DESC_ENTITY || desc_id != 0) + return reply_not_implemented(aecp, m, len); + + return reply_success(aecp, m, len); +} + +/* LOCK_ENTITY */ +static int handle_lock_entity(struct aecp *aecp, const void *m, int len) +{ + struct server *server = aecp->server; + const struct avb_packet_aecp_aem *p = m; + const struct avb_packet_aecp_aem_acquire *ae; + const struct descriptor *desc; + uint16_t desc_type, desc_id; + + ae = (const struct avb_packet_aecp_aem_acquire*)p->payload; + + desc_type = ntohs(ae->descriptor_type); + desc_id = ntohs(ae->descriptor_id); + + desc = server_find_descriptor(server, desc_type, desc_id); + if (desc == NULL) + return reply_status(aecp, AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len); + + if (desc_type != AVB_AEM_DESC_ENTITY || desc_id != 0) + return reply_not_implemented(aecp, m, len); + + return reply_success(aecp, m, len); +} + +/* READ_DESCRIPTOR */ +static int handle_read_descriptor(struct aecp *aecp, const void *m, int len) +{ + struct server *server = aecp->server; + const struct avb_packet_aecp_aem *p = m; + struct avb_packet_aecp_aem *reply; + const struct avb_packet_aecp_aem_read_descriptor *rd; + uint16_t desc_type, desc_id; + const struct descriptor *desc; + uint8_t buf[2048]; + size_t size, psize; + + rd = (struct avb_packet_aecp_aem_read_descriptor*)p->payload; + + desc_type = ntohs(rd->descriptor_type); + desc_id = ntohs(rd->descriptor_id); + + pw_log_info("descriptor type:%04x index:%d", desc_type, desc_id); + + desc = server_find_descriptor(server, desc_type, desc_id); + if (desc == NULL) + return reply_status(aecp, AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len); + + memcpy(buf, p, len); + + psize = sizeof(*rd); + size = sizeof(*reply) + psize; + + memcpy(buf + size, desc->ptr, desc->size); + size += desc->size; + psize += desc->size; + + reply = (struct avb_packet_aecp_aem*)buf; + AVB_PACKET_AECP_SET_MESSAGE_TYPE(&reply->aecp, AVB_AECP_MESSAGE_TYPE_AEM_RESPONSE); + AVB_PACKET_AECP_SET_STATUS(&reply->aecp, AVB_AECP_AEM_STATUS_SUCCESS); + AVB_PACKET_SET_LENGTH(&reply->aecp.hdr, psize + 12); + + return avb_server_send_packet(server, reply->aecp.hdr.eth.src, + AVB_TSN_ETH, reply, size); +} + +/* GET_AVB_INFO */ +static int handle_get_avb_info(struct aecp *aecp, const void *m, int len) +{ + struct server *server = aecp->server; + const struct avb_packet_aecp_aem *p = m; + struct avb_packet_aecp_aem *reply; + struct avb_packet_aecp_aem_get_avb_info *i; + struct avb_aem_desc_avb_interface *avb_interface; + uint16_t desc_type, desc_id; + const struct descriptor *desc; + uint8_t buf[2048]; + size_t size, psize; + + i = (struct avb_packet_aecp_aem_get_avb_info*)p->payload; + + desc_type = ntohs(i->descriptor_type); + desc_id = ntohs(i->descriptor_id); + + desc = server_find_descriptor(server, desc_type, desc_id); + if (desc == NULL) + return reply_status(aecp, AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len); + + if (desc_type != AVB_AEM_DESC_AVB_INTERFACE || desc_id != 0) + return reply_not_implemented(aecp, m, len); + + avb_interface = desc->ptr; + + memcpy(buf, p, len); + + psize = sizeof(*i); + size = sizeof(*reply) + psize; + + reply = (struct avb_packet_aecp_aem *)buf; + AVB_PACKET_AECP_SET_MESSAGE_TYPE(&reply->aecp, AVB_AECP_MESSAGE_TYPE_AEM_RESPONSE); + AVB_PACKET_AECP_SET_STATUS(&reply->aecp, AVB_AECP_AEM_STATUS_SUCCESS); + AVB_PACKET_SET_LENGTH(&reply->aecp.hdr, psize + 12); + + i = (struct avb_packet_aecp_aem_get_avb_info*)reply->payload; + i->gptp_grandmaster_id = avb_interface->clock_identity; + i->propagation_delay = htonl(0); + i->gptp_domain_number = avb_interface->domain_number; + i->flags = 0; + i->msrp_mappings_count = htons(0); + + return avb_server_send_packet(server, reply->aecp.hdr.eth.src, + AVB_TSN_ETH, reply, size); +} + +/* AEM_COMMAND */ +struct cmd_info { + uint16_t type; + const char *name; + int (*handle) (struct aecp *aecp, const void *p, int len); +}; + +static const struct cmd_info cmd_info[] = { + { AVB_AECP_AEM_CMD_ACQUIRE_ENTITY, "acquire-entity", handle_acquire_entity, }, + { AVB_AECP_AEM_CMD_LOCK_ENTITY, "lock-entity", handle_lock_entity, }, + { AVB_AECP_AEM_CMD_ENTITY_AVAILABLE, "entity-available", NULL, }, + { AVB_AECP_AEM_CMD_CONTROLLER_AVAILABLE, "controller-available", NULL, }, + { AVB_AECP_AEM_CMD_READ_DESCRIPTOR, "read-descriptor", handle_read_descriptor, }, + { AVB_AECP_AEM_CMD_WRITE_DESCRIPTOR, "write-descriptor", NULL, }, + { AVB_AECP_AEM_CMD_SET_CONFIGURATION, "set-configuration", NULL, }, + { AVB_AECP_AEM_CMD_GET_CONFIGURATION, "get-configuration", NULL, }, + { AVB_AECP_AEM_CMD_SET_STREAM_FORMAT, "set-stream-format", NULL, }, + { AVB_AECP_AEM_CMD_GET_STREAM_FORMAT, "get-stream-format", NULL, }, + { AVB_AECP_AEM_CMD_SET_VIDEO_FORMAT, "set-video-format", NULL, }, + { AVB_AECP_AEM_CMD_GET_VIDEO_FORMAT, "get-video-format", NULL, }, + { AVB_AECP_AEM_CMD_SET_SENSOR_FORMAT, "set-sensor-format", NULL, }, + { AVB_AECP_AEM_CMD_GET_SENSOR_FORMAT, "get-sensor-format", NULL, }, + { AVB_AECP_AEM_CMD_SET_STREAM_INFO, "set-stream-info", NULL, }, + { AVB_AECP_AEM_CMD_GET_STREAM_INFO, "get-stream-info", NULL, }, + { AVB_AECP_AEM_CMD_SET_NAME, "set-name", NULL, }, + { AVB_AECP_AEM_CMD_GET_NAME, "get-name", NULL, }, + { AVB_AECP_AEM_CMD_SET_ASSOCIATION_ID, "set-association-id", NULL, }, + { AVB_AECP_AEM_CMD_GET_ASSOCIATION_ID, "get-association-id", NULL, }, + { AVB_AECP_AEM_CMD_SET_SAMPLING_RATE, "set-sampling-rate", NULL, }, + { AVB_AECP_AEM_CMD_GET_SAMPLING_RATE, "get-sampling-rate", NULL, }, + { AVB_AECP_AEM_CMD_SET_CLOCK_SOURCE, "set-clock-source", NULL, }, + { AVB_AECP_AEM_CMD_GET_CLOCK_SOURCE, "get-clock-source", NULL, }, + { AVB_AECP_AEM_CMD_SET_CONTROL, "set-control", NULL, }, + { AVB_AECP_AEM_CMD_GET_CONTROL, "get-control", NULL, }, + { AVB_AECP_AEM_CMD_INCREMENT_CONTROL, "increment-control", NULL, }, + { AVB_AECP_AEM_CMD_DECREMENT_CONTROL, "decrement-control", NULL, }, + { AVB_AECP_AEM_CMD_SET_SIGNAL_SELECTOR, "set-signal-selector", NULL, }, + { AVB_AECP_AEM_CMD_GET_SIGNAL_SELECTOR, "get-signal-selector", NULL, }, + { AVB_AECP_AEM_CMD_SET_MIXER, "set-mixer", NULL, }, + { AVB_AECP_AEM_CMD_GET_MIXER, "get-mixer", NULL, }, + { AVB_AECP_AEM_CMD_SET_MATRIX, "set-matrix", NULL, }, + { AVB_AECP_AEM_CMD_GET_MATRIX, "get-matrix", NULL, }, + { AVB_AECP_AEM_CMD_START_STREAMING, "start-streaming", NULL, }, + { AVB_AECP_AEM_CMD_STOP_STREAMING, "stop-streaming", NULL, }, + { AVB_AECP_AEM_CMD_REGISTER_UNSOLICITED_NOTIFICATION, "register-unsolicited-notification", NULL, }, + { AVB_AECP_AEM_CMD_DEREGISTER_UNSOLICITED_NOTIFICATION, "deregister-unsolicited-notification", NULL, }, + { AVB_AECP_AEM_CMD_IDENTIFY_NOTIFICATION, "identify-notification", NULL, }, + { AVB_AECP_AEM_CMD_GET_AVB_INFO, "get-avb-info", handle_get_avb_info, }, + { AVB_AECP_AEM_CMD_GET_AS_PATH, "get-as-path", NULL, }, + { AVB_AECP_AEM_CMD_GET_COUNTERS, "get-counters", NULL, }, + { AVB_AECP_AEM_CMD_REBOOT, "reboot", NULL, }, + { AVB_AECP_AEM_CMD_GET_AUDIO_MAP, "get-audio-map", NULL, }, + { AVB_AECP_AEM_CMD_ADD_AUDIO_MAPPINGS, "add-audio-mappings", NULL, }, + { AVB_AECP_AEM_CMD_REMOVE_AUDIO_MAPPINGS, "remove-audio-mappings", NULL, }, + { AVB_AECP_AEM_CMD_GET_VIDEO_MAP, "get-video-map", NULL, }, + { AVB_AECP_AEM_CMD_ADD_VIDEO_MAPPINGS, "add-video-mappings", NULL, }, + { AVB_AECP_AEM_CMD_REMOVE_VIDEO_MAPPINGS, "remove-video-mappings", NULL, }, + { AVB_AECP_AEM_CMD_GET_SENSOR_MAP, "get-sensor-map", NULL, } +}; + +static inline const struct cmd_info *find_cmd_info(uint16_t type, const char *name) +{ + uint32_t i; + for (i = 0; i < SPA_N_ELEMENTS(cmd_info); i++) { + if ((name == NULL && type == cmd_info[i].type) || + (name != NULL && spa_streq(name, cmd_info[i].name))) + return &cmd_info[i]; + } + return NULL; +} + +int avb_aecp_aem_handle_command(struct aecp *aecp, const void *m, int len) +{ + const struct avb_packet_aecp_aem *p = m; + uint16_t cmd_type; + const struct cmd_info *info; + + cmd_type = AVB_PACKET_AEM_GET_COMMAND_TYPE(p); + + info = find_cmd_info(cmd_type, NULL); + if (info == NULL) + return reply_not_implemented(aecp, m, len); + + pw_log_info("aem command %s", info->name); + + if (info->handle == NULL) + return reply_not_implemented(aecp, m, len); + + return info->handle(aecp, m, len); +} + +int avb_aecp_aem_handle_response(struct aecp *aecp, const void *m, int len) +{ + return 0; +} diff --git a/src/modules/module-avb/aecp-aem.h b/src/modules/module-avb/aecp-aem.h new file mode 100644 index 000000000..dcf26b5b7 --- /dev/null +++ b/src/modules/module-avb/aecp-aem.h @@ -0,0 +1,345 @@ +/* AVB support + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AVB_AEM_H +#define AVB_AEM_H + +#include "aecp.h" + +#define AVB_AECP_AEM_STATUS_SUCCESS 0 +#define AVB_AECP_AEM_STATUS_NOT_IMPLEMENTED 1 +#define AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR 2 +#define AVB_AECP_AEM_STATUS_ENTITY_LOCKED 3 +#define AVB_AECP_AEM_STATUS_ENTITY_ACQUIRED 4 +#define AVB_AECP_AEM_STATUS_NOT_AUTHENTICATED 5 +#define AVB_AECP_AEM_STATUS_AUTHENTICATION_DISABLED 6 +#define AVB_AECP_AEM_STATUS_BAD_ARGUMENTS 7 +#define AVB_AECP_AEM_STATUS_NO_RESOURCES 8 +#define AVB_AECP_AEM_STATUS_IN_PROGRESS 9 +#define AVB_AECP_AEM_STATUS_ENTITY_MISBEHAVING 10 +#define AVB_AECP_AEM_STATUS_NOT_SUPPORTED 11 +#define AVB_AECP_AEM_STATUS_STREAM_IS_RUNNING 12 + +#define AVB_AECP_AEM_CMD_ACQUIRE_ENTITY 0x0000 +#define AVB_AECP_AEM_CMD_LOCK_ENTITY 0x0001 +#define AVB_AECP_AEM_CMD_ENTITY_AVAILABLE 0x0002 +#define AVB_AECP_AEM_CMD_CONTROLLER_AVAILABLE 0x0003 +#define AVB_AECP_AEM_CMD_READ_DESCRIPTOR 0x0004 +#define AVB_AECP_AEM_CMD_WRITE_DESCRIPTOR 0x0005 +#define AVB_AECP_AEM_CMD_SET_CONFIGURATION 0x0006 +#define AVB_AECP_AEM_CMD_GET_CONFIGURATION 0x0007 +#define AVB_AECP_AEM_CMD_SET_STREAM_FORMAT 0x0008 +#define AVB_AECP_AEM_CMD_GET_STREAM_FORMAT 0x0009 +#define AVB_AECP_AEM_CMD_SET_VIDEO_FORMAT 0x000a +#define AVB_AECP_AEM_CMD_GET_VIDEO_FORMAT 0x000b +#define AVB_AECP_AEM_CMD_SET_SENSOR_FORMAT 0x000c +#define AVB_AECP_AEM_CMD_GET_SENSOR_FORMAT 0x000d +#define AVB_AECP_AEM_CMD_SET_STREAM_INFO 0x000e +#define AVB_AECP_AEM_CMD_GET_STREAM_INFO 0x000f +#define AVB_AECP_AEM_CMD_SET_NAME 0x0010 +#define AVB_AECP_AEM_CMD_GET_NAME 0x0011 +#define AVB_AECP_AEM_CMD_SET_ASSOCIATION_ID 0x0012 +#define AVB_AECP_AEM_CMD_GET_ASSOCIATION_ID 0x0013 +#define AVB_AECP_AEM_CMD_SET_SAMPLING_RATE 0x0014 +#define AVB_AECP_AEM_CMD_GET_SAMPLING_RATE 0x0015 +#define AVB_AECP_AEM_CMD_SET_CLOCK_SOURCE 0x0016 +#define AVB_AECP_AEM_CMD_GET_CLOCK_SOURCE 0x0017 +#define AVB_AECP_AEM_CMD_SET_CONTROL 0x0018 +#define AVB_AECP_AEM_CMD_GET_CONTROL 0x0019 +#define AVB_AECP_AEM_CMD_INCREMENT_CONTROL 0x001a +#define AVB_AECP_AEM_CMD_DECREMENT_CONTROL 0x001b +#define AVB_AECP_AEM_CMD_SET_SIGNAL_SELECTOR 0x001c +#define AVB_AECP_AEM_CMD_GET_SIGNAL_SELECTOR 0x001d +#define AVB_AECP_AEM_CMD_SET_MIXER 0x001e +#define AVB_AECP_AEM_CMD_GET_MIXER 0x001f +#define AVB_AECP_AEM_CMD_SET_MATRIX 0x0020 +#define AVB_AECP_AEM_CMD_GET_MATRIX 0x0021 +#define AVB_AECP_AEM_CMD_START_STREAMING 0x0022 +#define AVB_AECP_AEM_CMD_STOP_STREAMING 0x0023 +#define AVB_AECP_AEM_CMD_REGISTER_UNSOLICITED_NOTIFICATION 0x0024 +#define AVB_AECP_AEM_CMD_DEREGISTER_UNSOLICITED_NOTIFICATION 0x0025 +#define AVB_AECP_AEM_CMD_IDENTIFY_NOTIFICATION 0x0026 +#define AVB_AECP_AEM_CMD_GET_AVB_INFO 0x0027 +#define AVB_AECP_AEM_CMD_GET_AS_PATH 0x0028 +#define AVB_AECP_AEM_CMD_GET_COUNTERS 0x0029 +#define AVB_AECP_AEM_CMD_REBOOT 0x002a +#define AVB_AECP_AEM_CMD_GET_AUDIO_MAP 0x002b +#define AVB_AECP_AEM_CMD_ADD_AUDIO_MAPPINGS 0x002c +#define AVB_AECP_AEM_CMD_REMOVE_AUDIO_MAPPINGS 0x002d +#define AVB_AECP_AEM_CMD_GET_VIDEO_MAP 0x002e +#define AVB_AECP_AEM_CMD_ADD_VIDEO_MAPPINGS 0x002f +#define AVB_AECP_AEM_CMD_REMOVE_VIDEO_MAPPINGS 0x0030 +#define AVB_AECP_AEM_CMD_GET_SENSOR_MAP 0x0031 +#define AVB_AECP_AEM_CMD_ADD_SENSOR_MAPPINGS 0x0032 +#define AVB_AECP_AEM_CMD_REMOVE_SENSOR_MAPPINGS 0x0033 +#define AVB_AECP_AEM_CMD_START_OPERATION 0x0034 +#define AVB_AECP_AEM_CMD_ABORT_OPERATION 0x0035 +#define AVB_AECP_AEM_CMD_OPERATION_STATUS 0x0036 +#define AVB_AECP_AEM_CMD_AUTH_ADD_KEY 0x0037 +#define AVB_AECP_AEM_CMD_AUTH_DELETE_KEY 0x0038 +#define AVB_AECP_AEM_CMD_AUTH_GET_KEY_LIST 0x0039 +#define AVB_AECP_AEM_CMD_AUTH_GET_KEY 0x003a +#define AVB_AECP_AEM_CMD_AUTH_ADD_KEY_TO_CHAIN 0x003b +#define AVB_AECP_AEM_CMD_AUTH_DELETE_KEY_FROM_CHAIN 0x003c +#define AVB_AECP_AEM_CMD_AUTH_GET_KEYCHAIN_LIST 0x003d +#define AVB_AECP_AEM_CMD_AUTH_GET_IDENTITY 0x003e +#define AVB_AECP_AEM_CMD_AUTH_ADD_TOKEN 0x003f +#define AVB_AECP_AEM_CMD_AUTH_DELETE_TOKEN 0x0040 +#define AVB_AECP_AEM_CMD_AUTHENTICATE 0x0041 +#define AVB_AECP_AEM_CMD_DEAUTHENTICATE 0x0042 +#define AVB_AECP_AEM_CMD_ENABLE_TRANSPORT_SECURITY 0x0043 +#define AVB_AECP_AEM_CMD_DISABLE_TRANSPORT_SECURITY 0x0044 +#define AVB_AECP_AEM_CMD_ENABLE_STREAM_ENCRYPTION 0x0045 +#define AVB_AECP_AEM_CMD_DISABLE_STREAM_ENCRYPTION 0x0046 +#define AVB_AECP_AEM_CMD_SET_MEMORY_OBJECT_LENGTH 0x0047 +#define AVB_AECP_AEM_CMD_GET_MEMORY_OBJECT_LENGTH 0x0048 +#define AVB_AECP_AEM_CMD_SET_STREAM_BACKUP 0x0049 +#define AVB_AECP_AEM_CMD_GET_STREAM_BACKUP 0x004a +#define AVB_AECP_AEM_CMD_EXPANSION 0x7fff + +#define AVB_AEM_ACQUIRE_ENTITY_PERSISTENT_FLAG (1<<0) + +struct avb_packet_aecp_aem_acquire { + uint32_t flags; + uint64_t owner_guid; + uint16_t descriptor_type; + uint16_t descriptor_id; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_lock { + uint32_t flags; + uint64_t locked_guid; + uint16_t descriptor_type; + uint16_t descriptor_id; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_read_descriptor { + uint16_t configuration; + uint8_t reserved[2]; + uint16_t descriptor_type; + uint16_t descriptor_id; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_configuration { + uint16_t reserved; + uint16_t configuration_index; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_stream_format { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint64_t stream_format; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_video_format { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint32_t format_specific; + uint16_t aspect_ratio; + uint16_t color_space; + uint32_t frame_size; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_sensor_format { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint64_t sensor_format; +} __attribute__ ((__packed__)); + + +#define AVB_AEM_STREAM_INFO_FLAG_CLASS_B (1u<<0) +#define AVB_AEM_STREAM_INFO_FLAG_FAST_CONNECT (1u<<1) +#define AVB_AEM_STREAM_INFO_FLAG_SAVED_STATE (1u<<2) +#define AVB_AEM_STREAM_INFO_FLAG_STREAMING_WAIT (1u<<3) +#define AVB_AEM_STREAM_INFO_FLAG_ENCRYPTED_PDU (1u<<4) +#define AVB_AEM_STREAM_INFO_FLAG_STREAM_VLAN_ID_VALID (1u<<25) +#define AVB_AEM_STREAM_INFO_FLAG_CONNECTED (1u<<26) +#define AVB_AEM_STREAM_INFO_FLAG_MSRP_FAILURE_VALID (1u<<27) +#define AVB_AEM_STREAM_INFO_FLAG_STREAM_DEST_MAC_VALID (1u<<28) +#define AVB_AEM_STREAM_INFO_FLAG_MSRP_ACC_LAT_VALID (1u<<29) +#define AVB_AEM_STREAM_INFO_FLAG_STREAM_ID_VALID (1u<<30) +#define AVB_AEM_STREAM_INFO_FLAG_STREAM_FORMAT_VALID (1u<<31) + +struct avb_packet_aecp_aem_setget_stream_info { + uint16_t descriptor_type; + uint16_t descriptor_index; + uint32_t aem_stream_info_flags; + uint64_t stream_format; + uint64_t stream_id; + uint32_t msrp_accumulated_latency; + uint8_t stream_dest_mac[6]; + uint8_t msrp_failure_code; + uint8_t reserved; + uint64_t msrp_failure_bridge_id; + uint16_t stream_vlan_id; + uint16_t reserved2; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_name { + uint16_t descriptor_type; + uint16_t descriptor_index; + uint16_t name_index; + uint16_t configuration_index; + char name[64]; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_association_id { + uint16_t descriptor_type; + uint16_t descriptor_index; + uint64_t association_id; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_sampling_rate { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint32_t sampling_rate; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_clock_source { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint16_t clock_source_index; + uint16_t reserved; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_control { + uint16_t descriptor_type; + uint16_t descriptor_id; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_incdec_control { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint16_t index_count; + uint16_t reserved; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_signal_selector { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint16_t signal_type; + uint16_t signal_index; + uint16_t signal_output; + uint16_t reserved; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_mixer { + uint16_t descriptor_type; + uint16_t descriptor_id; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_setget_matrix { + uint16_t descriptor_type; + uint16_t descriptor_index; + uint16_t matrix_column; + uint16_t matrix_row; + uint16_t region_width; + uint16_t region_height; + uint16_t rep_direction_value_count; + uint16_t item_offset; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_startstop_streaming { + uint16_t descriptor_type; + uint16_t descriptor_id; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_identify_notification { + uint16_t descriptor_type; + uint16_t descriptor_id; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_msrp_mapping { + uint8_t traffic_class; + uint8_t priority; + uint16_t vlan_id; +} __attribute__ ((__packed__)); + +#define AVB_AEM_AVB_INFO_FLAG_GPTP_GRANDMASTER_SUPPORTED (1u<<0) +#define AVB_AEM_AVB_INFO_FLAG_GPTP_ENABLED (1u<<1) +#define AVB_AEM_AVB_INFO_FLAG_SRP_ENABLED (1u<<2) + +struct avb_packet_aecp_aem_get_avb_info { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint64_t gptp_grandmaster_id; + uint32_t propagation_delay; + uint8_t gptp_domain_number; + uint8_t flags; + uint16_t msrp_mappings_count; + uint8_t msrp_mappings[0]; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_get_as_path { + uint16_t descriptor_index; + uint16_t reserved; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_get_counters { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint32_t counters_valid; + uint8_t counters_block[0]; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_reboot { + uint16_t descriptor_type; + uint16_t descriptor_id; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_start_operation { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint16_t operation_id; + uint16_t operation_type; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem_operation_status { + uint16_t descriptor_type; + uint16_t descriptor_id; + uint16_t operation_id; + uint16_t percent_complete; +} __attribute__ ((__packed__)); + +struct avb_packet_aecp_aem { + struct avb_packet_aecp_header aecp; +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned u:1; + unsigned cmd1:7; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + unsigned cmd1:7; + unsigned u:1; +#endif + uint8_t cmd2; + uint8_t payload[0]; +} __attribute__ ((__packed__)); + +#define AVB_PACKET_AEM_SET_COMMAND_TYPE(p,v) ((p)->cmd1 = ((v) >> 8),(p)->cmd2 = (v)) + +#define AVB_PACKET_AEM_GET_COMMAND_TYPE(p) ((p)->cmd1 << 8 | (p)->cmd2) + +int avb_aecp_aem_handle_command(struct aecp *aecp, const void *m, int len); +int avb_aecp_aem_handle_response(struct aecp *aecp, const void *m, int len); + +#endif /* AVB_AEM_H */ diff --git a/src/modules/module-avbtp/aecp.c b/src/modules/module-avb/aecp.c similarity index 73% rename from src/modules/module-avbtp/aecp.c rename to src/modules/module-avb/aecp.c index 1f6dba17f..1adaeddbc 100644 --- a/src/modules/module-avbtp/aecp.c +++ b/src/modules/module-avb/aecp.c @@ -43,26 +43,26 @@ static int reply_not_implemented(struct aecp *aecp, const void *p, int len) { struct server *server = aecp->server; uint8_t buf[len]; - struct avbtp_packet_aecp_header *reply = (struct avbtp_packet_aecp_header*)buf; + struct avb_packet_aecp_header *reply = (struct avb_packet_aecp_header*)buf; memcpy(reply, p, len); - AVBTP_PACKET_AECP_SET_STATUS(reply, AVBTP_AECP_STATUS_NOT_IMPLEMENTED); + AVB_PACKET_AECP_SET_STATUS(reply, AVB_AECP_STATUS_NOT_IMPLEMENTED); - return avbtp_server_send_packet(server, reply->hdr.eth.src, + return avb_server_send_packet(server, reply->hdr.eth.src, AVB_TSN_ETH, reply, len); } static const struct msg_info msg_info[] = { - { AVBTP_AECP_MESSAGE_TYPE_AEM_COMMAND, "aem-command", avbtp_aecp_aem_handle_command, }, - { AVBTP_AECP_MESSAGE_TYPE_AEM_RESPONSE, "aem-response", avbtp_aecp_aem_handle_response, }, - { AVBTP_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_COMMAND, "address-access-command", NULL, }, - { AVBTP_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_RESPONSE, "address-access-response", NULL, }, - { AVBTP_AECP_MESSAGE_TYPE_AVC_COMMAND, "avc-command", NULL, }, - { AVBTP_AECP_MESSAGE_TYPE_AVC_RESPONSE, "avc-response", NULL, }, - { AVBTP_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_COMMAND, "vendor-unique-command", NULL, }, - { AVBTP_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_RESPONSE, "vendor-unique-response", NULL, }, - { AVBTP_AECP_MESSAGE_TYPE_EXTENDED_COMMAND, "extended-command", NULL, }, - { AVBTP_AECP_MESSAGE_TYPE_EXTENDED_RESPONSE, "extended-response", NULL, }, + { AVB_AECP_MESSAGE_TYPE_AEM_COMMAND, "aem-command", avb_aecp_aem_handle_command, }, + { AVB_AECP_MESSAGE_TYPE_AEM_RESPONSE, "aem-response", avb_aecp_aem_handle_response, }, + { AVB_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_COMMAND, "address-access-command", NULL, }, + { AVB_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_RESPONSE, "address-access-response", NULL, }, + { AVB_AECP_MESSAGE_TYPE_AVC_COMMAND, "avc-command", NULL, }, + { AVB_AECP_MESSAGE_TYPE_AVC_RESPONSE, "avc-response", NULL, }, + { AVB_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_COMMAND, "vendor-unique-command", NULL, }, + { AVB_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_RESPONSE, "vendor-unique-response", NULL, }, + { AVB_AECP_MESSAGE_TYPE_EXTENDED_COMMAND, "extended-command", NULL, }, + { AVB_AECP_MESSAGE_TYPE_EXTENDED_RESPONSE, "extended-response", NULL, }, }; static inline const struct msg_info *find_msg_info(uint16_t type, const char *name) @@ -80,7 +80,7 @@ static int aecp_message(void *data, uint64_t now, const void *message, int len) { struct aecp *aecp = data; struct server *server = aecp->server; - const struct avbtp_packet_aecp_header *p = message; + const struct avb_packet_aecp_header *p = message; const struct msg_info *info; int message_type; @@ -89,10 +89,10 @@ static int aecp_message(void *data, uint64_t now, const void *message, int len) if (memcmp(p->hdr.eth.dest, mac, 6) != 0 && memcmp(p->hdr.eth.dest, server->mac_addr, 6) != 0) return 0; - if (AVBTP_PACKET_GET_SUBTYPE(&p->hdr) != AVBTP_SUBTYPE_AECP) + if (AVB_PACKET_GET_SUBTYPE(&p->hdr) != AVB_SUBTYPE_AECP) return 0; - message_type = AVBTP_PACKET_AECP_GET_MESSAGE_TYPE(p); + message_type = AVB_PACKET_AECP_GET_MESSAGE_TYPE(p); info = find_msg_info(message_type, NULL); if (info == NULL) @@ -141,13 +141,13 @@ static int aecp_command(void *data, uint64_t now, const char *command, const cha } static const struct server_events server_events = { - AVBTP_VERSION_SERVER_EVENTS, + AVB_VERSION_SERVER_EVENTS, .destroy = aecp_destroy, .message = aecp_message, .command = aecp_command }; -struct avbtp_aecp *avbtp_aecp_register(struct server *server) +struct avb_aecp *avb_aecp_register(struct server *server) { struct aecp *aecp; @@ -159,10 +159,10 @@ struct avbtp_aecp *avbtp_aecp_register(struct server *server) avdecc_server_add_listener(server, &aecp->server_listener, &server_events, aecp); - return (struct avbtp_aecp*)aecp; + return (struct avb_aecp*)aecp; } -void avbtp_aecp_unregister(struct avbtp_aecp *aecp) +void avb_aecp_unregister(struct avb_aecp *aecp) { aecp_destroy(aecp); } diff --git a/src/modules/module-avbtp/aecp.h b/src/modules/module-avb/aecp.h similarity index 54% rename from src/modules/module-avbtp/aecp.h rename to src/modules/module-avb/aecp.h index 0e8732c47..a3515f0e7 100644 --- a/src/modules/module-avbtp/aecp.h +++ b/src/modules/module-avb/aecp.h @@ -22,39 +22,39 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef AVBTP_AECP_H -#define AVBTP_AECP_H +#ifndef AVB_AECP_H +#define AVB_AECP_H #include "packets.h" #include "internal.h" -#define AVBTP_AECP_MESSAGE_TYPE_AEM_COMMAND 0 -#define AVBTP_AECP_MESSAGE_TYPE_AEM_RESPONSE 1 -#define AVBTP_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_COMMAND 2 -#define AVBTP_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_RESPONSE 3 -#define AVBTP_AECP_MESSAGE_TYPE_AVC_COMMAND 4 -#define AVBTP_AECP_MESSAGE_TYPE_AVC_RESPONSE 5 -#define AVBTP_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_COMMAND 6 -#define AVBTP_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_RESPONSE 7 -#define AVBTP_AECP_MESSAGE_TYPE_EXTENDED_COMMAND 14 -#define AVBTP_AECP_MESSAGE_TYPE_EXTENDED_RESPONSE 15 +#define AVB_AECP_MESSAGE_TYPE_AEM_COMMAND 0 +#define AVB_AECP_MESSAGE_TYPE_AEM_RESPONSE 1 +#define AVB_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_COMMAND 2 +#define AVB_AECP_MESSAGE_TYPE_ADDRESS_ACCESS_RESPONSE 3 +#define AVB_AECP_MESSAGE_TYPE_AVC_COMMAND 4 +#define AVB_AECP_MESSAGE_TYPE_AVC_RESPONSE 5 +#define AVB_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_COMMAND 6 +#define AVB_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_RESPONSE 7 +#define AVB_AECP_MESSAGE_TYPE_EXTENDED_COMMAND 14 +#define AVB_AECP_MESSAGE_TYPE_EXTENDED_RESPONSE 15 -#define AVBTP_AECP_STATUS_SUCCESS 0 -#define AVBTP_AECP_STATUS_NOT_IMPLEMENTED 1 +#define AVB_AECP_STATUS_SUCCESS 0 +#define AVB_AECP_STATUS_NOT_IMPLEMENTED 1 -struct avbtp_packet_aecp_header { - struct avbtp_packet_header hdr; +struct avb_packet_aecp_header { + struct avb_packet_header hdr; uint64_t target_guid; uint64_t controller_guid; uint16_t sequence_id; } __attribute__ ((__packed__)); -#define AVBTP_PACKET_AECP_SET_MESSAGE_TYPE(p,v) AVBTP_PACKET_SET_SUB1(&(p)->hdr, v) -#define AVBTP_PACKET_AECP_SET_STATUS(p,v) AVBTP_PACKET_SET_SUB2(&(p)->hdr, v) +#define AVB_PACKET_AECP_SET_MESSAGE_TYPE(p,v) AVB_PACKET_SET_SUB1(&(p)->hdr, v) +#define AVB_PACKET_AECP_SET_STATUS(p,v) AVB_PACKET_SET_SUB2(&(p)->hdr, v) -#define AVBTP_PACKET_AECP_GET_MESSAGE_TYPE(p) AVBTP_PACKET_GET_SUB1(&(p)->hdr) -#define AVBTP_PACKET_AECP_GET_STATUS(p) AVBTP_PACKET_GET_SUB2(&(p)->hdr) +#define AVB_PACKET_AECP_GET_MESSAGE_TYPE(p) AVB_PACKET_GET_SUB1(&(p)->hdr) +#define AVB_PACKET_AECP_GET_STATUS(p) AVB_PACKET_GET_SUB2(&(p)->hdr) -struct avbtp_aecp *avbtp_aecp_register(struct server *server); +struct avb_aecp *avb_aecp_register(struct server *server); -#endif /* AVBTP_AECP_H */ +#endif /* AVB_AECP_H */ diff --git a/src/modules/module-avbtp/avb.c b/src/modules/module-avb/avb.c similarity index 100% rename from src/modules/module-avbtp/avb.c rename to src/modules/module-avb/avb.c diff --git a/src/modules/module-avbtp/avb.h b/src/modules/module-avb/avb.h similarity index 100% rename from src/modules/module-avbtp/avb.h rename to src/modules/module-avb/avb.h diff --git a/src/modules/module-avbtp/avdecc.c b/src/modules/module-avb/avdecc.c similarity index 87% rename from src/modules/module-avbtp/avdecc.c rename to src/modules/module-avb/avdecc.c index b667bd8ac..d911fefc5 100644 --- a/src/modules/module-avbtp/avdecc.c +++ b/src/modules/module-avb/avdecc.c @@ -78,9 +78,9 @@ static void on_socket_data(void *data, int fd, uint32_t mask) if (len < 0) { pw_log_warn("got recv error: %m"); } - else if (len < (int)sizeof(struct avbtp_packet_header)) { + else if (len < (int)sizeof(struct avb_packet_header)) { pw_log_warn("short packet received (%d < %d)", len, - (int)sizeof(struct avbtp_packet_header)); + (int)sizeof(struct avb_packet_header)); } else { clock_gettime(CLOCK_REALTIME, &now); server_emit_message(server, SPA_TIMESPEC_TO_NSEC(&now), buffer, len); @@ -88,10 +88,10 @@ static void on_socket_data(void *data, int fd, uint32_t mask) } } -int avbtp_server_send_packet(struct server *server, const uint8_t dest[6], +int avb_server_send_packet(struct server *server, const uint8_t dest[6], uint16_t type, void *data, size_t size) { - struct avbtp_ethernet_header *hdr = (struct avbtp_ethernet_header*)data; + struct avb_ethernet_header *hdr = (struct avb_ethernet_header*)data; int res = 0; memcpy(hdr->dest, dest, ETH_ALEN); @@ -216,31 +216,31 @@ struct server *avdecc_server_new(struct impl *impl, const char *ifname, struct s init_descriptors(server); - server->mrp = avbtp_mrp_new(server); + server->mrp = avb_mrp_new(server); if (server->mrp == NULL) goto error_free; - avbtp_aecp_register(server); - avbtp_maap_register(server); - server->mmrp = avbtp_mmrp_register(server); - server->msrp = avbtp_msrp_register(server); - server->mvrp = avbtp_mvrp_register(server); - avbtp_adp_register(server); - avbtp_acmp_register(server); + avb_aecp_register(server); + avb_maap_register(server); + server->mmrp = avb_mmrp_register(server); + server->msrp = avb_msrp_register(server); + server->mvrp = avb_mvrp_register(server); + avb_adp_register(server); + avb_acmp_register(server); - server->domain_attr = avbtp_msrp_attribute_new(server->msrp, - AVBTP_MSRP_ATTRIBUTE_TYPE_DOMAIN); + server->domain_attr = avb_msrp_attribute_new(server->msrp, + AVB_MSRP_ATTRIBUTE_TYPE_DOMAIN); server->domain_attr->attr.domain.sr_class_id = 6; server->domain_attr->attr.domain.sr_class_priority = 3; server->domain_attr->attr.domain.sr_class_vid = htons(2); - avbtp_mrp_mad_begin(server->mrp, 0, server->domain_attr->mrp); - avbtp_mrp_mad_join(server->mrp, 0, server->domain_attr->mrp, true); + avb_mrp_mad_begin(server->mrp, 0, server->domain_attr->mrp); + avb_mrp_mad_join(server->mrp, 0, server->domain_attr->mrp, true); - server->listener_attr = avbtp_msrp_attribute_new(server->msrp, - AVBTP_MSRP_ATTRIBUTE_TYPE_LISTENER); + server->listener_attr = avb_msrp_attribute_new(server->msrp, + AVB_MSRP_ATTRIBUTE_TYPE_LISTENER); server->listener_attr->attr.listener.stream_id = htobe64(0); - avbtp_mrp_mad_begin(server->mrp, 0, server->listener_attr->mrp); + avb_mrp_mad_begin(server->mrp, 0, server->listener_attr->mrp); return server; diff --git a/src/modules/module-avbtp/descriptors.h b/src/modules/module-avb/descriptors.h similarity index 73% rename from src/modules/module-avbtp/descriptors.h rename to src/modules/module-avb/descriptors.h index 82377117f..56397e3d3 100644 --- a/src/modules/module-avbtp/descriptors.h +++ b/src/modules/module-avb/descriptors.h @@ -28,43 +28,43 @@ void init_descriptors(struct server *server) { - server_add_descriptor(server, AVBTP_AEM_DESC_STRINGS, 0, - sizeof(struct avbtp_aem_desc_strings), - &(struct avbtp_aem_desc_strings) + server_add_descriptor(server, AVB_AEM_DESC_STRINGS, 0, + sizeof(struct avb_aem_desc_strings), + &(struct avb_aem_desc_strings) { .string_0 = "PipeWire", .string_1 = "Configuration 1", .string_2 = "Wim Taymans", }); - server_add_descriptor(server, AVBTP_AEM_DESC_LOCALE, 0, - sizeof(struct avbtp_aem_desc_locale), - &(struct avbtp_aem_desc_locale) + server_add_descriptor(server, AVB_AEM_DESC_LOCALE, 0, + sizeof(struct avb_aem_desc_locale), + &(struct avb_aem_desc_locale) { .locale_identifier = "en-EN", .number_of_strings = htons(1), .base_strings = htons(0) }); - server_add_descriptor(server, AVBTP_AEM_DESC_ENTITY, 0, - sizeof(struct avbtp_aem_desc_entity), - &(struct avbtp_aem_desc_entity) + server_add_descriptor(server, AVB_AEM_DESC_ENTITY, 0, + sizeof(struct avb_aem_desc_entity), + &(struct avb_aem_desc_entity) { .entity_id = htobe64(server->entity_id), .entity_model_id = htobe64(0), .entity_capabilities = htonl( - AVBTP_ADP_ENTITY_CAPABILITY_AEM_SUPPORTED | - AVBTP_ADP_ENTITY_CAPABILITY_CLASS_A_SUPPORTED | - AVBTP_ADP_ENTITY_CAPABILITY_GPTP_SUPPORTED | - AVBTP_ADP_ENTITY_CAPABILITY_AEM_IDENTIFY_CONTROL_INDEX_VALID | - AVBTP_ADP_ENTITY_CAPABILITY_AEM_INTERFACE_INDEX_VALID), + AVB_ADP_ENTITY_CAPABILITY_AEM_SUPPORTED | + AVB_ADP_ENTITY_CAPABILITY_CLASS_A_SUPPORTED | + AVB_ADP_ENTITY_CAPABILITY_GPTP_SUPPORTED | + AVB_ADP_ENTITY_CAPABILITY_AEM_IDENTIFY_CONTROL_INDEX_VALID | + AVB_ADP_ENTITY_CAPABILITY_AEM_INTERFACE_INDEX_VALID), .talker_stream_sources = htons(8), .talker_capabilities = htons( - AVBTP_ADP_TALKER_CAPABILITY_IMPLEMENTED | - AVBTP_ADP_TALKER_CAPABILITY_AUDIO_SOURCE), + AVB_ADP_TALKER_CAPABILITY_IMPLEMENTED | + AVB_ADP_TALKER_CAPABILITY_AUDIO_SOURCE), .listener_stream_sinks = htons(8), .listener_capabilities = htons( - AVBTP_ADP_LISTENER_CAPABILITY_IMPLEMENTED | - AVBTP_ADP_LISTENER_CAPABILITY_AUDIO_SINK), + AVB_ADP_LISTENER_CAPABILITY_IMPLEMENTED | + AVB_ADP_LISTENER_CAPABILITY_AUDIO_SINK), .controller_capabilities = htons(0), .available_index = htonl(0), .association_id = htobe64(0), @@ -78,8 +78,8 @@ void init_descriptors(struct server *server) .current_configuration = htons(0) }); struct { - struct avbtp_aem_desc_configuration desc; - struct avbtp_aem_desc_descriptor_count descriptor_counts[8]; + struct avb_aem_desc_configuration desc; + struct avb_aem_desc_descriptor_count descriptor_counts[8]; } __attribute__ ((__packed__)) config = { { @@ -87,25 +87,25 @@ void init_descriptors(struct server *server) .localized_description = htons(1), .descriptor_counts_count = htons(8), .descriptor_counts_offset = htons( - 4 + sizeof(struct avbtp_aem_desc_configuration)), + 4 + sizeof(struct avb_aem_desc_configuration)), }, .descriptor_counts = { - { htons(AVBTP_AEM_DESC_AUDIO_UNIT), htons(1) }, - { htons(AVBTP_AEM_DESC_STREAM_INPUT), htons(1) }, - { htons(AVBTP_AEM_DESC_STREAM_OUTPUT), htons(1) }, - { htons(AVBTP_AEM_DESC_AVB_INTERFACE), htons(1) }, - { htons(AVBTP_AEM_DESC_CLOCK_SOURCE), htons(1) }, - { htons(AVBTP_AEM_DESC_CONTROL), htons(2) }, - { htons(AVBTP_AEM_DESC_LOCALE), htons(1) }, - { htons(AVBTP_AEM_DESC_CLOCK_DOMAIN), htons(1) } + { htons(AVB_AEM_DESC_AUDIO_UNIT), htons(1) }, + { htons(AVB_AEM_DESC_STREAM_INPUT), htons(1) }, + { htons(AVB_AEM_DESC_STREAM_OUTPUT), htons(1) }, + { htons(AVB_AEM_DESC_AVB_INTERFACE), htons(1) }, + { htons(AVB_AEM_DESC_CLOCK_SOURCE), htons(1) }, + { htons(AVB_AEM_DESC_CONTROL), htons(2) }, + { htons(AVB_AEM_DESC_LOCALE), htons(1) }, + { htons(AVB_AEM_DESC_CLOCK_DOMAIN), htons(1) } } }; - server_add_descriptor(server, AVBTP_AEM_DESC_CONFIGURATION, 0, + server_add_descriptor(server, AVB_AEM_DESC_CONFIGURATION, 0, sizeof(config), &config); struct { - struct avbtp_aem_desc_audio_unit desc; - struct avbtp_aem_desc_sampling_rate sampling_rates[6]; + struct avb_aem_desc_audio_unit desc; + struct avb_aem_desc_sampling_rate sampling_rates[6]; } __attribute__ ((__packed__)) audio_unit = { { @@ -146,7 +146,7 @@ void init_descriptors(struct server *server) .base_control_block = htons(0), .current_sampling_rate = htonl(48000), .sampling_rates_offset = htons( - 4 + sizeof(struct avbtp_aem_desc_audio_unit)), + 4 + sizeof(struct avb_aem_desc_audio_unit)), .sampling_rates_count = htons(6), }, .sampling_rates = { @@ -158,11 +158,11 @@ void init_descriptors(struct server *server) { .pull_frequency = htonl(192000) }, } }; - server_add_descriptor(server, AVBTP_AEM_DESC_AUDIO_UNIT, 0, + server_add_descriptor(server, AVB_AEM_DESC_AUDIO_UNIT, 0, sizeof(audio_unit), &audio_unit); struct { - struct avbtp_aem_desc_stream desc; + struct avb_aem_desc_stream desc; uint64_t stream_formats[6]; } __attribute__ ((__packed__)) stream_input_0 = { @@ -171,11 +171,11 @@ void init_descriptors(struct server *server) .localized_description = htons(0xffff), .clock_domain_index = htons(0), .stream_flags = htons( - AVBTP_AEM_DESC_STREAM_FLAG_SYNC_SOURCE | - AVBTP_AEM_DESC_STREAM_FLAG_CLASS_A), + AVB_AEM_DESC_STREAM_FLAG_SYNC_SOURCE | + AVB_AEM_DESC_STREAM_FLAG_CLASS_A), .current_format = htobe64(0x00a0020840000800ULL), .formats_offset = htons( - 4 + sizeof(struct avbtp_aem_desc_stream)), + 4 + sizeof(struct avb_aem_desc_stream)), .number_of_formats = htons(6), .backup_talker_entity_id_0 = htobe64(0), .backup_talker_unique_id_0 = htons(0), @@ -197,11 +197,11 @@ void init_descriptors(struct server *server) htobe64(0x00a0060860000800ULL), }, }; - server_add_descriptor(server, AVBTP_AEM_DESC_STREAM_INPUT, 0, + server_add_descriptor(server, AVB_AEM_DESC_STREAM_INPUT, 0, sizeof(stream_input_0), &stream_input_0); struct { - struct avbtp_aem_desc_stream desc; + struct avb_aem_desc_stream desc; uint64_t stream_formats[6]; } __attribute__ ((__packed__)) stream_output_0 = { @@ -210,10 +210,10 @@ void init_descriptors(struct server *server) .localized_description = htons(0xffff), .clock_domain_index = htons(0), .stream_flags = htons( - AVBTP_AEM_DESC_STREAM_FLAG_CLASS_A), + AVB_AEM_DESC_STREAM_FLAG_CLASS_A), .current_format = htobe64(0x00a0020840000800ULL), .formats_offset = htons( - 4 + sizeof(struct avbtp_aem_desc_stream)), + 4 + sizeof(struct avb_aem_desc_stream)), .number_of_formats = htons(6), .backup_talker_entity_id_0 = htobe64(0), .backup_talker_unique_id_0 = htons(0), @@ -235,13 +235,13 @@ void init_descriptors(struct server *server) htobe64(0x00a0060860000800ULL), }, }; - server_add_descriptor(server, AVBTP_AEM_DESC_STREAM_OUTPUT, 0, + server_add_descriptor(server, AVB_AEM_DESC_STREAM_OUTPUT, 0, sizeof(stream_output_0), &stream_output_0); - struct avbtp_aem_desc_avb_interface avb_interface = { + struct avb_aem_desc_avb_interface avb_interface = { .localized_description = htons(0xffff), .interface_flags = htons( - AVBTP_AEM_DESC_AVB_INTERFACE_FLAG_GPTP_GRANDMASTER_SUPPORTED), + AVB_AEM_DESC_AVB_INTERFACE_FLAG_GPTP_GRANDMASTER_SUPPORTED), .clock_identity = htobe64(0), .priority1 = 0, .clock_class = 0, @@ -256,19 +256,19 @@ void init_descriptors(struct server *server) }; strncpy(avb_interface.object_name, server->ifname, 63); memcpy(avb_interface.mac_address, server->mac_addr, 6); - server_add_descriptor(server, AVBTP_AEM_DESC_AVB_INTERFACE, 0, + server_add_descriptor(server, AVB_AEM_DESC_AVB_INTERFACE, 0, sizeof(avb_interface), &avb_interface); - struct avbtp_aem_desc_clock_source clock_source = { + struct avb_aem_desc_clock_source clock_source = { .object_name = "Stream Clock", .localized_description = htons(0xffff), .clock_source_flags = htons(0), .clock_source_type = htons( - AVBTP_AEM_DESC_CLOCK_SOURCE_TYPE_INPUT_STREAM), + AVB_AEM_DESC_CLOCK_SOURCE_TYPE_INPUT_STREAM), .clock_source_identifier = htobe64(0), - .clock_source_location_type = htons(AVBTP_AEM_DESC_STREAM_INPUT), + .clock_source_location_type = htons(AVB_AEM_DESC_STREAM_INPUT), .clock_source_location_index = htons(0), }; - server_add_descriptor(server, AVBTP_AEM_DESC_CLOCK_SOURCE, 0, + server_add_descriptor(server, AVB_AEM_DESC_CLOCK_SOURCE, 0, sizeof(clock_source), &clock_source); } diff --git a/src/modules/module-avbtp/internal.h b/src/modules/module-avb/internal.h similarity index 92% rename from src/modules/module-avbtp/internal.h rename to src/modules/module-avb/internal.h index fc22491bf..3683d5ae0 100644 --- a/src/modules/module-avbtp/internal.h +++ b/src/modules/module-avb/internal.h @@ -47,7 +47,7 @@ struct impl { }; struct server_events { -#define AVBTP_VERSION_SERVER_EVENTS 0 +#define AVB_VERSION_SERVER_EVENTS 0 uint32_t version; /** the server is destroyed */ @@ -87,13 +87,13 @@ struct server { unsigned debug_messages:1; - struct avbtp_mrp *mrp; - struct avbtp_mmrp *mmrp; - struct avbtp_mvrp *mvrp; - struct avbtp_msrp *msrp; + struct avb_mrp *mrp; + struct avb_mmrp *mmrp; + struct avb_mvrp *mvrp; + struct avb_msrp *msrp; - struct avbtp_msrp_attribute *domain_attr; - struct avbtp_msrp_attribute *listener_attr; + struct avb_msrp_attribute *domain_attr; + struct avb_msrp_attribute *listener_attr; }; static inline const struct descriptor *server_find_descriptor(struct server *server, @@ -131,7 +131,7 @@ 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); -int avbtp_server_send_packet(struct server *server, const uint8_t dest[6], +int avb_server_send_packet(struct server *server, const uint8_t dest[6], uint16_t type, void *data, size_t size); struct aecp { diff --git a/src/modules/module-avbtp/maap.c b/src/modules/module-avb/maap.c similarity index 77% rename from src/modules/module-avbtp/maap.c rename to src/modules/module-avb/maap.c index 979e27f73..aad811e2f 100644 --- a/src/modules/module-avbtp/maap.c +++ b/src/modules/module-avb/maap.c @@ -36,49 +36,49 @@ struct maap { static const char *message_type_as_string(uint8_t message_type) { switch (message_type) { - case AVBTP_MAAP_MESSAGE_TYPE_PROBE: + case AVB_MAAP_MESSAGE_TYPE_PROBE: return "PROBE"; - case AVBTP_MAAP_MESSAGE_TYPE_DEFEND: + case AVB_MAAP_MESSAGE_TYPE_DEFEND: return "DEFEND"; - case AVBTP_MAAP_MESSAGE_TYPE_ANNOUNCE: + case AVB_MAAP_MESSAGE_TYPE_ANNOUNCE: return "ANNOUNCE"; } return "INVALID"; } -static void maap_message_debug(struct maap *maap, const struct avbtp_packet_maap *p) +static void maap_message_debug(struct maap *maap, const struct avb_packet_maap *p) { uint32_t v; const uint8_t *addr; - v = AVBTP_PACKET_MAAP_GET_MESSAGE_TYPE(p); + v = AVB_PACKET_MAAP_GET_MESSAGE_TYPE(p); pw_log_info("message-type: %d (%s)", v, message_type_as_string(v)); - pw_log_info(" maap-version: %d", AVBTP_PACKET_MAAP_GET_MAAP_VERSION(p)); - pw_log_info(" length: %d", AVBTP_PACKET_GET_LENGTH(&p->hdr)); + pw_log_info(" maap-version: %d", AVB_PACKET_MAAP_GET_MAAP_VERSION(p)); + pw_log_info(" length: %d", AVB_PACKET_GET_LENGTH(&p->hdr)); - pw_log_info(" stream-id: 0x%"PRIx64, AVBTP_PACKET_MAAP_GET_STREAM_ID(p)); - addr = AVBTP_PACKET_MAAP_GET_REQUEST_START(p); + pw_log_info(" stream-id: 0x%"PRIx64, AVB_PACKET_MAAP_GET_STREAM_ID(p)); + addr = AVB_PACKET_MAAP_GET_REQUEST_START(p); pw_log_info(" request-start: %02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - pw_log_info(" request-count: %d", AVBTP_PACKET_MAAP_GET_REQUEST_COUNT(p)); - addr = AVBTP_PACKET_MAAP_GET_CONFLICT_START(p); + pw_log_info(" request-count: %d", AVB_PACKET_MAAP_GET_REQUEST_COUNT(p)); + addr = AVB_PACKET_MAAP_GET_CONFLICT_START(p); pw_log_info(" conflict-start: %02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - pw_log_info(" conflict-count: %d", AVBTP_PACKET_MAAP_GET_CONFLICT_COUNT(p)); + pw_log_info(" conflict-count: %d", AVB_PACKET_MAAP_GET_CONFLICT_COUNT(p)); } static int maap_message(void *data, uint64_t now, const void *message, int len) { struct maap *maap = data; struct server *server = maap->server; - const struct avbtp_packet_maap *p = message; + const struct avb_packet_maap *p = message; if (ntohs(p->hdr.eth.type) != AVB_TSN_ETH) return 0; if (memcmp(p->hdr.eth.dest, mac, 6) != 0 && memcmp(p->hdr.eth.dest, server->mac_addr, 6) != 0) return 0; - if (AVBTP_PACKET_GET_SUBTYPE(&p->hdr) != AVBTP_SUBTYPE_MAAP) + if (AVB_PACKET_GET_SUBTYPE(&p->hdr) != AVB_SUBTYPE_MAAP) return 0; if (maap->server->debug_messages) @@ -95,12 +95,12 @@ static void maap_destroy(void *data) } static const struct server_events server_events = { - AVBTP_VERSION_SERVER_EVENTS, + AVB_VERSION_SERVER_EVENTS, .destroy = maap_destroy, .message = maap_message }; -int avbtp_maap_register(struct server *server) +int avb_maap_register(struct server *server) { struct maap *maap; diff --git a/src/modules/module-avb/maap.h b/src/modules/module-avb/maap.h new file mode 100644 index 000000000..05489db39 --- /dev/null +++ b/src/modules/module-avb/maap.h @@ -0,0 +1,62 @@ +/* AVB support + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AVB_MAAP_H +#define AVB_MAAP_H + +#include "packets.h" +#include "internal.h" + +#define AVB_MAAP_MESSAGE_TYPE_PROBE 1 +#define AVB_MAAP_MESSAGE_TYPE_DEFEND 2 +#define AVB_MAAP_MESSAGE_TYPE_ANNOUNCE 3 + +struct avb_packet_maap { + struct avb_packet_header hdr; + uint64_t stream_id; + uint8_t request_start[6]; + uint16_t request_count; + uint8_t conflict_start[6]; + uint16_t conflict_count; +} __attribute__ ((__packed__)); + +#define AVB_PACKET_MAAP_SET_MESSAGE_TYPE(p,v) AVB_PACKET_SET_SUB1(&(p)->hdr, v) +#define AVB_PACKET_MAAP_SET_MAAP_VERSION(p,v) AVB_PACKET_SET_SUB2(&(p)->hdr, v) +#define AVB_PACKET_MAAP_SET_STREAM_ID(p,v) ((p)->stream_id = htobe64(v)) +#define AVB_PACKET_MAAP_SET_REQUEST_START(p,v) memcpy((p)->request_start, (v), 6) +#define AVB_PACKET_MAAP_SET_REQUEST_COUNT(p,v) ((p)->request_count = htons(v)) +#define AVB_PACKET_MAAP_SET_CONFLICT_START(p,v) memcpy((p)->conflict_start, (v), 6) +#define AVB_PACKET_MAAP_SET_CONFLICT_COUNT(p,v) ((p)->conflict_count = htons(v)) + +#define AVB_PACKET_MAAP_GET_MESSAGE_TYPE(p) AVB_PACKET_GET_SUB1(&(p)->hdr) +#define AVB_PACKET_MAAP_GET_MAAP_VERSION(p) AVB_PACKET_GET_SUB2(&(p)->hdr) +#define AVB_PACKET_MAAP_GET_STREAM_ID(p) be64toh((p)->stream_id) +#define AVB_PACKET_MAAP_GET_REQUEST_START(p) ((p)->request_start) +#define AVB_PACKET_MAAP_GET_REQUEST_COUNT(p) ntohs((p)->request_count) +#define AVB_PACKET_MAAP_GET_CONFLICT_START(p) ((p)->conflict_start) +#define AVB_PACKET_MAAP_GET_CONFLICT_COUNT(p) ntohs((p)->conflict_count) + +int avb_maap_register(struct server *server); + +#endif /* AVB_MAAP_H */ diff --git a/src/modules/module-avbtp/mmrp.c b/src/modules/module-avb/mmrp.c similarity index 75% rename from src/modules/module-avbtp/mmrp.c rename to src/modules/module-avb/mmrp.c index 440312dc3..0e86a674f 100644 --- a/src/modules/module-avbtp/mmrp.c +++ b/src/modules/module-avb/mmrp.c @@ -30,7 +30,7 @@ static const uint8_t mac[6] = AVB_MMRP_MAC; struct attr { - struct avbtp_mmrp_attribute attr; + struct avb_mmrp_attribute attr; struct spa_list link; }; @@ -43,10 +43,10 @@ struct mmrp { static bool mmrp_check_header(void *data, const void *hdr, size_t *hdr_size, bool *has_params) { - const struct avbtp_packet_mmrp_msg *msg = hdr; + const struct avb_packet_mmrp_msg *msg = hdr; uint8_t attr_type = msg->attribute_type; - if (!AVBTP_MMRP_ATTRIBUTE_TYPE_VALID(attr_type)) + if (!AVB_MMRP_ATTRIBUTE_TYPE_VALID(attr_type)) return false; *hdr_size = sizeof(*msg); @@ -60,21 +60,21 @@ static int mmrp_attr_event(void *data, uint64_t now, uint8_t attribute_type, uin struct attr *a; spa_list_for_each(a, &mmrp->attributes, link) if (a->attr.type == attribute_type) - avbtp_mrp_update_state(mmrp->server->mrp, now, a->attr.mrp, event); + avb_mrp_update_state(mmrp->server->mrp, now, a->attr.mrp, event); return 0; } -static void debug_service_requirement(const struct avbtp_packet_mmrp_service_requirement *t) +static void debug_service_requirement(const struct avb_packet_mmrp_service_requirement *t) { char buf[128]; pw_log_info("service requirement"); - pw_log_info(" %s", avbtp_utils_format_addr(buf, sizeof(buf), t->addr)); + pw_log_info(" %s", avb_utils_format_addr(buf, sizeof(buf), t->addr)); } static int process_service_requirement(struct mmrp *mmrp, uint64_t now, uint8_t attr_type, const void *m, uint8_t event, uint8_t param, int num) { - const struct avbtp_packet_mmrp_service_requirement *t = m; + const struct avb_packet_mmrp_service_requirement *t = m; struct attr *a; debug_service_requirement(t); @@ -82,21 +82,21 @@ static int process_service_requirement(struct mmrp *mmrp, uint64_t now, uint8_t spa_list_for_each(a, &mmrp->attributes, link) if (a->attr.type == attr_type && memcmp(a->attr.attr.service_requirement.addr, t->addr, 6) == 0) - avbtp_mrp_rx_event(mmrp->server->mrp, now, a->attr.mrp, event); + avb_mrp_rx_event(mmrp->server->mrp, now, a->attr.mrp, event); return 0; } -static void debug_process_mac(const struct avbtp_packet_mmrp_mac *t) +static void debug_process_mac(const struct avb_packet_mmrp_mac *t) { char buf[128]; pw_log_info("mac"); - pw_log_info(" %s", avbtp_utils_format_addr(buf, sizeof(buf), t->addr)); + pw_log_info(" %s", avb_utils_format_addr(buf, sizeof(buf), t->addr)); } static int process_mac(struct mmrp *mmrp, uint64_t now, uint8_t attr_type, const void *m, uint8_t event, uint8_t param, int num) { - const struct avbtp_packet_mmrp_mac *t = m; + const struct avb_packet_mmrp_mac *t = m; struct attr *a; debug_process_mac(t); @@ -104,7 +104,7 @@ static int process_mac(struct mmrp *mmrp, uint64_t now, uint8_t attr_type, spa_list_for_each(a, &mmrp->attributes, link) if (a->attr.type == attr_type && memcmp(a->attr.attr.mac.addr, t->addr, 6) == 0) - avbtp_mrp_rx_event(mmrp->server->mrp, now, a->attr.mrp, event); + avb_mrp_rx_event(mmrp->server->mrp, now, a->attr.mrp, event); return 0; } @@ -112,8 +112,8 @@ static const struct { int (*dispatch) (struct mmrp *mmrp, uint64_t now, uint8_t attr_type, const void *m, uint8_t event, uint8_t param, int num); } dispatch[] = { - [AVBTP_MMRP_ATTRIBUTE_TYPE_SERVICE_REQUIREMENT] = { process_service_requirement, }, - [AVBTP_MMRP_ATTRIBUTE_TYPE_MAC] = { process_mac, }, + [AVB_MMRP_ATTRIBUTE_TYPE_SERVICE_REQUIREMENT] = { process_service_requirement, }, + [AVB_MMRP_ATTRIBUTE_TYPE_MAC] = { process_mac, }, }; static int mmrp_process(void *data, uint64_t now, uint8_t attribute_type, const void *value, @@ -124,8 +124,8 @@ static int mmrp_process(void *data, uint64_t now, uint8_t attribute_type, const attribute_type, value, event, param, index); } -static const struct avbtp_mrp_parse_info info = { - AVBTP_VERSION_MRP_PARSE_INFO, +static const struct avb_mrp_parse_info info = { + AVB_VERSION_MRP_PARSE_INFO, .check_header = mmrp_check_header, .attr_event = mmrp_attr_event, .process = mmrp_process, @@ -134,7 +134,7 @@ static const struct avbtp_mrp_parse_info info = { static int mmrp_message(void *data, uint64_t now, const void *message, int len) { struct mmrp *mmrp = data; - const struct avbtp_packet_mrp *p = message; + const struct avb_packet_mrp *p = message; if (ntohs(p->eth.type) != AVB_MMRP_ETH) return 0; @@ -142,7 +142,7 @@ static int mmrp_message(void *data, uint64_t now, const void *message, int len) return 0; pw_log_debug("MMRP"); - return avbtp_mrp_parse_packet(mmrp->server->mrp, + return avb_mrp_parse_packet(mmrp->server->mrp, now, message, len, &info, mmrp); } @@ -154,19 +154,19 @@ static void mmrp_destroy(void *data) } static const struct server_events server_events = { - AVBTP_VERSION_SERVER_EVENTS, + AVB_VERSION_SERVER_EVENTS, .destroy = mmrp_destroy, .message = mmrp_message }; -struct avbtp_mmrp_attribute *avbtp_mmrp_attribute_new(struct avbtp_mmrp *m, +struct avb_mmrp_attribute *avb_mmrp_attribute_new(struct avb_mmrp *m, uint8_t type) { struct mmrp *mmrp = (struct mmrp*)m; - struct avbtp_mrp_attribute *attr; + struct avb_mrp_attribute *attr; struct attr *a; - attr = avbtp_mrp_attribute_new(mmrp->server->mrp, sizeof(struct attr)); + attr = avb_mrp_attribute_new(mmrp->server->mrp, sizeof(struct attr)); a = attr->user_data; a->attr.mrp = attr; @@ -176,7 +176,7 @@ struct avbtp_mmrp_attribute *avbtp_mmrp_attribute_new(struct avbtp_mmrp *m, return &a->attr; } -struct avbtp_mmrp *avbtp_mmrp_register(struct server *server) +struct avb_mmrp *avb_mmrp_register(struct server *server) { struct mmrp *mmrp; @@ -189,5 +189,5 @@ struct avbtp_mmrp *avbtp_mmrp_register(struct server *server) avdecc_server_add_listener(server, &mmrp->server_listener, &server_events, mmrp); - return (struct avbtp_mmrp*)mmrp; + return (struct avb_mmrp*)mmrp; } diff --git a/src/modules/module-avbtp/mmrp.h b/src/modules/module-avb/mmrp.h similarity index 70% rename from src/modules/module-avbtp/mmrp.h rename to src/modules/module-avb/mmrp.h index 1ed6beb9f..b7bcf8c46 100644 --- a/src/modules/module-avbtp/mmrp.h +++ b/src/modules/module-avb/mmrp.h @@ -22,8 +22,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef AVBTP_MMRP_H -#define AVBTP_MMRP_H +#ifndef AVB_MMRP_H +#define AVB_MMRP_H #include "mrp.h" #include "internal.h" @@ -31,38 +31,38 @@ #define AVB_MMRP_ETH 0x88f6 #define AVB_MMRP_MAC { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x20 } -#define AVBTP_MMRP_ATTRIBUTE_TYPE_SERVICE_REQUIREMENT 1 -#define AVBTP_MMRP_ATTRIBUTE_TYPE_MAC 2 -#define AVBTP_MMRP_ATTRIBUTE_TYPE_VALID(t) ((t)>=1 && (t)<=2) +#define AVB_MMRP_ATTRIBUTE_TYPE_SERVICE_REQUIREMENT 1 +#define AVB_MMRP_ATTRIBUTE_TYPE_MAC 2 +#define AVB_MMRP_ATTRIBUTE_TYPE_VALID(t) ((t)>=1 && (t)<=2) -struct avbtp_packet_mmrp_msg { +struct avb_packet_mmrp_msg { uint8_t attribute_type; uint8_t attribute_length; uint8_t attribute_list[0]; } __attribute__ ((__packed__)); -struct avbtp_packet_mmrp_service_requirement { +struct avb_packet_mmrp_service_requirement { unsigned char addr[6]; } __attribute__ ((__packed__)); -struct avbtp_packet_mmrp_mac { +struct avb_packet_mmrp_mac { unsigned char addr[6]; } __attribute__ ((__packed__)); -struct avbtp_mmrp; +struct avb_mmrp; -struct avbtp_mmrp_attribute { - struct avbtp_mrp_attribute *mrp; +struct avb_mmrp_attribute { + struct avb_mrp_attribute *mrp; uint8_t type; union { - struct avbtp_packet_mmrp_service_requirement service_requirement; - struct avbtp_packet_mmrp_mac mac; + struct avb_packet_mmrp_service_requirement service_requirement; + struct avb_packet_mmrp_mac mac; } attr; }; -struct avbtp_mmrp_attribute *avbtp_mmrp_attribute_new(struct avbtp_mmrp *mmrp, +struct avb_mmrp_attribute *avb_mmrp_attribute_new(struct avb_mmrp *mmrp, uint8_t type); -struct avbtp_mmrp *avbtp_mmrp_register(struct server *server); +struct avb_mmrp *avb_mmrp_register(struct server *server); -#endif /* AVBTP_MMRP_H */ +#endif /* AVB_MMRP_H */ diff --git a/src/modules/module-avbtp/mrp.c b/src/modules/module-avb/mrp.c similarity index 53% rename from src/modules/module-avbtp/mrp.c rename to src/modules/module-avb/mrp.c index 938f03dd2..ec0924bc1 100644 --- a/src/modules/module-avbtp/mrp.c +++ b/src/modules/module-avb/mrp.c @@ -31,12 +31,12 @@ #define MRP_LVATIMER_MS 10000 #define MRP_PERIODTIMER_MS 1000 -#define mrp_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct avbtp_mrp_events, m, v, ##__VA_ARGS__) +#define mrp_emit(s,m,v,...) spa_hook_list_call(&s->listener_list, struct avb_mrp_events, m, v, ##__VA_ARGS__) #define mrp_emit_event(s,n,e) mrp_emit(s,event,0,n,e) #define mrp_emit_notify(s,n,a,e) mrp_emit(s,notify,0,n,a,e) struct attribute { - struct avbtp_mrp_attribute attr; + struct avb_mrp_attribute attr; struct spa_list link; uint8_t applicant_state; uint8_t registrar_state; @@ -67,7 +67,7 @@ static void global_event(struct mrp *mrp, uint64_t now, uint8_t event) { struct attribute *a; spa_list_for_each(a, &mrp->attributes, link) - avbtp_mrp_update_state((struct avbtp_mrp*)mrp, now, &a->attr, event); + avb_mrp_update_state((struct avb_mrp*)mrp, now, &a->attr, event); mrp_emit_event(mrp, now, event); } @@ -79,12 +79,12 @@ static void mrp_periodic(void *data, uint64_t now) if (now > mrp->periodic_timeout) { if (mrp->periodic_timeout > 0) - global_event(mrp, now, AVBTP_MRP_EVENT_PERIODIC); + global_event(mrp, now, AVB_MRP_EVENT_PERIODIC); mrp->periodic_timeout = now + MRP_PERIODTIMER_MS * SPA_NSEC_PER_MSEC; } if (now > mrp->leave_all_timeout) { if (mrp->leave_all_timeout > 0) { - global_event(mrp, now, AVBTP_MRP_EVENT_RX_LVA); + global_event(mrp, now, AVB_MRP_EVENT_RX_LVA); leave_all = true; } mrp->leave_all_timeout = now + (MRP_LVATIMER_MS + (random() % (MRP_LVATIMER_MS / 2))) @@ -93,7 +93,7 @@ static void mrp_periodic(void *data, uint64_t now) if (now > mrp->join_timeout) { if (mrp->join_timeout > 0) { - uint8_t event = leave_all ? AVBTP_MRP_EVENT_TX_LVA : AVBTP_MRP_EVENT_TX; + uint8_t event = leave_all ? AVB_MRP_EVENT_TX_LVA : AVB_MRP_EVENT_TX; global_event(mrp, now, event); } mrp->join_timeout = now + MRP_JOINTIMER_MS * SPA_NSEC_PER_MSEC; @@ -102,7 +102,7 @@ static void mrp_periodic(void *data, uint64_t now) spa_list_for_each(a, &mrp->attributes, link) { if (a->leave_timeout > 0 && now > a->leave_timeout) { a->leave_timeout = 0; - avbtp_mrp_update_state((struct avbtp_mrp*)mrp, now, &a->attr, AVBTP_MRP_EVENT_LV_TIMER); + avb_mrp_update_state((struct avb_mrp*)mrp, now, &a->attr, AVB_MRP_EVENT_LV_TIMER); } if (a->attr.pending_notify) { mrp_emit_notify(mrp, now, &a->attr, a->attr.pending_notify); @@ -112,19 +112,19 @@ static void mrp_periodic(void *data, uint64_t now) } static const struct server_events server_events = { - AVBTP_VERSION_SERVER_EVENTS, + AVB_VERSION_SERVER_EVENTS, .destroy = mrp_destroy, .periodic = mrp_periodic, }; -int avbtp_mrp_parse_packet(struct avbtp_mrp *mrp, uint64_t now, const void *pkt, int len, - const struct avbtp_mrp_parse_info *info, void *data) +int avb_mrp_parse_packet(struct avb_mrp *mrp, uint64_t now, const void *pkt, int len, + const struct avb_mrp_parse_info *info, void *data) { uint8_t *e = SPA_PTROFF(pkt, len, uint8_t); - uint8_t *m = SPA_PTROFF(pkt, sizeof(struct avbtp_packet_mrp), uint8_t); + uint8_t *m = SPA_PTROFF(pkt, sizeof(struct avb_packet_mrp), uint8_t); while (m < e && (m[0] != 0 || m[1] != 0)) { - const struct avbtp_packet_mrp_hdr *hdr = (const struct avbtp_packet_mrp_hdr*)m; + const struct avb_packet_mrp_hdr *hdr = (const struct avb_packet_mrp_hdr*)m; uint8_t attr_type = hdr->attribute_type; uint8_t attr_len = hdr->attribute_length; size_t hdr_size; @@ -136,9 +136,9 @@ int avbtp_mrp_parse_packet(struct avbtp_mrp *mrp, uint64_t now, const void *pkt, m += hdr_size; while (m < e && (m[0] != 0 || m[1] != 0)) { - const struct avbtp_packet_mrp_vector *v = - (const struct avbtp_packet_mrp_vector*)m; - uint16_t i, num_values = AVBTP_MRP_VECTOR_GET_NUM_VALUES(v); + const struct avb_packet_mrp_vector *v = + (const struct avb_packet_mrp_vector*)m; + uint16_t i, num_values = AVB_MRP_VECTOR_GET_NUM_VALUES(v); uint8_t event_len = (num_values+2)/3; uint8_t param_len = has_param ? (num_values+3)/4 : 0; int plen = sizeof(*v) + attr_len + event_len + param_len; @@ -149,7 +149,7 @@ int avbtp_mrp_parse_packet(struct avbtp_mrp *mrp, uint64_t now, const void *pkt, return -EPROTO; if (v->lva) - info->attr_event(data, now, attr_type, AVBTP_MRP_EVENT_RX_LVA); + info->attr_event(data, now, attr_type, AVB_MRP_EVENT_RX_LVA); for (i = 0; i < num_values; i++) { if (i % 3 == 0) { @@ -175,7 +175,7 @@ int avbtp_mrp_parse_packet(struct avbtp_mrp *mrp, uint64_t now, const void *pkt, return 0; } -struct avbtp_mrp_attribute *avbtp_mrp_attribute_new(struct avbtp_mrp *m, +struct avb_mrp_attribute *avb_mrp_attribute_new(struct avb_mrp *m, size_t user_size) { struct mrp *mrp = (struct mrp*)m; @@ -191,50 +191,50 @@ struct avbtp_mrp_attribute *avbtp_mrp_attribute_new(struct avbtp_mrp *m, return &a->attr; } -static uint8_t get_pending_send(struct avbtp_mrp *mrp, struct attribute *a, bool leave_all) +static uint8_t get_pending_send(struct avb_mrp *mrp, struct attribute *a, bool leave_all) { uint8_t send = 0; switch (a->applicant_state) { - case AVBTP_MRP_VP: - case AVBTP_MRP_AA: - case AVBTP_MRP_AP: - case AVBTP_MRP_QA: - case AVBTP_MRP_QP: - if (leave_all && a->applicant_state == AVBTP_MRP_VP) { + case AVB_MRP_VP: + case AVB_MRP_AA: + case AVB_MRP_AP: + case AVB_MRP_QA: + case AVB_MRP_QP: + if (leave_all && a->applicant_state == AVB_MRP_VP) { switch (a->registrar_state) { - case AVBTP_MRP_IN: - send = AVBTP_MRP_SEND_IN; + case AVB_MRP_IN: + send = AVB_MRP_SEND_IN; break; default: - send = AVBTP_MRP_SEND_MT; + send = AVB_MRP_SEND_MT; break; } - } else if (leave_all || a->applicant_state != AVBTP_MRP_QP) { + } else if (leave_all || a->applicant_state != AVB_MRP_QP) { switch (a->registrar_state) { - case AVBTP_MRP_IN: - send = AVBTP_MRP_SEND_JOININ; + case AVB_MRP_IN: + send = AVB_MRP_SEND_JOININ; break; default: - send = AVBTP_MRP_SEND_JOINMT; + send = AVB_MRP_SEND_JOINMT; break; } } break; - case AVBTP_MRP_VN: - case AVBTP_MRP_AN: - send = AVBTP_MRP_SEND_NEW; + case AVB_MRP_VN: + case AVB_MRP_AN: + send = AVB_MRP_SEND_NEW; break; - case AVBTP_MRP_LA: - send = AVBTP_MRP_SEND_LV; + case AVB_MRP_LA: + send = AVB_MRP_SEND_LV; break; - case AVBTP_MRP_LO: + case AVB_MRP_LO: switch (a->registrar_state) { - case AVBTP_MRP_IN: - send = AVBTP_MRP_SEND_IN; + case AVB_MRP_IN: + send = AVB_MRP_SEND_IN; break; default: - send = AVBTP_MRP_SEND_MT; + send = AVB_MRP_SEND_MT; break; } break; @@ -242,8 +242,8 @@ static uint8_t get_pending_send(struct avbtp_mrp *mrp, struct attribute *a, bool return send; } -void avbtp_mrp_update_state(struct avbtp_mrp *mrp, uint64_t now, - struct avbtp_mrp_attribute *attr, int event) +void avb_mrp_update_state(struct avb_mrp *mrp, uint64_t now, + struct avb_mrp_attribute *attr, int event) { struct attribute *a = SPA_CONTAINER_OF(attr, struct attribute, attr); uint8_t notify = 0, state; @@ -252,62 +252,62 @@ void avbtp_mrp_update_state(struct avbtp_mrp *mrp, uint64_t now, state = a->registrar_state; switch (event) { - case AVBTP_MRP_EVENT_BEGIN: - state = AVBTP_MRP_MT; + case AVB_MRP_EVENT_BEGIN: + state = AVB_MRP_MT; break; - case AVBTP_MRP_EVENT_RX_NEW: - notify = AVBTP_MRP_NOTIFY_JOIN_NEW; + case AVB_MRP_EVENT_RX_NEW: + notify = AVB_MRP_NOTIFY_JOIN_NEW; switch (state) { - case AVBTP_MRP_LV: + case AVB_MRP_LV: a->leave_timeout = 0; SPA_FALLTHROUGH; - case AVBTP_MRP_MT: - case AVBTP_MRP_IN: - state = AVBTP_MRP_IN; + case AVB_MRP_MT: + case AVB_MRP_IN: + state = AVB_MRP_IN; break; } break; - case AVBTP_MRP_EVENT_RX_JOININ: - case AVBTP_MRP_EVENT_RX_JOINMT: + case AVB_MRP_EVENT_RX_JOININ: + case AVB_MRP_EVENT_RX_JOINMT: switch (state) { - case AVBTP_MRP_LV: + case AVB_MRP_LV: a->leave_timeout = 0; SPA_FALLTHROUGH; - case AVBTP_MRP_MT: - notify = AVBTP_MRP_NOTIFY_JOIN; + case AVB_MRP_MT: + notify = AVB_MRP_NOTIFY_JOIN; SPA_FALLTHROUGH; - case AVBTP_MRP_IN: - state = AVBTP_MRP_IN; + case AVB_MRP_IN: + state = AVB_MRP_IN; break; } break; - case AVBTP_MRP_EVENT_RX_LV: - notify = AVBTP_MRP_NOTIFY_LEAVE; + case AVB_MRP_EVENT_RX_LV: + notify = AVB_MRP_NOTIFY_LEAVE; SPA_FALLTHROUGH; - case AVBTP_MRP_EVENT_RX_LVA: - case AVBTP_MRP_EVENT_TX_LVA: - case AVBTP_MRP_EVENT_REDECLARE: + case AVB_MRP_EVENT_RX_LVA: + case AVB_MRP_EVENT_TX_LVA: + case AVB_MRP_EVENT_REDECLARE: switch (state) { - case AVBTP_MRP_IN: + case AVB_MRP_IN: a->leave_timeout = now + MRP_LVTIMER_MS * SPA_NSEC_PER_MSEC; - state = AVBTP_MRP_LV; + state = AVB_MRP_LV; break; } break; - case AVBTP_MRP_EVENT_LV_TIMER: + case AVB_MRP_EVENT_LV_TIMER: switch (state) { - case AVBTP_MRP_LV: - notify = AVBTP_MRP_NOTIFY_LEAVE; + case AVB_MRP_LV: + notify = AVB_MRP_NOTIFY_LEAVE; break; } break; - case AVBTP_MRP_EVENT_FLUSH: - notify = AVBTP_MRP_NOTIFY_LEAVE; + case AVB_MRP_EVENT_FLUSH: + notify = AVB_MRP_NOTIFY_LEAVE; switch (state) { - case AVBTP_MRP_LV: - case AVBTP_MRP_MT: - case AVBTP_MRP_IN: - state = AVBTP_MRP_MT; + case AVB_MRP_LV: + case AVB_MRP_MT: + case AVB_MRP_IN: + state = AVB_MRP_MT; break; } break; @@ -323,185 +323,185 @@ void avbtp_mrp_update_state(struct avbtp_mrp *mrp, uint64_t now, state = a->applicant_state; switch (event) { - case AVBTP_MRP_EVENT_BEGIN: - state = AVBTP_MRP_VO; + case AVB_MRP_EVENT_BEGIN: + state = AVB_MRP_VO; break; - case AVBTP_MRP_EVENT_NEW: + case AVB_MRP_EVENT_NEW: switch (state) { - case AVBTP_MRP_VN: - case AVBTP_MRP_AN: + case AVB_MRP_VN: + case AVB_MRP_AN: break; default: - state = AVBTP_MRP_VN; + state = AVB_MRP_VN; break; } break; - case AVBTP_MRP_EVENT_JOIN: + case AVB_MRP_EVENT_JOIN: switch (state) { - case AVBTP_MRP_VO: - case AVBTP_MRP_LO: - state = AVBTP_MRP_VP; + case AVB_MRP_VO: + case AVB_MRP_LO: + state = AVB_MRP_VP; break; - case AVBTP_MRP_LA: - state = AVBTP_MRP_AA; + case AVB_MRP_LA: + state = AVB_MRP_AA; break; - case AVBTP_MRP_AO: - state = AVBTP_MRP_AP; + case AVB_MRP_AO: + state = AVB_MRP_AP; break; - case AVBTP_MRP_QO: - state = AVBTP_MRP_QP; + case AVB_MRP_QO: + state = AVB_MRP_QP; break; } break; - case AVBTP_MRP_EVENT_LV: + case AVB_MRP_EVENT_LV: switch (state) { - case AVBTP_MRP_QP: - state = AVBTP_MRP_QO; + case AVB_MRP_QP: + state = AVB_MRP_QO; break; - case AVBTP_MRP_AP: - state = AVBTP_MRP_AO; + case AVB_MRP_AP: + state = AVB_MRP_AO; break; - case AVBTP_MRP_VP: - state = AVBTP_MRP_VO; + case AVB_MRP_VP: + state = AVB_MRP_VO; break; - case AVBTP_MRP_VN: - case AVBTP_MRP_AN: - case AVBTP_MRP_AA: - case AVBTP_MRP_QA: - state = AVBTP_MRP_LA; + case AVB_MRP_VN: + case AVB_MRP_AN: + case AVB_MRP_AA: + case AVB_MRP_QA: + state = AVB_MRP_LA; break; } break; - case AVBTP_MRP_EVENT_RX_JOININ: + case AVB_MRP_EVENT_RX_JOININ: switch (state) { - case AVBTP_MRP_VO: - state = AVBTP_MRP_AO; + case AVB_MRP_VO: + state = AVB_MRP_AO; break; - case AVBTP_MRP_VP: - state = AVBTP_MRP_AP; + case AVB_MRP_VP: + state = AVB_MRP_AP; break; - case AVBTP_MRP_AA: - state = AVBTP_MRP_QA; + case AVB_MRP_AA: + state = AVB_MRP_QA; break; - case AVBTP_MRP_AO: - state = AVBTP_MRP_QO; + case AVB_MRP_AO: + state = AVB_MRP_QO; break; - case AVBTP_MRP_AP: - state = AVBTP_MRP_QP; + case AVB_MRP_AP: + state = AVB_MRP_QP; break; } SPA_FALLTHROUGH; - case AVBTP_MRP_EVENT_RX_IN: + case AVB_MRP_EVENT_RX_IN: switch (state) { - case AVBTP_MRP_AA: - state = AVBTP_MRP_QA; + case AVB_MRP_AA: + state = AVB_MRP_QA; break; } SPA_FALLTHROUGH; - case AVBTP_MRP_EVENT_RX_JOINMT: - case AVBTP_MRP_EVENT_RX_MT: + case AVB_MRP_EVENT_RX_JOINMT: + case AVB_MRP_EVENT_RX_MT: switch (state) { - case AVBTP_MRP_QA: - state = AVBTP_MRP_AA; + case AVB_MRP_QA: + state = AVB_MRP_AA; break; - case AVBTP_MRP_QO: - state = AVBTP_MRP_AO; + case AVB_MRP_QO: + state = AVB_MRP_AO; break; - case AVBTP_MRP_QP: - state = AVBTP_MRP_AP; + case AVB_MRP_QP: + state = AVB_MRP_AP; break; - case AVBTP_MRP_LO: - state = AVBTP_MRP_VO; + case AVB_MRP_LO: + state = AVB_MRP_VO; break; } break; - case AVBTP_MRP_EVENT_RX_LV: - case AVBTP_MRP_EVENT_RX_LVA: - case AVBTP_MRP_EVENT_REDECLARE: + case AVB_MRP_EVENT_RX_LV: + case AVB_MRP_EVENT_RX_LVA: + case AVB_MRP_EVENT_REDECLARE: switch (state) { - case AVBTP_MRP_VO: - case AVBTP_MRP_AO: - case AVBTP_MRP_QO: - state = AVBTP_MRP_LO; + case AVB_MRP_VO: + case AVB_MRP_AO: + case AVB_MRP_QO: + state = AVB_MRP_LO; break; - case AVBTP_MRP_AN: - state = AVBTP_MRP_VN; + case AVB_MRP_AN: + state = AVB_MRP_VN; break; - case AVBTP_MRP_AA: - case AVBTP_MRP_QA: - case AVBTP_MRP_AP: - case AVBTP_MRP_QP: - state = AVBTP_MRP_VP; + case AVB_MRP_AA: + case AVB_MRP_QA: + case AVB_MRP_AP: + case AVB_MRP_QP: + state = AVB_MRP_VP; break; } break; - case AVBTP_MRP_EVENT_PERIODIC: + case AVB_MRP_EVENT_PERIODIC: switch (state) { - case AVBTP_MRP_QA: - state = AVBTP_MRP_AA; + case AVB_MRP_QA: + state = AVB_MRP_AA; break; - case AVBTP_MRP_QP: - state = AVBTP_MRP_AP; + case AVB_MRP_QP: + state = AVB_MRP_AP; break; } break; - case AVBTP_MRP_EVENT_TX: + case AVB_MRP_EVENT_TX: switch (state) { - case AVBTP_MRP_VP: - case AVBTP_MRP_VN: - case AVBTP_MRP_AN: - case AVBTP_MRP_AA: - case AVBTP_MRP_LA: - case AVBTP_MRP_AP: - case AVBTP_MRP_LO: + case AVB_MRP_VP: + case AVB_MRP_VN: + case AVB_MRP_AN: + case AVB_MRP_AA: + case AVB_MRP_LA: + case AVB_MRP_AP: + case AVB_MRP_LO: send = get_pending_send(mrp, a, false); } switch (state) { - case AVBTP_MRP_VP: - state = AVBTP_MRP_AA; + case AVB_MRP_VP: + state = AVB_MRP_AA; break; - case AVBTP_MRP_VN: - state = AVBTP_MRP_AN; + case AVB_MRP_VN: + state = AVB_MRP_AN; break; - case AVBTP_MRP_AN: - case AVBTP_MRP_AA: - case AVBTP_MRP_AP: - state = AVBTP_MRP_QA; + case AVB_MRP_AN: + case AVB_MRP_AA: + case AVB_MRP_AP: + state = AVB_MRP_QA; break; - case AVBTP_MRP_LA: - case AVBTP_MRP_LO: - state = AVBTP_MRP_VO; + case AVB_MRP_LA: + case AVB_MRP_LO: + state = AVB_MRP_VO; break; } break; - case AVBTP_MRP_EVENT_TX_LVA: + case AVB_MRP_EVENT_TX_LVA: { switch (state) { - case AVBTP_MRP_VP: - case AVBTP_MRP_VN: - case AVBTP_MRP_AN: - case AVBTP_MRP_AA: - case AVBTP_MRP_LA: - case AVBTP_MRP_QA: - case AVBTP_MRP_AP: - case AVBTP_MRP_QP: + case AVB_MRP_VP: + case AVB_MRP_VN: + case AVB_MRP_AN: + case AVB_MRP_AA: + case AVB_MRP_LA: + case AVB_MRP_QA: + case AVB_MRP_AP: + case AVB_MRP_QP: send = get_pending_send(mrp, a, true); } switch (state) { - case AVBTP_MRP_VO: - case AVBTP_MRP_LA: - case AVBTP_MRP_AO: - case AVBTP_MRP_QO: - state = AVBTP_MRP_LO; + case AVB_MRP_VO: + case AVB_MRP_LA: + case AVB_MRP_AO: + case AVB_MRP_QO: + state = AVB_MRP_LO; break; - case AVBTP_MRP_VN: - state = AVBTP_MRP_AN; + case AVB_MRP_VN: + state = AVB_MRP_AN; break; - case AVBTP_MRP_AN: - case AVBTP_MRP_AA: - case AVBTP_MRP_AP: - case AVBTP_MRP_QP: - state = AVBTP_MRP_QA; + case AVB_MRP_AN: + case AVB_MRP_AA: + case AVB_MRP_AP: + case AVB_MRP_QP: + state = AVB_MRP_QA; break; } break; @@ -516,46 +516,46 @@ void avbtp_mrp_update_state(struct avbtp_mrp *mrp, uint64_t now, a->attr.pending_send = send; } -void avbtp_mrp_rx_event(struct avbtp_mrp *mrp, uint64_t now, - struct avbtp_mrp_attribute *attr, uint8_t event) +void avb_mrp_rx_event(struct avb_mrp *mrp, uint64_t now, + struct avb_mrp_attribute *attr, uint8_t event) { static const int map[] = { - [AVBTP_MRP_ATTRIBUTE_EVENT_NEW] = AVBTP_MRP_EVENT_RX_NEW, - [AVBTP_MRP_ATTRIBUTE_EVENT_JOININ] = AVBTP_MRP_EVENT_RX_JOININ, - [AVBTP_MRP_ATTRIBUTE_EVENT_IN] = AVBTP_MRP_EVENT_RX_IN, - [AVBTP_MRP_ATTRIBUTE_EVENT_JOINMT] = AVBTP_MRP_EVENT_RX_JOINMT, - [AVBTP_MRP_ATTRIBUTE_EVENT_MT] = AVBTP_MRP_EVENT_RX_MT, - [AVBTP_MRP_ATTRIBUTE_EVENT_LV] = AVBTP_MRP_EVENT_RX_LV, + [AVB_MRP_ATTRIBUTE_EVENT_NEW] = AVB_MRP_EVENT_RX_NEW, + [AVB_MRP_ATTRIBUTE_EVENT_JOININ] = AVB_MRP_EVENT_RX_JOININ, + [AVB_MRP_ATTRIBUTE_EVENT_IN] = AVB_MRP_EVENT_RX_IN, + [AVB_MRP_ATTRIBUTE_EVENT_JOINMT] = AVB_MRP_EVENT_RX_JOINMT, + [AVB_MRP_ATTRIBUTE_EVENT_MT] = AVB_MRP_EVENT_RX_MT, + [AVB_MRP_ATTRIBUTE_EVENT_LV] = AVB_MRP_EVENT_RX_LV, }; - avbtp_mrp_update_state(mrp, now, attr, map[event]); + avb_mrp_update_state(mrp, now, attr, map[event]); } -void avbtp_mrp_mad_begin(struct avbtp_mrp *mrp, uint64_t now, struct avbtp_mrp_attribute *attr) +void avb_mrp_mad_begin(struct avb_mrp *mrp, uint64_t now, struct avb_mrp_attribute *attr) { struct attribute *a = SPA_CONTAINER_OF(attr, struct attribute, attr); a->leave_timeout = 0; - avbtp_mrp_update_state(mrp, now, attr, AVBTP_MRP_EVENT_BEGIN); + avb_mrp_update_state(mrp, now, attr, AVB_MRP_EVENT_BEGIN); } -void avbtp_mrp_mad_join(struct avbtp_mrp *mrp, uint64_t now, struct avbtp_mrp_attribute *attr, bool is_new) +void avb_mrp_mad_join(struct avb_mrp *mrp, uint64_t now, struct avb_mrp_attribute *attr, bool is_new) { if (is_new) - avbtp_mrp_update_state(mrp, now, attr, AVBTP_MRP_EVENT_NEW); + avb_mrp_update_state(mrp, now, attr, AVB_MRP_EVENT_NEW); else - avbtp_mrp_update_state(mrp, now, attr, AVBTP_MRP_EVENT_JOIN); + avb_mrp_update_state(mrp, now, attr, AVB_MRP_EVENT_JOIN); } -void avbtp_mrp_mad_leave(struct avbtp_mrp *mrp, uint64_t now, struct avbtp_mrp_attribute *attr) +void avb_mrp_mad_leave(struct avb_mrp *mrp, uint64_t now, struct avb_mrp_attribute *attr) { - avbtp_mrp_update_state(mrp, now, attr, AVBTP_MRP_EVENT_LV); + avb_mrp_update_state(mrp, now, attr, AVB_MRP_EVENT_LV); } -void avbtp_mrp_destroy(struct avbtp_mrp *mrp) +void avb_mrp_destroy(struct avb_mrp *mrp) { mrp_destroy(mrp); } -struct avbtp_mrp *avbtp_mrp_new(struct server *server) +struct avb_mrp *avb_mrp_new(struct server *server) { struct mrp *mrp; @@ -569,11 +569,11 @@ struct avbtp_mrp *avbtp_mrp_new(struct server *server) avdecc_server_add_listener(server, &mrp->server_listener, &server_events, mrp); - return (struct avbtp_mrp*)mrp; + return (struct avb_mrp*)mrp; } -void avbtp_mrp_add_listener(struct avbtp_mrp *m, struct spa_hook *listener, - const struct avbtp_mrp_events *events, void *data) +void avb_mrp_add_listener(struct avb_mrp *m, struct spa_hook *listener, + const struct avb_mrp_events *events, void *data) { struct mrp *mrp = (struct mrp*)m; spa_hook_list_append(&mrp->listener_list, listener, events, data); diff --git a/src/modules/module-avb/mrp.h b/src/modules/module-avb/mrp.h new file mode 100644 index 000000000..8f78a3b49 --- /dev/null +++ b/src/modules/module-avb/mrp.h @@ -0,0 +1,171 @@ +/* AVB support + * + * Copyright © 2022 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef AVB_MRP_H +#define AVB_MRP_H + +#include "packets.h" +#include "internal.h" + +#define AVB_MRP_PROTOCOL_VERSION 0 + +struct avb_packet_mrp { + struct avb_ethernet_header eth; + uint8_t version; +} __attribute__ ((__packed__)); + +struct avb_packet_mrp_hdr { + uint8_t attribute_type; + uint8_t attribute_length; +} __attribute__ ((__packed__)); + +struct avb_packet_mrp_vector { +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned lva:3; + unsigned nv1:5; +#elif __BYTE_ORDER == __LITTLE_ENDIAN + unsigned nv1:5; + unsigned lva:3; +#endif + uint8_t nv2; + uint8_t first_value[0]; +} __attribute__ ((__packed__)); + +#define AVB_MRP_VECTOR_SET_NUM_VALUES(a,v) ((a)->nv1 = ((v) >> 8),(a)->nv2 = (v)) +#define AVB_MRP_VECTOR_GET_NUM_VALUES(a) ((a)->nv1 << 8 | (a)->nv2) + +struct avb_packet_mrp_footer { + uint16_t end_mark; +} __attribute__ ((__packed__)); + +/* applicant states */ +#define AVB_MRP_VO 0 /* Very anxious Observer */ +#define AVB_MRP_VP 1 /* Very anxious Passive */ +#define AVB_MRP_VN 2 /* Very anxious New */ +#define AVB_MRP_AN 3 /* Anxious New */ +#define AVB_MRP_AA 4 /* Anxious Active */ +#define AVB_MRP_QA 5 /* Quiet Active */ +#define AVB_MRP_LA 6 /* Leaving Active */ +#define AVB_MRP_AO 7 /* Anxious Observer */ +#define AVB_MRP_QO 8 /* Quiet Observer */ +#define AVB_MRP_AP 9 /* Anxious Passive */ +#define AVB_MRP_QP 10 /* Quiet Passive */ +#define AVB_MRP_LO 11 /* Leaving Observer */ + +/* registrar states */ +#define AVB_MRP_IN 16 +#define AVB_MRP_LV 17 +#define AVB_MRP_MT 18 + +/* events */ +#define AVB_MRP_EVENT_BEGIN 0 +#define AVB_MRP_EVENT_NEW 1 +#define AVB_MRP_EVENT_JOIN 2 +#define AVB_MRP_EVENT_LV 3 +#define AVB_MRP_EVENT_TX 4 +#define AVB_MRP_EVENT_TX_LVA 5 +#define AVB_MRP_EVENT_TX_LVAF 6 +#define AVB_MRP_EVENT_RX_NEW 7 +#define AVB_MRP_EVENT_RX_JOININ 8 +#define AVB_MRP_EVENT_RX_IN 9 +#define AVB_MRP_EVENT_RX_JOINMT 10 +#define AVB_MRP_EVENT_RX_MT 11 +#define AVB_MRP_EVENT_RX_LV 12 +#define AVB_MRP_EVENT_RX_LVA 13 +#define AVB_MRP_EVENT_FLUSH 14 +#define AVB_MRP_EVENT_REDECLARE 15 +#define AVB_MRP_EVENT_PERIODIC 16 +#define AVB_MRP_EVENT_LV_TIMER 17 +#define AVB_MRP_EVENT_LVA_TIMER 18 + +/* attribute events */ +#define AVB_MRP_ATTRIBUTE_EVENT_NEW 0 +#define AVB_MRP_ATTRIBUTE_EVENT_JOININ 1 +#define AVB_MRP_ATTRIBUTE_EVENT_IN 2 +#define AVB_MRP_ATTRIBUTE_EVENT_JOINMT 3 +#define AVB_MRP_ATTRIBUTE_EVENT_MT 4 +#define AVB_MRP_ATTRIBUTE_EVENT_LV 5 + +#define AVB_MRP_SEND_NEW 1 +#define AVB_MRP_SEND_JOININ 2 +#define AVB_MRP_SEND_IN 3 +#define AVB_MRP_SEND_JOINMT 4 +#define AVB_MRP_SEND_MT 5 +#define AVB_MRP_SEND_LV 6 + +#define AVB_MRP_NOTIFY_JOIN_NEW (1u<<0) +#define AVB_MRP_NOTIFY_JOIN (1u<<1) +#define AVB_MRP_NOTIFY_LEAVE (1u<<2) + +struct avb_mrp_attribute { + uint8_t pending_send; + uint8_t pending_notify; + void *user_data; +}; + +struct avb_mrp_parse_info { +#define AVB_VERSION_MRP_PARSE_INFO 0 + uint32_t version; + + bool (*check_header) (void *data, const void *hdr, size_t *hdr_size, bool *has_params); + + int (*attr_event) (void *data, uint64_t now, uint8_t attribute_type, uint8_t event); + + int (*process) (void *data, uint64_t now, uint8_t attribute_type, const void *value, + uint8_t event, uint8_t param, int index); +}; + + +int avb_mrp_parse_packet(struct avb_mrp *mrp, uint64_t now, const void *pkt, int size, + const struct avb_mrp_parse_info *cb, void *data); + +struct avb_mrp_attribute *avb_mrp_attribute_new(struct avb_mrp *mrp, + size_t user_size); + +void avb_mrp_update_state(struct avb_mrp *mrp, uint64_t now, + struct avb_mrp_attribute *attr, int event); + +void avb_mrp_rx_event(struct avb_mrp *mrp, uint64_t now, + struct avb_mrp_attribute *attr, uint8_t event); + +void avb_mrp_mad_begin(struct avb_mrp *mrp, uint64_t now, struct avb_mrp_attribute *attr); +void avb_mrp_mad_join(struct avb_mrp *mrp, uint64_t now, struct avb_mrp_attribute *attr, bool is_new); +void avb_mrp_mad_leave(struct avb_mrp *mrp, uint64_t now, struct avb_mrp_attribute *attr); + +struct avb_mrp_events { +#define AVB_VERSION_MRP_ATTRIBUTE_CALLBACKS 0 + uint32_t version; + + void (*event) (void *data, uint64_t now, uint8_t event); + + void (*notify) (void *data, uint64_t now, struct avb_mrp_attribute *attr, uint8_t notify); +}; + +struct avb_mrp *avb_mrp_new(struct server *server); +void avb_mrp_destroy(struct avb_mrp *mrp); + +void avb_mrp_add_listener(struct avb_mrp *mrp, struct spa_hook *listener, + const struct avb_mrp_events *events, void *data); + +#endif /* AVB_MRP_H */ diff --git a/src/modules/module-avbtp/msrp.c b/src/modules/module-avb/msrp.c similarity index 68% rename from src/modules/module-avbtp/msrp.c rename to src/modules/module-avb/msrp.c index d9b891a12..9a15ed94a 100644 --- a/src/modules/module-avbtp/msrp.c +++ b/src/modules/module-avb/msrp.c @@ -32,7 +32,7 @@ static const uint8_t mac[6] = AVB_MSRP_MAC; struct attr { - struct avbtp_msrp_attribute attr; + struct avb_msrp_attribute attr; struct spa_list link; }; @@ -44,11 +44,11 @@ struct msrp { struct spa_list attributes; }; -static void debug_msrp_talker_common(const struct avbtp_packet_msrp_talker *t) +static void debug_msrp_talker_common(const struct avb_packet_msrp_talker *t) { char buf[128]; - pw_log_info(" stream-id: %s", avbtp_utils_format_id(buf, sizeof(buf), be64toh(t->stream_id))); - pw_log_info(" dest-addr: %s", avbtp_utils_format_addr(buf, sizeof(buf), t->dest_addr)); + pw_log_info(" stream-id: %s", avb_utils_format_id(buf, sizeof(buf), be64toh(t->stream_id))); + pw_log_info(" dest-addr: %s", avb_utils_format_addr(buf, sizeof(buf), t->dest_addr)); pw_log_info(" vlan-id: %d", ntohs(t->vlan_id)); pw_log_info(" tspec-max-frame-size: %d", ntohs(t->tspec_max_frame_size)); pw_log_info(" tspec-max-interval-frames: %d", ntohs(t->tspec_max_interval_frames)); @@ -57,7 +57,7 @@ static void debug_msrp_talker_common(const struct avbtp_packet_msrp_talker *t) pw_log_info(" accumulated-latency: %d", ntohl(t->accumulated_latency)); } -static void debug_msrp_talker(const struct avbtp_packet_msrp_talker *t) +static void debug_msrp_talker(const struct avb_packet_msrp_talker *t) { pw_log_info("talker"); debug_msrp_talker_common(t); @@ -72,30 +72,30 @@ static void notify_talker(struct msrp *msrp, uint64_t now, struct attr *attr, ui static int process_talker(struct msrp *msrp, uint64_t now, uint8_t attr_type, const void *m, uint8_t event, uint8_t param, int num) { - const struct avbtp_packet_msrp_talker *t = m; + const struct avb_packet_msrp_talker *t = m; struct attr *a; spa_list_for_each(a, &msrp->attributes, link) if (a->attr.type == attr_type && a->attr.attr.talker.stream_id == t->stream_id) { a->attr.attr.talker = *t; - avbtp_mrp_rx_event(msrp->server->mrp, now, a->attr.mrp, event); + avb_mrp_rx_event(msrp->server->mrp, now, a->attr.mrp, event); } return 0; } -static void debug_msrp_talker_fail(const struct avbtp_packet_msrp_talker_fail *t) +static void debug_msrp_talker_fail(const struct avb_packet_msrp_talker_fail *t) { char buf[128]; pw_log_info("talker fail"); debug_msrp_talker_common(&t->talker); - pw_log_info(" bridge-id: %s", avbtp_utils_format_id(buf, sizeof(buf), be64toh(t->bridge_id))); + pw_log_info(" bridge-id: %s", avb_utils_format_id(buf, sizeof(buf), be64toh(t->bridge_id))); pw_log_info(" failure-code: %d", t->failure_code); } static int process_talker_fail(struct msrp *msrp, uint64_t now, uint8_t attr_type, const void *m, uint8_t event, uint8_t param, int num) { - const struct avbtp_packet_msrp_talker_fail *t = m; + const struct avb_packet_msrp_talker_fail *t = m; struct attr *a; debug_msrp_talker_fail(t); @@ -103,15 +103,15 @@ static int process_talker_fail(struct msrp *msrp, uint64_t now, uint8_t attr_typ spa_list_for_each(a, &msrp->attributes, link) if (a->attr.type == attr_type && a->attr.attr.talker_fail.talker.stream_id == t->talker.stream_id) - avbtp_mrp_rx_event(msrp->server->mrp, now, a->attr.mrp, event); + avb_mrp_rx_event(msrp->server->mrp, now, a->attr.mrp, event); return 0; } -static void debug_msrp_listener(const struct avbtp_packet_msrp_listener *l) +static void debug_msrp_listener(const struct avb_packet_msrp_listener *l) { char buf[128]; pw_log_info("listener"); - pw_log_info(" %s", avbtp_utils_format_id(buf, sizeof(buf), be64toh(l->stream_id))); + pw_log_info(" %s", avb_utils_format_id(buf, sizeof(buf), be64toh(l->stream_id))); } static void notify_listener(struct msrp *msrp, uint64_t now, struct attr *attr, uint8_t notify) @@ -123,32 +123,32 @@ static void notify_listener(struct msrp *msrp, uint64_t now, struct attr *attr, static int process_listener(struct msrp *msrp, uint64_t now, uint8_t attr_type, const void *m, uint8_t event, uint8_t param, int num) { - const struct avbtp_packet_msrp_listener *l = m; + const struct avb_packet_msrp_listener *l = m; struct attr *a; spa_list_for_each(a, &msrp->attributes, link) if (a->attr.type == attr_type && a->attr.attr.listener.stream_id == l->stream_id) - avbtp_mrp_rx_event(msrp->server->mrp, now, a->attr.mrp, event); + avb_mrp_rx_event(msrp->server->mrp, now, a->attr.mrp, event); return 0; } static int encode_listener(struct msrp *msrp, struct attr *a, void *m) { - struct avbtp_packet_msrp_msg *msg = m; - struct avbtp_packet_mrp_vector *v; - struct avbtp_packet_msrp_listener *l; - struct avbtp_packet_mrp_footer *f; + struct avb_packet_msrp_msg *msg = m; + struct avb_packet_mrp_vector *v; + struct avb_packet_msrp_listener *l; + struct avb_packet_mrp_footer *f; uint8_t *ev; size_t attr_list_length = sizeof(*v) + sizeof(*l) + sizeof(*f) + 1 + 1; - msg->attribute_type = AVBTP_MSRP_ATTRIBUTE_TYPE_LISTENER; + msg->attribute_type = AVB_MSRP_ATTRIBUTE_TYPE_LISTENER; msg->attribute_length = sizeof(*l); msg->attribute_list_length = htons(attr_list_length); - v = (struct avbtp_packet_mrp_vector *)msg->attribute_list; + v = (struct avb_packet_mrp_vector *)msg->attribute_list; v->lva = 0; - AVBTP_MRP_VECTOR_SET_NUM_VALUES(v, 1); + AVB_MRP_VECTOR_SET_NUM_VALUES(v, 1); - l = (struct avbtp_packet_msrp_listener *)v->first_value; + l = (struct avb_packet_msrp_listener *)v->first_value; *l = a->attr.attr.listener; ev = SPA_PTROFF(l, sizeof(*l), uint8_t); @@ -157,14 +157,14 @@ static int encode_listener(struct msrp *msrp, struct attr *a, void *m) ev = SPA_PTROFF(ev, sizeof(*ev), uint8_t); *ev = a->attr.param * 4 * 4 * 4; - f = SPA_PTROFF(ev, sizeof(*ev), struct avbtp_packet_mrp_footer); + f = SPA_PTROFF(ev, sizeof(*ev), struct avb_packet_mrp_footer); f->end_mark = 0; return attr_list_length + sizeof(*msg); } -static void debug_msrp_domain(const struct avbtp_packet_msrp_domain *d) +static void debug_msrp_domain(const struct avb_packet_msrp_domain *d) { pw_log_info("domain"); pw_log_info(" %d", d->sr_class_id); @@ -184,34 +184,34 @@ static int process_domain(struct msrp *msrp, uint64_t now, uint8_t attr_type, struct attr *a; spa_list_for_each(a, &msrp->attributes, link) if (a->attr.type == attr_type) - avbtp_mrp_rx_event(msrp->server->mrp, now, a->attr.mrp, event); + avb_mrp_rx_event(msrp->server->mrp, now, a->attr.mrp, event); return 0; } static int encode_domain(struct msrp *msrp, struct attr *a, void *m) { - struct avbtp_packet_msrp_msg *msg = m; - struct avbtp_packet_mrp_vector *v; - struct avbtp_packet_msrp_domain *d; - struct avbtp_packet_mrp_footer *f; + struct avb_packet_msrp_msg *msg = m; + struct avb_packet_mrp_vector *v; + struct avb_packet_msrp_domain *d; + struct avb_packet_mrp_footer *f; uint8_t *ev; size_t attr_list_length = sizeof(*v) + sizeof(*d) + sizeof(*f) + 1; - msg->attribute_type = AVBTP_MSRP_ATTRIBUTE_TYPE_DOMAIN; + msg->attribute_type = AVB_MSRP_ATTRIBUTE_TYPE_DOMAIN; msg->attribute_length = sizeof(*d); msg->attribute_list_length = htons(attr_list_length); - v = (struct avbtp_packet_mrp_vector *)msg->attribute_list; + v = (struct avb_packet_mrp_vector *)msg->attribute_list; v->lva = 0; - AVBTP_MRP_VECTOR_SET_NUM_VALUES(v, 1); + AVB_MRP_VECTOR_SET_NUM_VALUES(v, 1); - d = (struct avbtp_packet_msrp_domain *)v->first_value; + d = (struct avb_packet_msrp_domain *)v->first_value; *d = a->attr.attr.domain; ev = SPA_PTROFF(d, sizeof(*d), uint8_t); *ev = a->attr.mrp->pending_send * 36; - f = SPA_PTROFF(ev, sizeof(*ev), struct avbtp_packet_mrp_footer); + f = SPA_PTROFF(ev, sizeof(*ev), struct avb_packet_mrp_footer); f->end_mark = 0; return attr_list_length + sizeof(*msg); @@ -223,22 +223,22 @@ static const struct { int (*encode) (struct msrp *msrp, struct attr *attr, void *m); void (*notify) (struct msrp *msrp, uint64_t now, struct attr *attr, uint8_t notify); } dispatch[] = { - [AVBTP_MSRP_ATTRIBUTE_TYPE_TALKER_ADVERTISE] = { process_talker, NULL, notify_talker, }, - [AVBTP_MSRP_ATTRIBUTE_TYPE_TALKER_FAILED] = { process_talker_fail, NULL, NULL }, - [AVBTP_MSRP_ATTRIBUTE_TYPE_LISTENER] = { process_listener, encode_listener, notify_listener }, - [AVBTP_MSRP_ATTRIBUTE_TYPE_DOMAIN] = { process_domain, encode_domain, notify_domain, }, + [AVB_MSRP_ATTRIBUTE_TYPE_TALKER_ADVERTISE] = { process_talker, NULL, notify_talker, }, + [AVB_MSRP_ATTRIBUTE_TYPE_TALKER_FAILED] = { process_talker_fail, NULL, NULL }, + [AVB_MSRP_ATTRIBUTE_TYPE_LISTENER] = { process_listener, encode_listener, notify_listener }, + [AVB_MSRP_ATTRIBUTE_TYPE_DOMAIN] = { process_domain, encode_domain, notify_domain, }, }; static bool msrp_check_header(void *data, const void *hdr, size_t *hdr_size, bool *has_params) { - const struct avbtp_packet_msrp_msg *msg = hdr; + const struct avb_packet_msrp_msg *msg = hdr; uint8_t attr_type = msg->attribute_type; - if (!AVBTP_MSRP_ATTRIBUTE_TYPE_VALID(attr_type)) + if (!AVB_MSRP_ATTRIBUTE_TYPE_VALID(attr_type)) return false; *hdr_size = sizeof(*msg); - *has_params = attr_type == AVBTP_MSRP_ATTRIBUTE_TYPE_LISTENER; + *has_params = attr_type == AVB_MSRP_ATTRIBUTE_TYPE_LISTENER; return true; } @@ -248,7 +248,7 @@ static int msrp_attr_event(void *data, uint64_t now, uint8_t attribute_type, uin struct attr *a; spa_list_for_each(a, &msrp->attributes, link) if (a->attr.type == attribute_type) - avbtp_mrp_update_state(msrp->server->mrp, now, a->attr.mrp, event); + avb_mrp_update_state(msrp->server->mrp, now, a->attr.mrp, event); return 0; } @@ -260,8 +260,8 @@ static int msrp_process(void *data, uint64_t now, uint8_t attribute_type, const attribute_type, value, event, param, index); } -static const struct avbtp_mrp_parse_info info = { - AVBTP_VERSION_MRP_PARSE_INFO, +static const struct avb_mrp_parse_info info = { + AVB_VERSION_MRP_PARSE_INFO, .check_header = msrp_check_header, .attr_event = msrp_attr_event, .process = msrp_process, @@ -271,7 +271,7 @@ static const struct avbtp_mrp_parse_info info = { static int msrp_message(void *data, uint64_t now, const void *message, int len) { struct msrp *msrp = data; - const struct avbtp_packet_mrp *p = message; + const struct avb_packet_mrp *p = message; if (ntohs(p->eth.type) != AVB_MSRP_ETH) return 0; @@ -279,7 +279,7 @@ static int msrp_message(void *data, uint64_t now, const void *message, int len) return 0; pw_log_debug("MSRP"); - return avbtp_mrp_parse_packet(msrp->server->mrp, + return avb_mrp_parse_packet(msrp->server->mrp, now, message, len, &info, msrp); } @@ -291,19 +291,19 @@ static void msrp_destroy(void *data) } static const struct server_events server_events = { - AVBTP_VERSION_SERVER_EVENTS, + AVB_VERSION_SERVER_EVENTS, .destroy = msrp_destroy, .message = msrp_message }; -struct avbtp_msrp_attribute *avbtp_msrp_attribute_new(struct avbtp_msrp *m, +struct avb_msrp_attribute *avb_msrp_attribute_new(struct avb_msrp *m, uint8_t type) { struct msrp *msrp = (struct msrp*)m; - struct avbtp_mrp_attribute *attr; + struct avb_mrp_attribute *attr; struct attr *a; - attr = avbtp_mrp_attribute_new(msrp->server->mrp, sizeof(struct attr)); + attr = avb_mrp_attribute_new(msrp->server->mrp, sizeof(struct attr)); a = attr->user_data; a->attr.mrp = attr; @@ -317,14 +317,14 @@ static void msrp_event(void *data, uint64_t now, uint8_t event) { struct msrp *msrp = data; uint8_t buffer[2048]; - struct avbtp_packet_mrp *p = (struct avbtp_packet_mrp*)buffer; - struct avbtp_packet_mrp_footer *f; + struct avb_packet_mrp *p = (struct avb_packet_mrp*)buffer; + struct avb_packet_mrp_footer *f; void *msg = SPA_PTROFF(buffer, sizeof(*p), void); struct attr *a; int len, count = 0; size_t total = sizeof(*p) + 2; - p->version = AVBTP_MRP_PROTOCOL_VERSION; + p->version = AVB_MRP_PROTOCOL_VERSION; spa_list_for_each(a, &msrp->attributes, link) { if (!a->attr.mrp->pending_send) @@ -340,15 +340,15 @@ static void msrp_event(void *data, uint64_t now, uint8_t event) msg = SPA_PTROFF(msg, len, void); total += len; } - f = (struct avbtp_packet_mrp_footer *)msg; + f = (struct avb_packet_mrp_footer *)msg; f->end_mark = 0; if (count > 0) - avbtp_server_send_packet(msrp->server, mac, AVB_MSRP_ETH, + avb_server_send_packet(msrp->server, mac, AVB_MSRP_ETH, buffer, total); } -static void msrp_notify(void *data, uint64_t now, struct avbtp_mrp_attribute *attr, uint8_t notify) +static void msrp_notify(void *data, uint64_t now, struct avb_mrp_attribute *attr, uint8_t notify) { struct msrp *msrp = data; struct attr *a = attr->user_data; @@ -356,13 +356,13 @@ static void msrp_notify(void *data, uint64_t now, struct avbtp_mrp_attribute *at dispatch[a->attr.type].notify(msrp, now, a, notify); } -static const struct avbtp_mrp_events mrp_events = { - AVBTP_VERSION_MRP_ATTRIBUTE_CALLBACKS, +static const struct avb_mrp_events mrp_events = { + AVB_VERSION_MRP_ATTRIBUTE_CALLBACKS, .event = msrp_event, .notify = msrp_notify }; -struct avbtp_msrp *avbtp_msrp_register(struct server *server) +struct avb_msrp *avb_msrp_register(struct server *server) { struct msrp *msrp; @@ -374,7 +374,7 @@ struct avbtp_msrp *avbtp_msrp_register(struct server *server) spa_list_init(&msrp->attributes); avdecc_server_add_listener(server, &msrp->server_listener, &server_events, msrp); - avbtp_mrp_add_listener(server->mrp, &msrp->mrp_listener, &mrp_events, msrp); + avb_mrp_add_listener(server->mrp, &msrp->mrp_listener, &mrp_events, msrp); - return (struct avbtp_msrp*)msrp; + return (struct avb_msrp*)msrp; } diff --git a/src/modules/module-avbtp/msrp.h b/src/modules/module-avb/msrp.h similarity index 52% rename from src/modules/module-avbtp/msrp.h rename to src/modules/module-avb/msrp.h index 02f30798d..675392dc4 100644 --- a/src/modules/module-avbtp/msrp.h +++ b/src/modules/module-avb/msrp.h @@ -22,8 +22,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef AVBTP_MSRP_H -#define AVBTP_MSRP_H +#ifndef AVB_MSRP_H +#define AVB_MSRP_H #include "internal.h" #include "mrp.h" @@ -31,24 +31,24 @@ #define AVB_MSRP_ETH 0x22ea #define AVB_MSRP_MAC { 0x01, 0x80, 0xc2, 0x00, 0x00, 0xe }; -#define AVBTP_MSRP_ATTRIBUTE_TYPE_TALKER_ADVERTISE 1 -#define AVBTP_MSRP_ATTRIBUTE_TYPE_TALKER_FAILED 2 -#define AVBTP_MSRP_ATTRIBUTE_TYPE_LISTENER 3 -#define AVBTP_MSRP_ATTRIBUTE_TYPE_DOMAIN 4 -#define AVBTP_MSRP_ATTRIBUTE_TYPE_VALID(t) ((t)>=1 && (t)<=4) +#define AVB_MSRP_ATTRIBUTE_TYPE_TALKER_ADVERTISE 1 +#define AVB_MSRP_ATTRIBUTE_TYPE_TALKER_FAILED 2 +#define AVB_MSRP_ATTRIBUTE_TYPE_LISTENER 3 +#define AVB_MSRP_ATTRIBUTE_TYPE_DOMAIN 4 +#define AVB_MSRP_ATTRIBUTE_TYPE_VALID(t) ((t)>=1 && (t)<=4) -struct avbtp_packet_msrp_msg { +struct avb_packet_msrp_msg { uint8_t attribute_type; uint8_t attribute_length; uint16_t attribute_list_length; uint8_t attribute_list[0]; } __attribute__ ((__packed__)); -#define AVBTP_MSRP_TSPEC_MAX_INTERVAL_FRAMES_DEFAULT 1 -#define AVBTP_MSRP_RANK_DEFAULT 1 -#define AVBTP_MSRP_PRIORITY_DEFAULT 3 +#define AVB_MSRP_TSPEC_MAX_INTERVAL_FRAMES_DEFAULT 1 +#define AVB_MSRP_RANK_DEFAULT 1 +#define AVB_MSRP_PRIORITY_DEFAULT 3 -struct avbtp_packet_msrp_talker { +struct avb_packet_msrp_talker { uint64_t stream_id; uint8_t dest_addr[6]; uint16_t vlan_id; @@ -67,65 +67,65 @@ struct avbtp_packet_msrp_talker { } __attribute__ ((__packed__)); /* failure codes */ -#define AVBTP_MRP_FAIL_BANDWIDTH 1 -#define AVBTP_MRP_FAIL_BRIDGE 2 -#define AVBTP_MRP_FAIL_TC_BANDWIDTH 3 -#define AVBTP_MRP_FAIL_ID_BUSY 4 -#define AVBTP_MRP_FAIL_DSTADDR_BUSY 5 -#define AVBTP_MRP_FAIL_PREEMPTED 6 -#define AVBTP_MRP_FAIL_LATENCY_CHNG 7 -#define AVBTP_MRP_FAIL_PORT_NOT_AVB 8 -#define AVBTP_MRP_FAIL_DSTADDR_FULL 9 -#define AVBTP_MRP_FAIL_AVBTP_MRP_RESOURCE 10 -#define AVBTP_MRP_FAIL_MMRP_RESOURCE 11 -#define AVBTP_MRP_FAIL_DSTADDR_FAIL 12 -#define AVBTP_MRP_FAIL_PRIO_NOT_SR 13 -#define AVBTP_MRP_FAIL_FRAME_SIZE 14 -#define AVBTP_MRP_FAIL_FANIN_EXCEED 15 -#define AVBTP_MRP_FAIL_STREAM_CHANGE 16 -#define AVBTP_MRP_FAIL_VLAN_BLOCKED 17 -#define AVBTP_MRP_FAIL_VLAN_DISABLED 18 -#define AVBTP_MRP_FAIL_SR_PRIO_ERR 19 +#define AVB_MRP_FAIL_BANDWIDTH 1 +#define AVB_MRP_FAIL_BRIDGE 2 +#define AVB_MRP_FAIL_TC_BANDWIDTH 3 +#define AVB_MRP_FAIL_ID_BUSY 4 +#define AVB_MRP_FAIL_DSTADDR_BUSY 5 +#define AVB_MRP_FAIL_PREEMPTED 6 +#define AVB_MRP_FAIL_LATENCY_CHNG 7 +#define AVB_MRP_FAIL_PORT_NOT_AVB 8 +#define AVB_MRP_FAIL_DSTADDR_FULL 9 +#define AVB_MRP_FAIL_AVB_MRP_RESOURCE 10 +#define AVB_MRP_FAIL_MMRP_RESOURCE 11 +#define AVB_MRP_FAIL_DSTADDR_FAIL 12 +#define AVB_MRP_FAIL_PRIO_NOT_SR 13 +#define AVB_MRP_FAIL_FRAME_SIZE 14 +#define AVB_MRP_FAIL_FANIN_EXCEED 15 +#define AVB_MRP_FAIL_STREAM_CHANGE 16 +#define AVB_MRP_FAIL_VLAN_BLOCKED 17 +#define AVB_MRP_FAIL_VLAN_DISABLED 18 +#define AVB_MRP_FAIL_SR_PRIO_ERR 19 -struct avbtp_packet_msrp_talker_fail { - struct avbtp_packet_msrp_talker talker; +struct avb_packet_msrp_talker_fail { + struct avb_packet_msrp_talker talker; uint64_t bridge_id; uint8_t failure_code; } __attribute__ ((__packed__)); -struct avbtp_packet_msrp_listener { +struct avb_packet_msrp_listener { uint64_t stream_id; } __attribute__ ((__packed__)); /* domain discovery */ -struct avbtp_packet_msrp_domain { +struct avb_packet_msrp_domain { uint8_t sr_class_id; uint8_t sr_class_priority; uint16_t sr_class_vid; } __attribute__ ((__packed__)); -#define AVBTP_MSRP_LISTENER_PARAM_IGNORE 0 -#define AVBTP_MSRP_LISTENER_PARAM_ASKING_FAILED 1 -#define AVBTP_MSRP_LISTENER_PARAM_READY 2 -#define AVBTP_MSRP_LISTENER_PARAM_READY_FAILED 3 +#define AVB_MSRP_LISTENER_PARAM_IGNORE 0 +#define AVB_MSRP_LISTENER_PARAM_ASKING_FAILED 1 +#define AVB_MSRP_LISTENER_PARAM_READY 2 +#define AVB_MSRP_LISTENER_PARAM_READY_FAILED 3 -struct avbtp_msrp_attribute { - struct avbtp_mrp_attribute *mrp; +struct avb_msrp_attribute { + struct avb_mrp_attribute *mrp; uint8_t type; uint8_t param; union { - struct avbtp_packet_msrp_talker talker; - struct avbtp_packet_msrp_talker_fail talker_fail; - struct avbtp_packet_msrp_listener listener; - struct avbtp_packet_msrp_domain domain; + struct avb_packet_msrp_talker talker; + struct avb_packet_msrp_talker_fail talker_fail; + struct avb_packet_msrp_listener listener; + struct avb_packet_msrp_domain domain; } attr; }; -struct avbtp_msrp; +struct avb_msrp; -struct avbtp_msrp_attribute *avbtp_msrp_attribute_new(struct avbtp_msrp *msrp, +struct avb_msrp_attribute *avb_msrp_attribute_new(struct avb_msrp *msrp, uint8_t type); -struct avbtp_msrp *avbtp_msrp_register(struct server *server); +struct avb_msrp *avb_msrp_register(struct server *server); -#endif /* AVBTP_MSRP_H */ +#endif /* AVB_MSRP_H */ diff --git a/src/modules/module-avbtp/mvrp.c b/src/modules/module-avb/mvrp.c similarity index 82% rename from src/modules/module-avbtp/mvrp.c rename to src/modules/module-avb/mvrp.c index bc60fee8d..645c13d3b 100644 --- a/src/modules/module-avbtp/mvrp.c +++ b/src/modules/module-avb/mvrp.c @@ -29,7 +29,7 @@ static const uint8_t mac[6] = AVB_MVRP_MAC; struct attr { - struct avbtp_mvrp_attribute attr; + struct avb_mvrp_attribute attr; struct spa_list link; }; @@ -42,10 +42,10 @@ struct mvrp { static bool mvrp_check_header(void *data, const void *hdr, size_t *hdr_size, bool *has_params) { - const struct avbtp_packet_mvrp_msg *msg = hdr; + const struct avb_packet_mvrp_msg *msg = hdr; uint8_t attr_type = msg->attribute_type; - if (!AVBTP_MVRP_ATTRIBUTE_TYPE_VALID(attr_type)) + if (!AVB_MVRP_ATTRIBUTE_TYPE_VALID(attr_type)) return false; *hdr_size = sizeof(*msg); @@ -59,13 +59,13 @@ static int mvrp_attr_event(void *data, uint64_t now, uint8_t attribute_type, uin struct attr *a; spa_list_for_each(a, &mvrp->attributes, link) if (a->attr.type == attribute_type) - avbtp_mrp_update_state(mvrp->server->mrp, now, a->attr.mrp, event); + avb_mrp_update_state(mvrp->server->mrp, now, a->attr.mrp, event); return 0; } static void debug_vid(const void *p) { - const struct avbtp_packet_mvrp_vid *t = p; + const struct avb_packet_mvrp_vid *t = p; pw_log_info("vid"); pw_log_info(" %d", ntohs(t->vlan)); } @@ -81,7 +81,7 @@ static const struct { int (*dispatch) (struct mvrp *mvrp, uint64_t now, uint8_t attr_type, const void *m, uint8_t event, uint8_t param, int num); } dispatch[] = { - [AVBTP_MVRP_ATTRIBUTE_TYPE_VID] = { debug_vid, process_vid, }, + [AVB_MVRP_ATTRIBUTE_TYPE_VID] = { debug_vid, process_vid, }, }; static int mvrp_process(void *data, uint64_t now, uint8_t attribute_type, const void *value, @@ -92,8 +92,8 @@ static int mvrp_process(void *data, uint64_t now, uint8_t attribute_type, const attribute_type, value, event, param, index); } -static const struct avbtp_mrp_parse_info info = { - AVBTP_VERSION_MRP_PARSE_INFO, +static const struct avb_mrp_parse_info info = { + AVB_VERSION_MRP_PARSE_INFO, .check_header = mvrp_check_header, .attr_event = mvrp_attr_event, .process = mvrp_process, @@ -102,7 +102,7 @@ static const struct avbtp_mrp_parse_info info = { static int mvrp_message(void *data, uint64_t now, const void *message, int len) { struct mvrp *mvrp = data; - const struct avbtp_packet_mrp *p = message; + const struct avb_packet_mrp *p = message; if (ntohs(p->eth.type) != AVB_MVRP_ETH) return 0; @@ -110,7 +110,7 @@ static int mvrp_message(void *data, uint64_t now, const void *message, int len) return 0; pw_log_debug("MVRP"); - return avbtp_mrp_parse_packet(mvrp->server->mrp, + return avb_mrp_parse_packet(mvrp->server->mrp, now, message, len, &info, mvrp); } @@ -122,19 +122,19 @@ static void mvrp_destroy(void *data) } static const struct server_events server_events = { - AVBTP_VERSION_SERVER_EVENTS, + AVB_VERSION_SERVER_EVENTS, .destroy = mvrp_destroy, .message = mvrp_message }; -struct avbtp_mvrp_attribute *avbtp_mvrp_attribute_new(struct avbtp_mvrp *m, +struct avb_mvrp_attribute *avb_mvrp_attribute_new(struct avb_mvrp *m, uint8_t type) { struct mvrp *mvrp = (struct mvrp*)m; - struct avbtp_mrp_attribute *attr; + struct avb_mrp_attribute *attr; struct attr *a; - attr = avbtp_mrp_attribute_new(mvrp->server->mrp, sizeof(struct attr)); + attr = avb_mrp_attribute_new(mvrp->server->mrp, sizeof(struct attr)); a = attr->user_data; a->attr.mrp = attr; @@ -144,7 +144,7 @@ struct avbtp_mvrp_attribute *avbtp_mvrp_attribute_new(struct avbtp_mvrp *m, return &a->attr; } -struct avbtp_mvrp *avbtp_mvrp_register(struct server *server) +struct avb_mvrp *avb_mvrp_register(struct server *server) { struct mvrp *mvrp; @@ -157,5 +157,5 @@ struct avbtp_mvrp *avbtp_mvrp_register(struct server *server) avdecc_server_add_listener(server, &mvrp->server_listener, &server_events, mvrp); - return (struct avbtp_mvrp*)mvrp; + return (struct avb_mvrp*)mvrp; } diff --git a/src/modules/module-avbtp/mvrp.h b/src/modules/module-avb/mvrp.h similarity index 75% rename from src/modules/module-avbtp/mvrp.h rename to src/modules/module-avb/mvrp.h index 2595ca986..da3d5dcf8 100644 --- a/src/modules/module-avbtp/mvrp.h +++ b/src/modules/module-avb/mvrp.h @@ -22,8 +22,8 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef AVBTP_MVRP_H -#define AVBTP_MVRP_H +#ifndef AVB_MVRP_H +#define AVB_MVRP_H #include "mrp.h" #include "internal.h" @@ -31,32 +31,32 @@ #define AVB_MVRP_ETH 0x88f5 #define AVB_MVRP_MAC { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x21 }; -struct avbtp_packet_mvrp_msg { +struct avb_packet_mvrp_msg { uint8_t attribute_type; uint8_t attribute_length; uint8_t attribute_list[0]; } __attribute__ ((__packed__)); -#define AVBTP_MVRP_ATTRIBUTE_TYPE_VID 1 -#define AVBTP_MVRP_ATTRIBUTE_TYPE_VALID(t) ((t)==1) +#define AVB_MVRP_ATTRIBUTE_TYPE_VID 1 +#define AVB_MVRP_ATTRIBUTE_TYPE_VALID(t) ((t)==1) -struct avbtp_packet_mvrp_vid { +struct avb_packet_mvrp_vid { uint16_t vlan; } __attribute__ ((__packed__)); -struct avbtp_mvrp; +struct avb_mvrp; -struct avbtp_mvrp_attribute { - struct avbtp_mrp_attribute *mrp; +struct avb_mvrp_attribute { + struct avb_mrp_attribute *mrp; uint8_t type; union { - struct avbtp_packet_mvrp_vid vid; + struct avb_packet_mvrp_vid vid; } attr; }; -struct avbtp_mvrp_attribute *avbtp_mvrp_attribute_new(struct avbtp_mvrp *mvrp, +struct avb_mvrp_attribute *avb_mvrp_attribute_new(struct avb_mvrp *mvrp, uint8_t type); -struct avbtp_mvrp *avbtp_mvrp_register(struct server *server); +struct avb_mvrp *avb_mvrp_register(struct server *server); -#endif /* AVBTP_MVRP_H */ +#endif /* AVB_MVRP_H */ diff --git a/src/modules/module-avbtp/packets.h b/src/modules/module-avb/packets.h similarity index 52% rename from src/modules/module-avbtp/packets.h rename to src/modules/module-avb/packets.h index 9e5e53659..fef147aa0 100644 --- a/src/modules/module-avbtp/packets.h +++ b/src/modules/module-avb/packets.h @@ -22,40 +22,40 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef AVBTP_PACKETS_H -#define AVBTP_PACKETS_H +#ifndef AVB_PACKETS_H +#define AVB_PACKETS_H #include -#define AVBTP_SUBTYPE_61883_IIDC 0x00 -#define AVBTP_SUBTYPE_MMA_STREAM 0x01 -#define AVBTP_SUBTYPE_AAF 0x02 -#define AVBTP_SUBTYPE_CVF 0x03 -#define AVBTP_SUBTYPE_CRF 0x04 -#define AVBTP_SUBTYPE_TSCF 0x05 -#define AVBTP_SUBTYPE_SVF 0x06 -#define AVBTP_SUBTYPE_RVF 0x07 -#define AVBTP_SUBTYPE_AEF_CONTINUOUS 0x6E -#define AVBTP_SUBTYPE_VSF_STREAM 0x6F -#define AVBTP_SUBTYPE_EF_STREAM 0x7F -#define AVBTP_SUBTYPE_NTSCF 0x82 -#define AVBTP_SUBTYPE_ESCF 0xEC -#define AVBTP_SUBTYPE_EECF 0xED -#define AVBTP_SUBTYPE_AEF_DISCRETE 0xEE -#define AVBTP_SUBTYPE_ADP 0xFA -#define AVBTP_SUBTYPE_AECP 0xFB -#define AVBTP_SUBTYPE_ACMP 0xFC -#define AVBTP_SUBTYPE_MAAP 0xFE -#define AVBTP_SUBTYPE_EF_CONTROL 0xFF +#define AVB_SUBTYPE_61883_IIDC 0x00 +#define AVB_SUBTYPE_MMA_STREAM 0x01 +#define AVB_SUBTYPE_AAF 0x02 +#define AVB_SUBTYPE_CVF 0x03 +#define AVB_SUBTYPE_CRF 0x04 +#define AVB_SUBTYPE_TSCF 0x05 +#define AVB_SUBTYPE_SVF 0x06 +#define AVB_SUBTYPE_RVF 0x07 +#define AVB_SUBTYPE_AEF_CONTINUOUS 0x6E +#define AVB_SUBTYPE_VSF_STREAM 0x6F +#define AVB_SUBTYPE_EF_STREAM 0x7F +#define AVB_SUBTYPE_NTSCF 0x82 +#define AVB_SUBTYPE_ESCF 0xEC +#define AVB_SUBTYPE_EECF 0xED +#define AVB_SUBTYPE_AEF_DISCRETE 0xEE +#define AVB_SUBTYPE_ADP 0xFA +#define AVB_SUBTYPE_AECP 0xFB +#define AVB_SUBTYPE_ACMP 0xFC +#define AVB_SUBTYPE_MAAP 0xFE +#define AVB_SUBTYPE_EF_CONTROL 0xFF -struct avbtp_ethernet_header { +struct avb_ethernet_header { uint8_t dest[6]; uint8_t src[6]; uint16_t type; } __attribute__ ((__packed__)); -struct avbtp_packet_header { - struct avbtp_ethernet_header eth; +struct avb_packet_header { + struct avb_ethernet_header eth; uint8_t subtype; #if __BYTE_ORDER == __BIG_ENDIAN unsigned sv:1; /* stream_id valid */ @@ -77,18 +77,18 @@ struct avbtp_packet_header { uint8_t len2:8; } __attribute__ ((__packed__)); -#define AVBTP_PACKET_SET_SUBTYPE(p,v) ((p)->subtype = (v)) -#define AVBTP_PACKET_SET_SV(p,v) ((p)->sv = (v)) -#define AVBTP_PACKET_SET_VERSION(p,v) ((p)->version = (v)) -#define AVBTP_PACKET_SET_SUB1(p,v) ((p)->subtype_data1 = (v)) -#define AVBTP_PACKET_SET_SUB2(p,v) ((p)->subtype_data2 = (v)) -#define AVBTP_PACKET_SET_LENGTH(p,v) ((p)->len1 = ((v) >> 8),(p)->len2 = (v)) +#define AVB_PACKET_SET_SUBTYPE(p,v) ((p)->subtype = (v)) +#define AVB_PACKET_SET_SV(p,v) ((p)->sv = (v)) +#define AVB_PACKET_SET_VERSION(p,v) ((p)->version = (v)) +#define AVB_PACKET_SET_SUB1(p,v) ((p)->subtype_data1 = (v)) +#define AVB_PACKET_SET_SUB2(p,v) ((p)->subtype_data2 = (v)) +#define AVB_PACKET_SET_LENGTH(p,v) ((p)->len1 = ((v) >> 8),(p)->len2 = (v)) -#define AVBTP_PACKET_GET_SUBTYPE(p) ((p)->subtype) -#define AVBTP_PACKET_GET_SV(p) ((p)->sv) -#define AVBTP_PACKET_GET_VERSION(p) ((p)->version) -#define AVBTP_PACKET_GET_SUB1(p) ((p)->subtype_data1) -#define AVBTP_PACKET_GET_SUB2(p) ((p)->subtype_data2) -#define AVBTP_PACKET_GET_LENGTH(p) ((p)->len1 << 8 | (p)->len2) +#define AVB_PACKET_GET_SUBTYPE(p) ((p)->subtype) +#define AVB_PACKET_GET_SV(p) ((p)->sv) +#define AVB_PACKET_GET_VERSION(p) ((p)->version) +#define AVB_PACKET_GET_SUB1(p) ((p)->subtype_data1) +#define AVB_PACKET_GET_SUB2(p) ((p)->subtype_data2) +#define AVB_PACKET_GET_LENGTH(p) ((p)->len1 << 8 | (p)->len2) -#endif /* AVBTP_PACKETS_H */ +#endif /* AVB_PACKETS_H */ diff --git a/src/modules/module-avbtp/srp.c b/src/modules/module-avb/srp.c similarity index 95% rename from src/modules/module-avbtp/srp.c rename to src/modules/module-avb/srp.c index 867c96f53..89d75f12a 100644 --- a/src/modules/module-avbtp/srp.c +++ b/src/modules/module-avb/srp.c @@ -39,11 +39,11 @@ static void srp_destroy(void *data) } static const struct server_events server_events = { - AVBTP_VERSION_SERVER_EVENTS, + AVB_VERSION_SERVER_EVENTS, .destroy = srp_destroy, }; -int avbtp_srp_register(struct server *server) +int avb_srp_register(struct server *server) { struct srp *srp; diff --git a/src/modules/module-avbtp/srp.h b/src/modules/module-avb/srp.h similarity index 91% rename from src/modules/module-avbtp/srp.h rename to src/modules/module-avb/srp.h index 131385785..853321fb3 100644 --- a/src/modules/module-avbtp/srp.h +++ b/src/modules/module-avb/srp.h @@ -22,11 +22,11 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef AVBTP_SRP_H -#define AVBTP_SRP_H +#ifndef AVB_SRP_H +#define AVB_SRP_H #include "internal.h" -int avbtp_srp_register(struct server *server); +int avb_srp_register(struct server *server); -#endif /* AVBTP_SRP_H */ +#endif /* AVB_SRP_H */ diff --git a/src/modules/module-avbtp/utils.h b/src/modules/module-avb/utils.h similarity index 86% rename from src/modules/module-avbtp/utils.h rename to src/modules/module-avb/utils.h index 784af5876..88328f899 100644 --- a/src/modules/module-avbtp/utils.h +++ b/src/modules/module-avb/utils.h @@ -22,14 +22,14 @@ * DEALINGS IN THE SOFTWARE. */ -#ifndef AVBTP_UTILS_H -#define AVBTP_UTILS_H +#ifndef AVB_UTILS_H +#define AVB_UTILS_H #include #include "internal.h" -static inline char *avbtp_utils_format_id(char *str, size_t size, const uint64_t id) +static inline char *avb_utils_format_id(char *str, size_t size, const uint64_t id) { snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x:%04x", (uint8_t)(id >> 56), @@ -42,7 +42,7 @@ static inline char *avbtp_utils_format_id(char *str, size_t size, const uint64_t return str; } -static inline int avbtp_utils_parse_id(const char *str, int len, uint64_t *id) +static inline int avb_utils_parse_id(const char *str, int len, uint64_t *id) { char s[64]; uint8_t v[6]; @@ -64,11 +64,11 @@ static inline int avbtp_utils_parse_id(const char *str, int len, uint64_t *id) return 0; } -static inline char *avbtp_utils_format_addr(char *str, size_t size, const uint8_t addr[6]) +static inline char *avb_utils_format_addr(char *str, size_t size, const uint8_t addr[6]) { snprintf(str, size, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); return str; } -#endif /* AVBTP_UTILS_H */ +#endif /* AVB_UTILS_H */ diff --git a/src/modules/module-avbtp.c b/src/modules/module-avbtp.c deleted file mode 100644 index a86b9590d..000000000 --- a/src/modules/module-avbtp.c +++ /dev/null @@ -1,134 +0,0 @@ -/* PipeWire - * - * Copyright © 2022 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" - -#include -#include -#include - -#include -#include -#include - -#include "module-avbtp/avb.h" - -/** \page page_module_avb PipeWire Module: AVB - */ - -#define NAME "avb" - -PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME); -#define PW_LOG_TOPIC_DEFAULT mod_topic - -#define MODULE_USAGE " " - -static const struct spa_dict_item module_props[] = { - { PW_KEY_MODULE_AUTHOR, "Wim Taymans " }, - { PW_KEY_MODULE_DESCRIPTION, "Manage an AVB network" }, - { PW_KEY_MODULE_USAGE, MODULE_USAGE }, - { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, -}; - - -struct impl { - struct pw_context *context; - - struct pw_impl_module *module; - struct spa_hook module_listener; - - struct pw_properties *properties; - - struct pw_avb *avb; -}; - -static void impl_free(struct impl *impl) -{ - pw_properties_free(impl->properties); - free(impl); -} - -static void module_destroy(void *data) -{ - struct impl *impl = data; - spa_hook_remove(&impl->module_listener); - impl_free(impl); -} - -static const struct pw_impl_module_events module_events = { - PW_VERSION_IMPL_MODULE_EVENTS, - .destroy = module_destroy, -}; - -SPA_EXPORT -int pipewire__module_init(struct pw_impl_module *module, const char *args) -{ - struct pw_context *context = pw_impl_module_get_context(module); - struct pw_properties *props; - struct impl *impl; - int res; - - PW_LOG_TOPIC_INIT(mod_topic); - - impl = calloc(1, sizeof(struct impl)); - if (impl == NULL) - goto error_errno; - - pw_log_debug("module %p: new %s", impl, args); - - if (args == NULL) - args = ""; - - props = pw_properties_new_string(args); - if (props == NULL) - goto error_errno; - - impl->module = module; - impl->context = context; - impl->properties = props; - - impl->avb = pw_avb_new(context, props, 0); - if (impl->avb == NULL) - goto error_errno; - - pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl); - - pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props)); - - return 0; - -error_errno: - res = -errno; - if (impl) - impl_free(impl); - return res; -} diff --git a/src/modules/module-avbtp/aaf.h b/src/modules/module-avbtp/aaf.h deleted file mode 100644 index bb4487028..000000000 --- a/src/modules/module-avbtp/aaf.h +++ /dev/null @@ -1,140 +0,0 @@ -/* AVBTP support - * - * Copyright © 2022 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef AVBTP_AAF_H -#define AVBTP_AAF_H - -struct avbtp_packet_aaf { - struct avbtp_ethernet_header hdr; - uint8_t subtype; -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned sv:1; - unsigned version:3; - unsigned mr:1; - unsigned _r1:1; - unsigned gv:1; - unsigned tv:1; - - uint8_t seq_number; - - unsigned _r2:7; - unsigned tu:1; -#elif __BYTE_ORDER == __LITTLE_ENDIAN - unsigned tv:1; - unsigned gv:1; - unsigned _r1:1; - unsigned mr:1; - unsigned version:3; - unsigned sv:1; - - uint8_t seq_num; - - unsigned tu:1; - unsigned _r2:7; -#endif - uint64_t stream_id; - uint32_t timestamp; -#define AVBTP_AAF_FORMAT_USER 0x00 -#define AVBTP_AAF_FORMAT_FLOAT_32BIT 0x01 -#define AVBTP_AAF_FORMAT_INT_32BIT 0x02 -#define AVBTP_AAF_FORMAT_INT_24BIT 0x03 -#define AVBTP_AAF_FORMAT_INT_16BIT 0x04 -#define AVBTP_AAF_FORMAT_AES3_32BIT 0x05 - uint8_t format; - -#define AVBTP_AAF_PCM_NSR_USER 0x00 -#define AVBTP_AAF_PCM_NSR_8KHZ 0x01 -#define AVBTP_AAF_PCM_NSR_16KHZ 0x02 -#define AVBTP_AAF_PCM_NSR_32KHZ 0x03 -#define AVBTP_AAF_PCM_NSR_44_1KHZ 0x04 -#define AVBTP_AAF_PCM_NSR_48KHZ 0x05 -#define AVBTP_AAF_PCM_NSR_88_2KHZ 0x06 -#define AVBTP_AAF_PCM_NSR_96KHZ 0x07 -#define AVBTP_AAF_PCM_NSR_176_4KHZ 0x08 -#define AVBTP_AAF_PCM_NSR_192KHZ 0x09 -#define AVBTP_AAF_PCM_NSR_24KHZ 0x0A -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned nsr:4; - unsigned _r3:4; -#elif __BYTE_ORDER == __LITTLE_ENDIAN - unsigned _r3:4; - unsigned nsr:4; -#endif - uint8_t chan_per_frame; - uint8_t bit_depth; - uint16_t data_len; - -#define AVBTP_AAF_PCM_SP_NORMAL 0x00 -#define AVBTP_AAF_PCM_SP_SPARSE 0x01 -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned _r4:3; - unsigned sp:1; - unsigned event:4; -#elif __BYTE_ORDER == __LITTLE_ENDIAN - unsigned event:4; - unsigned sp:1; - unsigned _r4:3; -#endif - uint8_t _r5; - uint8_t payload[0]; -} __attribute__ ((__packed__)); - -#define AVBTP_PACKET_AAF_SET_SUBTYPE(p,v) ((p)->subtype = (v)) -#define AVBTP_PACKET_AAF_SET_SV(p,v) ((p)->sv = (v)) -#define AVBTP_PACKET_AAF_SET_VERSION(p,v) ((p)->version = (v)) -#define AVBTP_PACKET_AAF_SET_MR(p,v) ((p)->mr = (v)) -#define AVBTP_PACKET_AAF_SET_GV(p,v) ((p)->gv = (v)) -#define AVBTP_PACKET_AAF_SET_TV(p,v) ((p)->tv = (v)) -#define AVBTP_PACKET_AAF_SET_SEQ_NUM(p,v) ((p)->seq_num = (v)) -#define AVBTP_PACKET_AAF_SET_TU(p,v) ((p)->tu = (v)) -#define AVBTP_PACKET_AAF_SET_STREAM_ID(p,v) ((p)->stream_id = htobe64(v)) -#define AVBTP_PACKET_AAF_SET_TIMESTAMP(p,v) ((p)->timestamp = htonl(v)) -#define AVBTP_PACKET_AAF_SET_DATA_LEN(p,v) ((p)->data_len = htons(v)) -#define AVBTP_PACKET_AAF_SET_FORMAT(p,v) ((p)->format = (v)) -#define AVBTP_PACKET_AAF_SET_NSR(p,v) ((p)->nsr = (v)) -#define AVBTP_PACKET_AAF_SET_CHAN_PER_FRAME(p,v) ((p)->chan_per_frame = (v)) -#define AVBTP_PACKET_AAF_SET_BIT_DEPTH(p,v) ((p)->bit_depth = (v)) -#define AVBTP_PACKET_AAF_SET_SP(p,v) ((p)->sp = (v)) -#define AVBTP_PACKET_AAF_SET_EVENT(p,v) ((p)->event = (v)) - -#define AVBTP_PACKET_AAF_GET_SUBTYPE(p) ((p)->subtype) -#define AVBTP_PACKET_AAF_GET_SV(p) ((p)->sv) -#define AVBTP_PACKET_AAF_GET_VERSION(p) ((p)->version) -#define AVBTP_PACKET_AAF_GET_MR(p) ((p)->mr) -#define AVBTP_PACKET_AAF_GET_GV(p) ((p)->gv) -#define AVBTP_PACKET_AAF_GET_TV(p) ((p)->tv) -#define AVBTP_PACKET_AAF_GET_SEQ_NUM(p) ((p)->seq_num) -#define AVBTP_PACKET_AAF_GET_TU(p) ((p)->tu) -#define AVBTP_PACKET_AAF_GET_STREAM_ID(p) be64toh((p)->stream_id) -#define AVBTP_PACKET_AAF_GET_TIMESTAMP(p) ntohl((p)->timestamp) -#define AVBTP_PACKET_AAF_GET_DATA_LEN(p) ntohs((p)->data_len) -#define AVBTP_PACKET_AAF_GET_FORMAT(p) ((p)->format) -#define AVBTP_PACKET_AAF_GET_NSR(p) ((p)->nsr) -#define AVBTP_PACKET_AAF_GET_CHAN_PER_FRAME(p) ((p)->chan_per_frame) -#define AVBTP_PACKET_AAF_GET_BIT_DEPTH(p) ((p)->bit_depth) -#define AVBTP_PACKET_AAF_GET_SP(p) ((p)->sp) -#define AVBTP_PACKET_AAF_GET_EVENT(p) ((p)->event) - - -#endif /* AVBTP_AAF_H */ diff --git a/src/modules/module-avbtp/acmp.h b/src/modules/module-avbtp/acmp.h deleted file mode 100644 index 6fb218686..000000000 --- a/src/modules/module-avbtp/acmp.h +++ /dev/null @@ -1,99 +0,0 @@ -/* AVB support - * - * Copyright © 2022 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef AVBTP_ACMP_H -#define AVBTP_ACMP_H - -#include "packets.h" -#include "internal.h" - -#define AVBTP_ACMP_MESSAGE_TYPE_CONNECT_TX_COMMAND 0 -#define AVBTP_ACMP_MESSAGE_TYPE_CONNECT_TX_RESPONSE 1 -#define AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_TX_COMMAND 2 -#define AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_TX_RESPONSE 3 -#define AVBTP_ACMP_MESSAGE_TYPE_GET_TX_STATE_COMMAND 4 -#define AVBTP_ACMP_MESSAGE_TYPE_GET_TX_STATE_RESPONSE 5 -#define AVBTP_ACMP_MESSAGE_TYPE_CONNECT_RX_COMMAND 6 -#define AVBTP_ACMP_MESSAGE_TYPE_CONNECT_RX_RESPONSE 7 -#define AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_RX_COMMAND 8 -#define AVBTP_ACMP_MESSAGE_TYPE_DISCONNECT_RX_RESPONSE 9 -#define AVBTP_ACMP_MESSAGE_TYPE_GET_RX_STATE_COMMAND 10 -#define AVBTP_ACMP_MESSAGE_TYPE_GET_RX_STATE_RESPONSE 11 -#define AVBTP_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_COMMAND 12 -#define AVBTP_ACMP_MESSAGE_TYPE_GET_TX_CONNECTION_RESPONSE 13 - -#define AVBTP_ACMP_STATUS_SUCCESS 0 -#define AVBTP_ACMP_STATUS_LISTENER_UNKNOWN_ID 1 -#define AVBTP_ACMP_STATUS_TALKER_UNKNOWN_ID 2 -#define AVBTP_ACMP_STATUS_TALKER_DEST_MAC_FAIL 3 -#define AVBTP_ACMP_STATUS_TALKER_NO_STREAM_INDEX 4 -#define AVBTP_ACMP_STATUS_TALKER_NO_BANDWIDTH 5 -#define AVBTP_ACMP_STATUS_TALKER_EXCLUSIVE 6 -#define AVBTP_ACMP_STATUS_LISTENER_TALKER_TIMEOUT 7 -#define AVBTP_ACMP_STATUS_LISTENER_EXCLUSIVE 8 -#define AVBTP_ACMP_STATUS_STATE_UNAVAILABLE 9 -#define AVBTP_ACMP_STATUS_NOT_CONNECTED 10 -#define AVBTP_ACMP_STATUS_NO_SUCH_CONNECTION 11 -#define AVBTP_ACMP_STATUS_COULD_NOT_SEND_MESSAGE 12 -#define AVBTP_ACMP_STATUS_TALKER_MISBEHAVING 13 -#define AVBTP_ACMP_STATUS_LISTENER_MISBEHAVING 14 -#define AVBTP_ACMP_STATUS_RESERVED 15 -#define AVBTP_ACMP_STATUS_CONTROLLER_NOT_AUTHORIZED 16 -#define AVBTP_ACMP_STATUS_INCOMPATIBLE_REQUEST 17 -#define AVBTP_ACMP_STATUS_LISTENER_INVALID_CONNECTION 18 -#define AVBTP_ACMP_STATUS_NOT_SUPPORTED 31 - -#define AVBTP_ACMP_TIMEOUT_CONNECT_TX_COMMAND_MS 2000 -#define AVBTP_ACMP_TIMEOUT_DISCONNECT_TX_COMMAND_MS 200 -#define AVBTP_ACMP_TIMEOUT_GET_TX_STATE_COMMAND 200 -#define AVBTP_ACMP_TIMEOUT_CONNECT_RX_COMMAND_MS 4500 -#define AVBTP_ACMP_TIMEOUT_DISCONNECT_RX_COMMAND_MS 500 -#define AVBTP_ACMP_TIMEOUT_GET_RX_STATE_COMMAND_MS 200 -#define AVBTP_ACMP_TIMEOUT_GET_TX_CONNECTION_COMMAND 200 - -struct avbtp_packet_acmp { - struct avbtp_packet_header hdr; - uint64_t stream_id; - uint64_t controller_guid; - uint64_t talker_guid; - uint64_t listener_guid; - uint16_t talker_unique_id; - uint16_t listener_unique_id; - char stream_dest_mac[6]; - uint16_t connection_count; - uint16_t sequence_id; - uint16_t flags; - uint16_t stream_vlan_id; - uint16_t reserved; -} __attribute__ ((__packed__)); - -#define AVBTP_PACKET_ACMP_SET_MESSAGE_TYPE(p,v) AVBTP_PACKET_SET_SUB1(&(p)->hdr, v) -#define AVBTP_PACKET_ACMP_SET_STATUS(p,v) AVBTP_PACKET_SET_SUB2(&(p)->hdr, v) - -#define AVBTP_PACKET_ACMP_GET_MESSAGE_TYPE(p) AVBTP_PACKET_GET_SUB1(&(p)->hdr) -#define AVBTP_PACKET_ACMP_GET_STATUS(p) AVBTP_PACKET_GET_SUB2(&(p)->hdr) - -struct avbtp_acmp *avbtp_acmp_register(struct server *server); - -#endif /* AVBTP_ACMP_H */ diff --git a/src/modules/module-avbtp/adp.h b/src/modules/module-avbtp/adp.h deleted file mode 100644 index e30cf991b..000000000 --- a/src/modules/module-avbtp/adp.h +++ /dev/null @@ -1,105 +0,0 @@ -/* AVB support - * - * Copyright © 2022 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef AVBTP_ADP_H -#define AVBTP_ADP_H - -#include "packets.h" -#include "internal.h" - -#define AVBTP_ADP_MESSAGE_TYPE_ENTITY_AVAILABLE 0 -#define AVBTP_ADP_MESSAGE_TYPE_ENTITY_DEPARTING 1 -#define AVBTP_ADP_MESSAGE_TYPE_ENTITY_DISCOVER 2 - -#define AVBTP_ADP_ENTITY_CAPABILITY_EFU_MODE (1u<<0) -#define AVBTP_ADP_ENTITY_CAPABILITY_ADDRESS_ACCESS_SUPPORTED (1u<<1) -#define AVBTP_ADP_ENTITY_CAPABILITY_GATEWAY_ENTITY (1u<<2) -#define AVBTP_ADP_ENTITY_CAPABILITY_AEM_SUPPORTED (1u<<3) -#define AVBTP_ADP_ENTITY_CAPABILITY_LEGACY_AVC (1u<<4) -#define AVBTP_ADP_ENTITY_CAPABILITY_ASSOCIATION_ID_SUPPORTED (1u<<5) -#define AVBTP_ADP_ENTITY_CAPABILITY_ASSOCIATION_ID_VALID (1u<<6) -#define AVBTP_ADP_ENTITY_CAPABILITY_VENDOR_UNIQUE_SUPPORTED (1u<<7) -#define AVBTP_ADP_ENTITY_CAPABILITY_CLASS_A_SUPPORTED (1u<<8) -#define AVBTP_ADP_ENTITY_CAPABILITY_CLASS_B_SUPPORTED (1u<<9) -#define AVBTP_ADP_ENTITY_CAPABILITY_GPTP_SUPPORTED (1u<<10) -#define AVBTP_ADP_ENTITY_CAPABILITY_AEM_AUTHENTICATION_SUPPORTED (1u<<11) -#define AVBTP_ADP_ENTITY_CAPABILITY_AEM_AUTHENTICATION_REQUIRED (1u<<12) -#define AVBTP_ADP_ENTITY_CAPABILITY_AEM_PERSISTENT_ACQUIRE_SUPPORTED (1u<<13) -#define AVBTP_ADP_ENTITY_CAPABILITY_AEM_IDENTIFY_CONTROL_INDEX_VALID (1u<<14) -#define AVBTP_ADP_ENTITY_CAPABILITY_AEM_INTERFACE_INDEX_VALID (1u<<15) -#define AVBTP_ADP_ENTITY_CAPABILITY_GENERAL_CONTROLLER_IGNORE (1u<<16) -#define AVBTP_ADP_ENTITY_CAPABILITY_ENTITY_NOT_READY (1u<<17) - -#define AVBTP_ADP_TALKER_CAPABILITY_IMPLEMENTED (1u<<0) -#define AVBTP_ADP_TALKER_CAPABILITY_OTHER_SOURCE (1u<<9) -#define AVBTP_ADP_TALKER_CAPABILITY_CONTROL_SOURCE (1u<<10) -#define AVBTP_ADP_TALKER_CAPABILITY_MEDIA_CLOCK_SOURCE (1u<<11) -#define AVBTP_ADP_TALKER_CAPABILITY_SMPTE_SOURCE (1u<<12) -#define AVBTP_ADP_TALKER_CAPABILITY_MIDI_SOURCE (1u<<13) -#define AVBTP_ADP_TALKER_CAPABILITY_AUDIO_SOURCE (1u<<14) -#define AVBTP_ADP_TALKER_CAPABILITY_VIDEO_SOURCE (1u<<15) - -#define AVBTP_ADP_LISTENER_CAPABILITY_IMPLEMENTED (1u<<0) -#define AVBTP_ADP_LISTENER_CAPABILITY_OTHER_SINK (1u<<9) -#define AVBTP_ADP_LISTENER_CAPABILITY_CONTROL_SINK (1u<<10) -#define AVBTP_ADP_LISTENER_CAPABILITY_MEDIA_CLOCK_SINK (1u<<11) -#define AVBTP_ADP_LISTENER_CAPABILITY_SMPTE_SINK (1u<<12) -#define AVBTP_ADP_LISTENER_CAPABILITY_MIDI_SINK (1u<<13) -#define AVBTP_ADP_LISTENER_CAPABILITY_AUDIO_SINK (1u<<14) -#define AVBTP_ADP_LISTENER_CAPABILITY_VIDEO_SINK (1u<<15) - -#define AVBTP_ADP_CONTROLLER_CAPABILITY_IMPLEMENTED (1u<<0) -#define AVBTP_ADP_CONTROLLER_CAPABILITY_LAYER3_PROXY (1u<<1) - -#define AVBTP_ADP_CONTROL_DATA_LENGTH 56 - -struct avbtp_packet_adp { - struct avbtp_packet_header hdr; - uint64_t entity_id; - uint64_t entity_model_id; - uint32_t entity_capabilities; - uint16_t talker_stream_sources; - uint16_t talker_capabilities; - uint16_t listener_stream_sinks; - uint16_t listener_capabilities; - uint32_t controller_capabilities; - uint32_t available_index; - uint64_t gptp_grandmaster_id; - uint8_t gptp_domain_number; - uint8_t reserved0[3]; - uint16_t identify_control_index; - uint16_t interface_index; - uint64_t association_id; - uint32_t reserved1; -} __attribute__ ((__packed__)); - -#define AVBTP_PACKET_ADP_SET_MESSAGE_TYPE(p,v) AVBTP_PACKET_SET_SUB1(&(p)->hdr, v) -#define AVBTP_PACKET_ADP_SET_VALID_TIME(p,v) AVBTP_PACKET_SET_SUB2(&(p)->hdr, v) - -#define AVBTP_PACKET_ADP_GET_MESSAGE_TYPE(p) AVBTP_PACKET_GET_SUB1(&(p)->hdr) -#define AVBTP_PACKET_ADP_GET_VALID_TIME(p) AVBTP_PACKET_GET_SUB2(&(p)->hdr) - -struct avbtp_adp *avbtp_adp_register(struct server *server); - -#endif /* AVBTP_ADP_H */ diff --git a/src/modules/module-avbtp/aecp-aem.c b/src/modules/module-avbtp/aecp-aem.c deleted file mode 100644 index 923b98625..000000000 --- a/src/modules/module-avbtp/aecp-aem.c +++ /dev/null @@ -1,283 +0,0 @@ -/* AVB support - * - * Copyright © 2022 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "aecp-aem.h" -#include "aecp-aem-descriptors.h" - -static int reply_status(struct aecp *aecp, int status, const void *m, int len) -{ - struct server *server = aecp->server; - uint8_t buf[len]; - struct avbtp_packet_aecp_header *reply = (struct avbtp_packet_aecp_header*)buf; - - memcpy(reply, m, len); - AVBTP_PACKET_AECP_SET_MESSAGE_TYPE(reply, AVBTP_AECP_MESSAGE_TYPE_AEM_RESPONSE); - AVBTP_PACKET_AECP_SET_STATUS(reply, status); - - return avbtp_server_send_packet(server, reply->hdr.eth.src, - AVB_TSN_ETH, reply, len); -} - -static int reply_not_implemented(struct aecp *aecp, const void *m, int len) -{ - return reply_status(aecp, AVBTP_AECP_AEM_STATUS_NOT_IMPLEMENTED, m, len); -} - -static int reply_success(struct aecp *aecp, const void *m, int len) -{ - return reply_status(aecp, AVBTP_AECP_AEM_STATUS_SUCCESS, m, len); -} - -/* ACQUIRE_ENTITY */ -static int handle_acquire_entity(struct aecp *aecp, const void *m, int len) -{ - struct server *server = aecp->server; - const struct avbtp_packet_aecp_aem *p = m; - const struct avbtp_packet_aecp_aem_acquire *ae; - const struct descriptor *desc; - uint16_t desc_type, desc_id; - - ae = (const struct avbtp_packet_aecp_aem_acquire*)p->payload; - - desc_type = ntohs(ae->descriptor_type); - desc_id = ntohs(ae->descriptor_id); - - desc = server_find_descriptor(server, desc_type, desc_id); - if (desc == NULL) - return reply_status(aecp, AVBTP_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len); - - if (desc_type != AVBTP_AEM_DESC_ENTITY || desc_id != 0) - return reply_not_implemented(aecp, m, len); - - return reply_success(aecp, m, len); -} - -/* LOCK_ENTITY */ -static int handle_lock_entity(struct aecp *aecp, const void *m, int len) -{ - struct server *server = aecp->server; - const struct avbtp_packet_aecp_aem *p = m; - const struct avbtp_packet_aecp_aem_acquire *ae; - const struct descriptor *desc; - uint16_t desc_type, desc_id; - - ae = (const struct avbtp_packet_aecp_aem_acquire*)p->payload; - - desc_type = ntohs(ae->descriptor_type); - desc_id = ntohs(ae->descriptor_id); - - desc = server_find_descriptor(server, desc_type, desc_id); - if (desc == NULL) - return reply_status(aecp, AVBTP_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len); - - if (desc_type != AVBTP_AEM_DESC_ENTITY || desc_id != 0) - return reply_not_implemented(aecp, m, len); - - return reply_success(aecp, m, len); -} - -/* READ_DESCRIPTOR */ -static int handle_read_descriptor(struct aecp *aecp, const void *m, int len) -{ - struct server *server = aecp->server; - const struct avbtp_packet_aecp_aem *p = m; - struct avbtp_packet_aecp_aem *reply; - const struct avbtp_packet_aecp_aem_read_descriptor *rd; - uint16_t desc_type, desc_id; - const struct descriptor *desc; - uint8_t buf[2048]; - size_t size, psize; - - rd = (struct avbtp_packet_aecp_aem_read_descriptor*)p->payload; - - desc_type = ntohs(rd->descriptor_type); - desc_id = ntohs(rd->descriptor_id); - - pw_log_info("descriptor type:%04x index:%d", desc_type, desc_id); - - desc = server_find_descriptor(server, desc_type, desc_id); - if (desc == NULL) - return reply_status(aecp, AVBTP_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len); - - memcpy(buf, p, len); - - psize = sizeof(*rd); - size = sizeof(*reply) + psize; - - memcpy(buf + size, desc->ptr, desc->size); - size += desc->size; - psize += desc->size; - - reply = (struct avbtp_packet_aecp_aem*)buf; - AVBTP_PACKET_AECP_SET_MESSAGE_TYPE(&reply->aecp, AVBTP_AECP_MESSAGE_TYPE_AEM_RESPONSE); - AVBTP_PACKET_AECP_SET_STATUS(&reply->aecp, AVBTP_AECP_AEM_STATUS_SUCCESS); - AVBTP_PACKET_SET_LENGTH(&reply->aecp.hdr, psize + 12); - - return avbtp_server_send_packet(server, reply->aecp.hdr.eth.src, - AVB_TSN_ETH, reply, size); -} - -/* GET_AVB_INFO */ -static int handle_get_avb_info(struct aecp *aecp, const void *m, int len) -{ - struct server *server = aecp->server; - const struct avbtp_packet_aecp_aem *p = m; - struct avbtp_packet_aecp_aem *reply; - struct avbtp_packet_aecp_aem_get_avb_info *i; - struct avbtp_aem_desc_avb_interface *avb_interface; - uint16_t desc_type, desc_id; - const struct descriptor *desc; - uint8_t buf[2048]; - size_t size, psize; - - i = (struct avbtp_packet_aecp_aem_get_avb_info*)p->payload; - - desc_type = ntohs(i->descriptor_type); - desc_id = ntohs(i->descriptor_id); - - desc = server_find_descriptor(server, desc_type, desc_id); - if (desc == NULL) - return reply_status(aecp, AVBTP_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len); - - if (desc_type != AVBTP_AEM_DESC_AVB_INTERFACE || desc_id != 0) - return reply_not_implemented(aecp, m, len); - - avb_interface = desc->ptr; - - memcpy(buf, p, len); - - psize = sizeof(*i); - size = sizeof(*reply) + psize; - - reply = (struct avbtp_packet_aecp_aem *)buf; - AVBTP_PACKET_AECP_SET_MESSAGE_TYPE(&reply->aecp, AVBTP_AECP_MESSAGE_TYPE_AEM_RESPONSE); - AVBTP_PACKET_AECP_SET_STATUS(&reply->aecp, AVBTP_AECP_AEM_STATUS_SUCCESS); - AVBTP_PACKET_SET_LENGTH(&reply->aecp.hdr, psize + 12); - - i = (struct avbtp_packet_aecp_aem_get_avb_info*)reply->payload; - i->gptp_grandmaster_id = avb_interface->clock_identity; - i->propagation_delay = htonl(0); - i->gptp_domain_number = avb_interface->domain_number; - i->flags = 0; - i->msrp_mappings_count = htons(0); - - return avbtp_server_send_packet(server, reply->aecp.hdr.eth.src, - AVB_TSN_ETH, reply, size); -} - -/* AEM_COMMAND */ -struct cmd_info { - uint16_t type; - const char *name; - int (*handle) (struct aecp *aecp, const void *p, int len); -}; - -static const struct cmd_info cmd_info[] = { - { AVBTP_AECP_AEM_CMD_ACQUIRE_ENTITY, "acquire-entity", handle_acquire_entity, }, - { AVBTP_AECP_AEM_CMD_LOCK_ENTITY, "lock-entity", handle_lock_entity, }, - { AVBTP_AECP_AEM_CMD_ENTITY_AVAILABLE, "entity-available", NULL, }, - { AVBTP_AECP_AEM_CMD_CONTROLLER_AVAILABLE, "controller-available", NULL, }, - { AVBTP_AECP_AEM_CMD_READ_DESCRIPTOR, "read-descriptor", handle_read_descriptor, }, - { AVBTP_AECP_AEM_CMD_WRITE_DESCRIPTOR, "write-descriptor", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_CONFIGURATION, "set-configuration", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_CONFIGURATION, "get-configuration", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_STREAM_FORMAT, "set-stream-format", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_STREAM_FORMAT, "get-stream-format", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_VIDEO_FORMAT, "set-video-format", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_VIDEO_FORMAT, "get-video-format", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_SENSOR_FORMAT, "set-sensor-format", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_SENSOR_FORMAT, "get-sensor-format", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_STREAM_INFO, "set-stream-info", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_STREAM_INFO, "get-stream-info", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_NAME, "set-name", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_NAME, "get-name", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_ASSOCIATION_ID, "set-association-id", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_ASSOCIATION_ID, "get-association-id", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_SAMPLING_RATE, "set-sampling-rate", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_SAMPLING_RATE, "get-sampling-rate", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_CLOCK_SOURCE, "set-clock-source", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_CLOCK_SOURCE, "get-clock-source", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_CONTROL, "set-control", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_CONTROL, "get-control", NULL, }, - { AVBTP_AECP_AEM_CMD_INCREMENT_CONTROL, "increment-control", NULL, }, - { AVBTP_AECP_AEM_CMD_DECREMENT_CONTROL, "decrement-control", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_SIGNAL_SELECTOR, "set-signal-selector", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_SIGNAL_SELECTOR, "get-signal-selector", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_MIXER, "set-mixer", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_MIXER, "get-mixer", NULL, }, - { AVBTP_AECP_AEM_CMD_SET_MATRIX, "set-matrix", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_MATRIX, "get-matrix", NULL, }, - { AVBTP_AECP_AEM_CMD_START_STREAMING, "start-streaming", NULL, }, - { AVBTP_AECP_AEM_CMD_STOP_STREAMING, "stop-streaming", NULL, }, - { AVBTP_AECP_AEM_CMD_REGISTER_UNSOLICITED_NOTIFICATION, "register-unsolicited-notification", NULL, }, - { AVBTP_AECP_AEM_CMD_DEREGISTER_UNSOLICITED_NOTIFICATION, "deregister-unsolicited-notification", NULL, }, - { AVBTP_AECP_AEM_CMD_IDENTIFY_NOTIFICATION, "identify-notification", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_AVB_INFO, "get-avb-info", handle_get_avb_info, }, - { AVBTP_AECP_AEM_CMD_GET_AS_PATH, "get-as-path", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_COUNTERS, "get-counters", NULL, }, - { AVBTP_AECP_AEM_CMD_REBOOT, "reboot", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_AUDIO_MAP, "get-audio-map", NULL, }, - { AVBTP_AECP_AEM_CMD_ADD_AUDIO_MAPPINGS, "add-audio-mappings", NULL, }, - { AVBTP_AECP_AEM_CMD_REMOVE_AUDIO_MAPPINGS, "remove-audio-mappings", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_VIDEO_MAP, "get-video-map", NULL, }, - { AVBTP_AECP_AEM_CMD_ADD_VIDEO_MAPPINGS, "add-video-mappings", NULL, }, - { AVBTP_AECP_AEM_CMD_REMOVE_VIDEO_MAPPINGS, "remove-video-mappings", NULL, }, - { AVBTP_AECP_AEM_CMD_GET_SENSOR_MAP, "get-sensor-map", NULL, } -}; - -static inline const struct cmd_info *find_cmd_info(uint16_t type, const char *name) -{ - uint32_t i; - for (i = 0; i < SPA_N_ELEMENTS(cmd_info); i++) { - if ((name == NULL && type == cmd_info[i].type) || - (name != NULL && spa_streq(name, cmd_info[i].name))) - return &cmd_info[i]; - } - return NULL; -} - -int avbtp_aecp_aem_handle_command(struct aecp *aecp, const void *m, int len) -{ - const struct avbtp_packet_aecp_aem *p = m; - uint16_t cmd_type; - const struct cmd_info *info; - - cmd_type = AVBTP_PACKET_AEM_GET_COMMAND_TYPE(p); - - info = find_cmd_info(cmd_type, NULL); - if (info == NULL) - return reply_not_implemented(aecp, m, len); - - pw_log_info("aem command %s", info->name); - - if (info->handle == NULL) - return reply_not_implemented(aecp, m, len); - - return info->handle(aecp, m, len); -} - -int avbtp_aecp_aem_handle_response(struct aecp *aecp, const void *m, int len) -{ - return 0; -} diff --git a/src/modules/module-avbtp/aecp-aem.h b/src/modules/module-avbtp/aecp-aem.h deleted file mode 100644 index 2ddb8470e..000000000 --- a/src/modules/module-avbtp/aecp-aem.h +++ /dev/null @@ -1,345 +0,0 @@ -/* AVB support - * - * Copyright © 2022 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef AVBTP_AEM_H -#define AVBTP_AEM_H - -#include "aecp.h" - -#define AVBTP_AECP_AEM_STATUS_SUCCESS 0 -#define AVBTP_AECP_AEM_STATUS_NOT_IMPLEMENTED 1 -#define AVBTP_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR 2 -#define AVBTP_AECP_AEM_STATUS_ENTITY_LOCKED 3 -#define AVBTP_AECP_AEM_STATUS_ENTITY_ACQUIRED 4 -#define AVBTP_AECP_AEM_STATUS_NOT_AUTHENTICATED 5 -#define AVBTP_AECP_AEM_STATUS_AUTHENTICATION_DISABLED 6 -#define AVBTP_AECP_AEM_STATUS_BAD_ARGUMENTS 7 -#define AVBTP_AECP_AEM_STATUS_NO_RESOURCES 8 -#define AVBTP_AECP_AEM_STATUS_IN_PROGRESS 9 -#define AVBTP_AECP_AEM_STATUS_ENTITY_MISBEHAVING 10 -#define AVBTP_AECP_AEM_STATUS_NOT_SUPPORTED 11 -#define AVBTP_AECP_AEM_STATUS_STREAM_IS_RUNNING 12 - -#define AVBTP_AECP_AEM_CMD_ACQUIRE_ENTITY 0x0000 -#define AVBTP_AECP_AEM_CMD_LOCK_ENTITY 0x0001 -#define AVBTP_AECP_AEM_CMD_ENTITY_AVAILABLE 0x0002 -#define AVBTP_AECP_AEM_CMD_CONTROLLER_AVAILABLE 0x0003 -#define AVBTP_AECP_AEM_CMD_READ_DESCRIPTOR 0x0004 -#define AVBTP_AECP_AEM_CMD_WRITE_DESCRIPTOR 0x0005 -#define AVBTP_AECP_AEM_CMD_SET_CONFIGURATION 0x0006 -#define AVBTP_AECP_AEM_CMD_GET_CONFIGURATION 0x0007 -#define AVBTP_AECP_AEM_CMD_SET_STREAM_FORMAT 0x0008 -#define AVBTP_AECP_AEM_CMD_GET_STREAM_FORMAT 0x0009 -#define AVBTP_AECP_AEM_CMD_SET_VIDEO_FORMAT 0x000a -#define AVBTP_AECP_AEM_CMD_GET_VIDEO_FORMAT 0x000b -#define AVBTP_AECP_AEM_CMD_SET_SENSOR_FORMAT 0x000c -#define AVBTP_AECP_AEM_CMD_GET_SENSOR_FORMAT 0x000d -#define AVBTP_AECP_AEM_CMD_SET_STREAM_INFO 0x000e -#define AVBTP_AECP_AEM_CMD_GET_STREAM_INFO 0x000f -#define AVBTP_AECP_AEM_CMD_SET_NAME 0x0010 -#define AVBTP_AECP_AEM_CMD_GET_NAME 0x0011 -#define AVBTP_AECP_AEM_CMD_SET_ASSOCIATION_ID 0x0012 -#define AVBTP_AECP_AEM_CMD_GET_ASSOCIATION_ID 0x0013 -#define AVBTP_AECP_AEM_CMD_SET_SAMPLING_RATE 0x0014 -#define AVBTP_AECP_AEM_CMD_GET_SAMPLING_RATE 0x0015 -#define AVBTP_AECP_AEM_CMD_SET_CLOCK_SOURCE 0x0016 -#define AVBTP_AECP_AEM_CMD_GET_CLOCK_SOURCE 0x0017 -#define AVBTP_AECP_AEM_CMD_SET_CONTROL 0x0018 -#define AVBTP_AECP_AEM_CMD_GET_CONTROL 0x0019 -#define AVBTP_AECP_AEM_CMD_INCREMENT_CONTROL 0x001a -#define AVBTP_AECP_AEM_CMD_DECREMENT_CONTROL 0x001b -#define AVBTP_AECP_AEM_CMD_SET_SIGNAL_SELECTOR 0x001c -#define AVBTP_AECP_AEM_CMD_GET_SIGNAL_SELECTOR 0x001d -#define AVBTP_AECP_AEM_CMD_SET_MIXER 0x001e -#define AVBTP_AECP_AEM_CMD_GET_MIXER 0x001f -#define AVBTP_AECP_AEM_CMD_SET_MATRIX 0x0020 -#define AVBTP_AECP_AEM_CMD_GET_MATRIX 0x0021 -#define AVBTP_AECP_AEM_CMD_START_STREAMING 0x0022 -#define AVBTP_AECP_AEM_CMD_STOP_STREAMING 0x0023 -#define AVBTP_AECP_AEM_CMD_REGISTER_UNSOLICITED_NOTIFICATION 0x0024 -#define AVBTP_AECP_AEM_CMD_DEREGISTER_UNSOLICITED_NOTIFICATION 0x0025 -#define AVBTP_AECP_AEM_CMD_IDENTIFY_NOTIFICATION 0x0026 -#define AVBTP_AECP_AEM_CMD_GET_AVB_INFO 0x0027 -#define AVBTP_AECP_AEM_CMD_GET_AS_PATH 0x0028 -#define AVBTP_AECP_AEM_CMD_GET_COUNTERS 0x0029 -#define AVBTP_AECP_AEM_CMD_REBOOT 0x002a -#define AVBTP_AECP_AEM_CMD_GET_AUDIO_MAP 0x002b -#define AVBTP_AECP_AEM_CMD_ADD_AUDIO_MAPPINGS 0x002c -#define AVBTP_AECP_AEM_CMD_REMOVE_AUDIO_MAPPINGS 0x002d -#define AVBTP_AECP_AEM_CMD_GET_VIDEO_MAP 0x002e -#define AVBTP_AECP_AEM_CMD_ADD_VIDEO_MAPPINGS 0x002f -#define AVBTP_AECP_AEM_CMD_REMOVE_VIDEO_MAPPINGS 0x0030 -#define AVBTP_AECP_AEM_CMD_GET_SENSOR_MAP 0x0031 -#define AVBTP_AECP_AEM_CMD_ADD_SENSOR_MAPPINGS 0x0032 -#define AVBTP_AECP_AEM_CMD_REMOVE_SENSOR_MAPPINGS 0x0033 -#define AVBTP_AECP_AEM_CMD_START_OPERATION 0x0034 -#define AVBTP_AECP_AEM_CMD_ABORT_OPERATION 0x0035 -#define AVBTP_AECP_AEM_CMD_OPERATION_STATUS 0x0036 -#define AVBTP_AECP_AEM_CMD_AUTH_ADD_KEY 0x0037 -#define AVBTP_AECP_AEM_CMD_AUTH_DELETE_KEY 0x0038 -#define AVBTP_AECP_AEM_CMD_AUTH_GET_KEY_LIST 0x0039 -#define AVBTP_AECP_AEM_CMD_AUTH_GET_KEY 0x003a -#define AVBTP_AECP_AEM_CMD_AUTH_ADD_KEY_TO_CHAIN 0x003b -#define AVBTP_AECP_AEM_CMD_AUTH_DELETE_KEY_FROM_CHAIN 0x003c -#define AVBTP_AECP_AEM_CMD_AUTH_GET_KEYCHAIN_LIST 0x003d -#define AVBTP_AECP_AEM_CMD_AUTH_GET_IDENTITY 0x003e -#define AVBTP_AECP_AEM_CMD_AUTH_ADD_TOKEN 0x003f -#define AVBTP_AECP_AEM_CMD_AUTH_DELETE_TOKEN 0x0040 -#define AVBTP_AECP_AEM_CMD_AUTHENTICATE 0x0041 -#define AVBTP_AECP_AEM_CMD_DEAUTHENTICATE 0x0042 -#define AVBTP_AECP_AEM_CMD_ENABLE_TRANSPORT_SECURITY 0x0043 -#define AVBTP_AECP_AEM_CMD_DISABLE_TRANSPORT_SECURITY 0x0044 -#define AVBTP_AECP_AEM_CMD_ENABLE_STREAM_ENCRYPTION 0x0045 -#define AVBTP_AECP_AEM_CMD_DISABLE_STREAM_ENCRYPTION 0x0046 -#define AVBTP_AECP_AEM_CMD_SET_MEMORY_OBJECT_LENGTH 0x0047 -#define AVBTP_AECP_AEM_CMD_GET_MEMORY_OBJECT_LENGTH 0x0048 -#define AVBTP_AECP_AEM_CMD_SET_STREAM_BACKUP 0x0049 -#define AVBTP_AECP_AEM_CMD_GET_STREAM_BACKUP 0x004a -#define AVBTP_AECP_AEM_CMD_EXPANSION 0x7fff - -#define AVBTP_AEM_ACQUIRE_ENTITY_PERSISTENT_FLAG (1<<0) - -struct avbtp_packet_aecp_aem_acquire { - uint32_t flags; - uint64_t owner_guid; - uint16_t descriptor_type; - uint16_t descriptor_id; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_lock { - uint32_t flags; - uint64_t locked_guid; - uint16_t descriptor_type; - uint16_t descriptor_id; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_read_descriptor { - uint16_t configuration; - uint8_t reserved[2]; - uint16_t descriptor_type; - uint16_t descriptor_id; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_configuration { - uint16_t reserved; - uint16_t configuration_index; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_stream_format { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint64_t stream_format; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_video_format { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint32_t format_specific; - uint16_t aspect_ratio; - uint16_t color_space; - uint32_t frame_size; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_sensor_format { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint64_t sensor_format; -} __attribute__ ((__packed__)); - - -#define AVBTP_AEM_STREAM_INFO_FLAG_CLASS_B (1u<<0) -#define AVBTP_AEM_STREAM_INFO_FLAG_FAST_CONNECT (1u<<1) -#define AVBTP_AEM_STREAM_INFO_FLAG_SAVED_STATE (1u<<2) -#define AVBTP_AEM_STREAM_INFO_FLAG_STREAMING_WAIT (1u<<3) -#define AVBTP_AEM_STREAM_INFO_FLAG_ENCRYPTED_PDU (1u<<4) -#define AVBTP_AEM_STREAM_INFO_FLAG_STREAM_VLAN_ID_VALID (1u<<25) -#define AVBTP_AEM_STREAM_INFO_FLAG_CONNECTED (1u<<26) -#define AVBTP_AEM_STREAM_INFO_FLAG_MSRP_FAILURE_VALID (1u<<27) -#define AVBTP_AEM_STREAM_INFO_FLAG_STREAM_DEST_MAC_VALID (1u<<28) -#define AVBTP_AEM_STREAM_INFO_FLAG_MSRP_ACC_LAT_VALID (1u<<29) -#define AVBTP_AEM_STREAM_INFO_FLAG_STREAM_ID_VALID (1u<<30) -#define AVBTP_AEM_STREAM_INFO_FLAG_STREAM_FORMAT_VALID (1u<<31) - -struct avbtp_packet_aecp_aem_setget_stream_info { - uint16_t descriptor_type; - uint16_t descriptor_index; - uint32_t aem_stream_info_flags; - uint64_t stream_format; - uint64_t stream_id; - uint32_t msrp_accumulated_latency; - uint8_t stream_dest_mac[6]; - uint8_t msrp_failure_code; - uint8_t reserved; - uint64_t msrp_failure_bridge_id; - uint16_t stream_vlan_id; - uint16_t reserved2; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_name { - uint16_t descriptor_type; - uint16_t descriptor_index; - uint16_t name_index; - uint16_t configuration_index; - char name[64]; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_association_id { - uint16_t descriptor_type; - uint16_t descriptor_index; - uint64_t association_id; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_sampling_rate { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint32_t sampling_rate; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_clock_source { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint16_t clock_source_index; - uint16_t reserved; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_control { - uint16_t descriptor_type; - uint16_t descriptor_id; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_incdec_control { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint16_t index_count; - uint16_t reserved; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_signal_selector { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint16_t signal_type; - uint16_t signal_index; - uint16_t signal_output; - uint16_t reserved; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_mixer { - uint16_t descriptor_type; - uint16_t descriptor_id; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_setget_matrix { - uint16_t descriptor_type; - uint16_t descriptor_index; - uint16_t matrix_column; - uint16_t matrix_row; - uint16_t region_width; - uint16_t region_height; - uint16_t rep_direction_value_count; - uint16_t item_offset; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_startstop_streaming { - uint16_t descriptor_type; - uint16_t descriptor_id; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_identify_notification { - uint16_t descriptor_type; - uint16_t descriptor_id; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_msrp_mapping { - uint8_t traffic_class; - uint8_t priority; - uint16_t vlan_id; -} __attribute__ ((__packed__)); - -#define AVBTP_AEM_AVB_INFO_FLAG_GPTP_GRANDMASTER_SUPPORTED (1u<<0) -#define AVBTP_AEM_AVB_INFO_FLAG_GPTP_ENABLED (1u<<1) -#define AVBTP_AEM_AVB_INFO_FLAG_SRP_ENABLED (1u<<2) - -struct avbtp_packet_aecp_aem_get_avb_info { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint64_t gptp_grandmaster_id; - uint32_t propagation_delay; - uint8_t gptp_domain_number; - uint8_t flags; - uint16_t msrp_mappings_count; - uint8_t msrp_mappings[0]; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_get_as_path { - uint16_t descriptor_index; - uint16_t reserved; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_get_counters { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint32_t counters_valid; - uint8_t counters_block[0]; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_reboot { - uint16_t descriptor_type; - uint16_t descriptor_id; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_start_operation { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint16_t operation_id; - uint16_t operation_type; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem_operation_status { - uint16_t descriptor_type; - uint16_t descriptor_id; - uint16_t operation_id; - uint16_t percent_complete; -} __attribute__ ((__packed__)); - -struct avbtp_packet_aecp_aem { - struct avbtp_packet_aecp_header aecp; -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned u:1; - unsigned cmd1:7; -#elif __BYTE_ORDER == __LITTLE_ENDIAN - unsigned cmd1:7; - unsigned u:1; -#endif - uint8_t cmd2; - uint8_t payload[0]; -} __attribute__ ((__packed__)); - -#define AVBTP_PACKET_AEM_SET_COMMAND_TYPE(p,v) ((p)->cmd1 = ((v) >> 8),(p)->cmd2 = (v)) - -#define AVBTP_PACKET_AEM_GET_COMMAND_TYPE(p) ((p)->cmd1 << 8 | (p)->cmd2) - -int avbtp_aecp_aem_handle_command(struct aecp *aecp, const void *m, int len); -int avbtp_aecp_aem_handle_response(struct aecp *aecp, const void *m, int len); - -#endif /* AVBTP_AEM_H */ diff --git a/src/modules/module-avbtp/maap.h b/src/modules/module-avbtp/maap.h deleted file mode 100644 index ca0ca77d5..000000000 --- a/src/modules/module-avbtp/maap.h +++ /dev/null @@ -1,61 +0,0 @@ -/* AVB support - * - * Copyright © 2022 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef AVBTP_MAAP_H -#define AVBTP_MAAP_H - -#include "packets.h" -#include "internal.h" - -#define AVBTP_MAAP_MESSAGE_TYPE_PROBE 1 -#define AVBTP_MAAP_MESSAGE_TYPE_DEFEND 2 -#define AVBTP_MAAP_MESSAGE_TYPE_ANNOUNCE 3 - -struct avbtp_packet_maap { - struct avbtp_packet_header hdr; - uint64_t stream_id; - uint8_t request_start[6]; - uint16_t request_count; - uint8_t conflict_start[6]; - uint16_t conflict_count; -} __attribute__ ((__packed__)); - -#define AVBTP_PACKET_MAAP_SET_MESSAGE_TYPE(p,v) AVBTP_PACKET_SET_SUB1(&(p)->hdr, v) -#define AVBTP_PACKET_MAAP_SET_MAAP_VERSION(p,v) AVBTP_PACKET_SET_SUB2(&(p)->hdr, v) -#define AVBTP_PACKET_MAAP_SET_STREAM_ID(p,v) ((p)->stream_id = htobe64(v)) -#define AVBTP_PACKET_MAAP_SET_REQUEST_START(p,v) memcpy((p)->request_start, (v), 6) -#define AVBTP_PACKET_MAAP_SET_REQUEST_COUNT(p,v) ((p)->request_count = htons(v)) -#define AVBTP_PACKET_MAAP_SET_CONFLICT_START(p,v) memcpy((p)->conflict_start, (v), 6) -#define AVBTP_PACKET_MAAP_SET_CONFLICT_COUNT(p,v) ((p)->conflict_count = htons(v)) -#define AVBTP_PACKET_MAAP_GET_MESSAGE_TYPE(p) AVBTP_PACKET_GET_SUB1(&(p)->hdr) -#define AVBTP_PACKET_MAAP_GET_MAAP_VERSION(p) AVBTP_PACKET_GET_SUB2(&(p)->hdr) -#define AVBTP_PACKET_MAAP_GET_STREAM_ID(p) be64toh((p)->stream_id) -#define AVBTP_PACKET_MAAP_GET_REQUEST_START(p) ((p)->request_start) -#define AVBTP_PACKET_MAAP_GET_REQUEST_COUNT(p) ntohs((p)->request_count) -#define AVBTP_PACKET_MAAP_GET_CONFLICT_START(p) ((p)->conflict_start) -#define AVBTP_PACKET_MAAP_GET_CONFLICT_COUNT(p) ntohs((p)->conflict_count) - -int avbtp_maap_register(struct server *server); - -#endif /* AVBTP_MAAP_H */ diff --git a/src/modules/module-avbtp/mrp.h b/src/modules/module-avbtp/mrp.h deleted file mode 100644 index d10f3546c..000000000 --- a/src/modules/module-avbtp/mrp.h +++ /dev/null @@ -1,171 +0,0 @@ -/* AVB support - * - * Copyright © 2022 Wim Taymans - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef AVBTP_MRP_H -#define AVBTP_MRP_H - -#include "packets.h" -#include "internal.h" - -#define AVBTP_MRP_PROTOCOL_VERSION 0 - -struct avbtp_packet_mrp { - struct avbtp_ethernet_header eth; - uint8_t version; -} __attribute__ ((__packed__)); - -struct avbtp_packet_mrp_hdr { - uint8_t attribute_type; - uint8_t attribute_length; -} __attribute__ ((__packed__)); - -struct avbtp_packet_mrp_vector { -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned lva:3; - unsigned nv1:5; -#elif __BYTE_ORDER == __LITTLE_ENDIAN - unsigned nv1:5; - unsigned lva:3; -#endif - uint8_t nv2; - uint8_t first_value[0]; -} __attribute__ ((__packed__)); - -#define AVBTP_MRP_VECTOR_SET_NUM_VALUES(a,v) ((a)->nv1 = ((v) >> 8),(a)->nv2 = (v)) -#define AVBTP_MRP_VECTOR_GET_NUM_VALUES(a) ((a)->nv1 << 8 | (a)->nv2) - -struct avbtp_packet_mrp_footer { - uint16_t end_mark; -} __attribute__ ((__packed__)); - -/* applicant states */ -#define AVBTP_MRP_VO 0 /* Very anxious Observer */ -#define AVBTP_MRP_VP 1 /* Very anxious Passive */ -#define AVBTP_MRP_VN 2 /* Very anxious New */ -#define AVBTP_MRP_AN 3 /* Anxious New */ -#define AVBTP_MRP_AA 4 /* Anxious Active */ -#define AVBTP_MRP_QA 5 /* Quiet Active */ -#define AVBTP_MRP_LA 6 /* Leaving Active */ -#define AVBTP_MRP_AO 7 /* Anxious Observer */ -#define AVBTP_MRP_QO 8 /* Quiet Observer */ -#define AVBTP_MRP_AP 9 /* Anxious Passive */ -#define AVBTP_MRP_QP 10 /* Quiet Passive */ -#define AVBTP_MRP_LO 11 /* Leaving Observer */ - -/* registrar states */ -#define AVBTP_MRP_IN 16 -#define AVBTP_MRP_LV 17 -#define AVBTP_MRP_MT 18 - -/* events */ -#define AVBTP_MRP_EVENT_BEGIN 0 -#define AVBTP_MRP_EVENT_NEW 1 -#define AVBTP_MRP_EVENT_JOIN 2 -#define AVBTP_MRP_EVENT_LV 3 -#define AVBTP_MRP_EVENT_TX 4 -#define AVBTP_MRP_EVENT_TX_LVA 5 -#define AVBTP_MRP_EVENT_TX_LVAF 6 -#define AVBTP_MRP_EVENT_RX_NEW 7 -#define AVBTP_MRP_EVENT_RX_JOININ 8 -#define AVBTP_MRP_EVENT_RX_IN 9 -#define AVBTP_MRP_EVENT_RX_JOINMT 10 -#define AVBTP_MRP_EVENT_RX_MT 11 -#define AVBTP_MRP_EVENT_RX_LV 12 -#define AVBTP_MRP_EVENT_RX_LVA 13 -#define AVBTP_MRP_EVENT_FLUSH 14 -#define AVBTP_MRP_EVENT_REDECLARE 15 -#define AVBTP_MRP_EVENT_PERIODIC 16 -#define AVBTP_MRP_EVENT_LV_TIMER 17 -#define AVBTP_MRP_EVENT_LVA_TIMER 18 - -/* attribute events */ -#define AVBTP_MRP_ATTRIBUTE_EVENT_NEW 0 -#define AVBTP_MRP_ATTRIBUTE_EVENT_JOININ 1 -#define AVBTP_MRP_ATTRIBUTE_EVENT_IN 2 -#define AVBTP_MRP_ATTRIBUTE_EVENT_JOINMT 3 -#define AVBTP_MRP_ATTRIBUTE_EVENT_MT 4 -#define AVBTP_MRP_ATTRIBUTE_EVENT_LV 5 - -#define AVBTP_MRP_SEND_NEW 1 -#define AVBTP_MRP_SEND_JOININ 2 -#define AVBTP_MRP_SEND_IN 3 -#define AVBTP_MRP_SEND_JOINMT 4 -#define AVBTP_MRP_SEND_MT 5 -#define AVBTP_MRP_SEND_LV 6 - -#define AVBTP_MRP_NOTIFY_JOIN_NEW (1u<<0) -#define AVBTP_MRP_NOTIFY_JOIN (1u<<1) -#define AVBTP_MRP_NOTIFY_LEAVE (1u<<2) - -struct avbtp_mrp_attribute { - uint8_t pending_send; - uint8_t pending_notify; - void *user_data; -}; - -struct avbtp_mrp_parse_info { -#define AVBTP_VERSION_MRP_PARSE_INFO 0 - uint32_t version; - - bool (*check_header) (void *data, const void *hdr, size_t *hdr_size, bool *has_params); - - int (*attr_event) (void *data, uint64_t now, uint8_t attribute_type, uint8_t event); - - int (*process) (void *data, uint64_t now, uint8_t attribute_type, const void *value, - uint8_t event, uint8_t param, int index); -}; - - -int avbtp_mrp_parse_packet(struct avbtp_mrp *mrp, uint64_t now, const void *pkt, int size, - const struct avbtp_mrp_parse_info *cb, void *data); - -struct avbtp_mrp_attribute *avbtp_mrp_attribute_new(struct avbtp_mrp *mrp, - size_t user_size); - -void avbtp_mrp_update_state(struct avbtp_mrp *mrp, uint64_t now, - struct avbtp_mrp_attribute *attr, int event); - -void avbtp_mrp_rx_event(struct avbtp_mrp *mrp, uint64_t now, - struct avbtp_mrp_attribute *attr, uint8_t event); - -void avbtp_mrp_mad_begin(struct avbtp_mrp *mrp, uint64_t now, struct avbtp_mrp_attribute *attr); -void avbtp_mrp_mad_join(struct avbtp_mrp *mrp, uint64_t now, struct avbtp_mrp_attribute *attr, bool is_new); -void avbtp_mrp_mad_leave(struct avbtp_mrp *mrp, uint64_t now, struct avbtp_mrp_attribute *attr); - -struct avbtp_mrp_events { -#define AVBTP_VERSION_MRP_ATTRIBUTE_CALLBACKS 0 - uint32_t version; - - void (*event) (void *data, uint64_t now, uint8_t event); - - void (*notify) (void *data, uint64_t now, struct avbtp_mrp_attribute *attr, uint8_t notify); -}; - -struct avbtp_mrp *avbtp_mrp_new(struct server *server); -void avbtp_mrp_destroy(struct avbtp_mrp *mrp); - -void avbtp_mrp_add_listener(struct avbtp_mrp *mrp, struct spa_hook *listener, - const struct avbtp_mrp_events *events, void *data); - -#endif /* AVBTP_MRP_H */