diff --git a/src/modules/meson.build b/src/modules/meson.build index d942fcd28..0d1f189a3 100644 --- a/src/modules/meson.build +++ b/src/modules/meson.build @@ -737,6 +737,7 @@ if build_module_avb 'module-avb/aecp.c', 'module-avb/aecp-aem.c', 'module-avb/aecp-aem-cmds-resps/cmd-lock-entity.c', + 'module-avb/aecp-aem-cmds-resps/cmd-available.c', 'module-avb/es-builder.c', 'module-avb/avdecc.c', 'module-avb/maap.c', diff --git a/src/modules/module-avb/aecp-aem-cmds-resps/cmd-available.c b/src/modules/module-avb/aecp-aem-cmds-resps/cmd-available.c new file mode 100644 index 000000000..90fadb899 --- /dev/null +++ b/src/modules/module-avb/aecp-aem-cmds-resps/cmd-available.c @@ -0,0 +1,64 @@ +/* AVB support */ +/* SPDX-FileCopyrightText: Copyright © 2025 Kebag-Logic */ +/* SPDX-FileCopyrightText: Copyright © 2025 Alex Malki */ +/* SPDX-License-Identifier: MIT */ + +#include "../aecp-aem-state.h" +#include "../descriptors.h" +#include "cmd-resp-helpers.h" +#include "cmd-resp-types.h" + +#include "cmd-available.h" + +/* ENTITY AVAILABLE according to the locking state */ +#define AECP_AEM_AVAIL_ENTITY_ACQUIRED (1<<0) +#define AECP_AEM_AVAIL_ENTITY_LOCKED (1<<1) +#define AECP_AEM_AVAIL_SUBENTITY_ACQUIRED (1<<2) +#define AECP_AEM_AVAIL_SUBENTITY_LOCKED (1<<3) + +int handle_cmd_entity_available_milan_v12(struct aecp *aecp, int64_t now, const void *m, + int len) +{ + uint8_t buf[512]; + + /* Commnand received specific */ + struct server *server = aecp->server; + const struct avb_ethernet_header *h = m; + struct avb_ethernet_header *h_reply; + const struct avb_packet_aecp_aem *p = SPA_PTROFF(h, sizeof(*h), void); + + /* Reply specific */ + struct avb_packet_aecp_aem *p_reply; + struct avb_packet_aecp_aem_available *avail_reply; + + /* Entity specific */ + struct descriptor *desc; + struct aecp_aem_entity_milan_state *entity_state; + struct aecp_aem_lock_state *lock; + + desc = server_find_descriptor(server, AVB_AEM_DESC_ENTITY, 0); + if (desc == NULL) { + return reply_status(aecp, + AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len); + } + + entity_state = desc->ptr; + lock = &entity_state->lock_state; + + /* Forge the response for the entity that is locking the device */ + memcpy(buf, m, len); + h_reply = (struct avb_ethernet_header *) buf; + p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void); + avail_reply = (struct avb_packet_aecp_aem_available*)p_reply->payload; + + avail_reply->acquired_controller_guid = 0; + + if ((lock->base_info.expire_timeout < now) || !lock->is_locked) { + avail_reply->flags = 0; + } else if (lock->is_locked) { + avail_reply->lock_controller_guid = htobe64(lock->locked_id); + avail_reply->flags = htonl(AECP_AEM_AVAIL_ENTITY_LOCKED); + } + + return reply_success(aecp, buf, len); +} diff --git a/src/modules/module-avb/aecp-aem-cmds-resps/cmd-available.h b/src/modules/module-avb/aecp-aem-cmds-resps/cmd-available.h new file mode 100644 index 000000000..7dce0f4cf --- /dev/null +++ b/src/modules/module-avb/aecp-aem-cmds-resps/cmd-available.h @@ -0,0 +1,16 @@ +/* AVB support */ +/* SPDX-FileCopyrightText: Copyright © 2025 Kebag-Logic */ +/* SPDX-FileCopyrightText: Copyright © 2025 Alex Malki */ +/* SPDX-License-Identifier: MIT */ +#ifndef __AVB_AECP_AEM_AVAILABLE_H__ +#define __AVB_AECP_AEM_AVAILABLE_H__ + +#include + +/** + * \brief Milan V1.2 implementation to handle available command. + */ +int handle_cmd_entity_available_milan_v12(struct aecp *aecp, int64_t now, const void *m, + int len); + +#endif //__AVB_AECP_AEM_AVAILABLE_H__ diff --git a/src/modules/module-avb/aecp-aem.c b/src/modules/module-avb/aecp-aem.c index 61c0cbf4b..816fd07d4 100644 --- a/src/modules/module-avb/aecp-aem.c +++ b/src/modules/module-avb/aecp-aem.c @@ -9,6 +9,7 @@ #include "utils.h" /* The headers including the command and response of the system */ +#include "aecp-aem-cmds-resps/cmd-available.h" #include "aecp-aem-cmds-resps/cmd-lock-entity.h" @@ -286,7 +287,7 @@ static const struct cmd_info cmd_info_milan_v12[] = { handle_cmd_lock_entity_milan_v12), AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_ENTITY_AVAILABLE, true, - NULL), + handle_cmd_entity_available_milan_v12), AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_READ_DESCRIPTOR, true, handle_read_descriptor_common),