mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-20 17:20:02 +01:00
module-avb: milan: adding get/set for configuration
This commit is contained in:
parent
43bf1b8f7c
commit
b22e442b10
4 changed files with 218 additions and 0 deletions
|
|
@ -743,6 +743,9 @@ if build_module_avb
|
||||||
'module-avb/aecp-aem-cmds-resps/cmd-register-unsolicited-notifications.c',
|
'module-avb/aecp-aem-cmds-resps/cmd-register-unsolicited-notifications.c',
|
||||||
'module-avb/aecp-aem-cmds-resps/cmd-get-set-stream-format.c',
|
'module-avb/aecp-aem-cmds-resps/cmd-get-set-stream-format.c',
|
||||||
'module-avb/aecp-aem-cmds-resps/cmd-lock-entity.c',
|
'module-avb/aecp-aem-cmds-resps/cmd-lock-entity.c',
|
||||||
|
'module-avb/aecp-aem-cmds-resps/cmd-get-set-configuration.c',
|
||||||
|
'module-avb/aecp-aem-cmds-resps/cmd-lock-entity.c',
|
||||||
|
'module-avb/aecp-aem-cmds-resps/cmd-register-unsolicited-notifications.c',
|
||||||
'module-avb/aecp-aem-cmds-resps/reply-unsol-helpers.c',
|
'module-avb/aecp-aem-cmds-resps/reply-unsol-helpers.c',
|
||||||
'module-avb/es-builder.c',
|
'module-avb/es-builder.c',
|
||||||
'module-avb/avdecc.c',
|
'module-avb/avdecc.c',
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,194 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "../aecp-aem.h"
|
||||||
|
#include "../aecp-aem-state.h"
|
||||||
|
#include "../aecp-aem-descriptors.h"
|
||||||
|
#include "../aecp-aem-types.h"
|
||||||
|
|
||||||
|
#include "cmd-get-set-configuration.h"
|
||||||
|
#include "cmd-resp-helpers.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static int handle_unsol_set_configuration_milan_v12(struct aecp *aecp, struct descriptor *desc,
|
||||||
|
uint64_t ctrler_id)
|
||||||
|
{
|
||||||
|
/* Reply */
|
||||||
|
uint8_t buf[512];
|
||||||
|
void *m = buf;
|
||||||
|
struct avb_aem_desc_entity *entity_desc;
|
||||||
|
struct avb_ethernet_header *h = m;
|
||||||
|
struct avb_packet_aecp_aem *p = SPA_PTROFF(h, sizeof(*h), void);
|
||||||
|
struct avb_packet_aecp_aem_setget_configuration *cfg;
|
||||||
|
size_t len = sizeof (*h) + sizeof(*p) + sizeof(*cfg);
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
entity_desc = (struct avb_aem_desc_entity*) desc->ptr;
|
||||||
|
cfg = (struct avb_packet_aecp_aem_setget_configuration *) p->payload;
|
||||||
|
cfg->configuration_index = htons(entity_desc->current_configuration);
|
||||||
|
p->aecp.target_guid = htobe64(aecp->server->entity_id);
|
||||||
|
|
||||||
|
AVB_PACKET_AEM_SET_COMMAND_TYPE(p, AVB_AECP_AEM_CMD_SET_CONFIGURATION);
|
||||||
|
rc = reply_unsolicited_notifications_ctrler_id(aecp, ctrler_id,
|
||||||
|
buf, len, false);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
pw_log_error("unsol notif failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common handler for SET_CONFIGURATION command
|
||||||
|
*
|
||||||
|
* Milan v1.2, Sec. 5.4.2.5
|
||||||
|
* IEEE 1722.1-2021, Sec. 7.4.7
|
||||||
|
*/
|
||||||
|
int handle_cmd_set_configuration_milan_v12(struct aecp *aecp, int64_t now,
|
||||||
|
const void *m, int len)
|
||||||
|
{
|
||||||
|
uint8_t buf[2048];
|
||||||
|
struct server *server = aecp->server;
|
||||||
|
const struct avb_ethernet_header *h = m;
|
||||||
|
const struct avb_packet_aecp_aem *p = SPA_PTROFF(h, sizeof(*h), void);
|
||||||
|
/* Reply */
|
||||||
|
struct avb_ethernet_header *h_reply;
|
||||||
|
struct avb_packet_aecp_aem *p_reply;
|
||||||
|
struct avb_packet_aecp_aem_setget_configuration *cfg;
|
||||||
|
|
||||||
|
/* Information about the current entity */
|
||||||
|
struct avb_aem_desc_entity *entity_desc;
|
||||||
|
uint16_t req_cfg_id, cur_cfg_id, cfg_count;
|
||||||
|
struct descriptor *desc;
|
||||||
|
int rc;
|
||||||
|
bool has_failed;
|
||||||
|
|
||||||
|
/* FIXME ACMP: IMPORTANT!!!! find the stream connection information
|
||||||
|
* whether they are running or not. */
|
||||||
|
|
||||||
|
/* Milan v1.2, Sec. 5.4.2.5
|
||||||
|
* The PAAD-AE shall not accept a SET_CONFIGURATION command if one of
|
||||||
|
* the Stream Input is bound or one of the Stream Output is streaming.
|
||||||
|
* In this case, the STREAM_IS_RUNNING error code shall be returned.
|
||||||
|
*
|
||||||
|
* If the PAAD-AE is locked by a controller, it shall not accept a
|
||||||
|
* SET_CONFIGURATION command from a different controller, and it shall
|
||||||
|
* also not change its current configuration by non-ATDECC
|
||||||
|
* means (proprietary remote control software, front-panel, ...).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** WARNING! Milan forces only one entity */
|
||||||
|
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);
|
||||||
|
|
||||||
|
// TODO maybe avoid copy here
|
||||||
|
memcpy(buf, m, len);
|
||||||
|
h_reply = (struct avb_ethernet_header *)buf;
|
||||||
|
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||||
|
|
||||||
|
cfg = (struct avb_packet_aecp_aem_setget_configuration*) p_reply->payload;
|
||||||
|
entity_desc = (struct avb_aem_desc_entity*) desc->ptr;
|
||||||
|
cur_cfg_id = ntohs(entity_desc->current_configuration);
|
||||||
|
req_cfg_id = ntohs(cfg->configuration_index);
|
||||||
|
cfg_count = ntohs(entity_desc->configurations_count);
|
||||||
|
|
||||||
|
if (entity_desc->entity_id != p->aecp.target_guid) {
|
||||||
|
pw_log_error("Invalid entity id");
|
||||||
|
has_failed = true;
|
||||||
|
/* TODO: req_cfg_id is zero based, cfg_count is not.
|
||||||
|
* Should be req_cfg_id >= cfg_count */
|
||||||
|
} else if (req_cfg_id >= cfg_count) {
|
||||||
|
pw_log_error("Requested %u, but has max %u id",
|
||||||
|
req_cfg_id, cfg_count);
|
||||||
|
has_failed = true;
|
||||||
|
} else if (req_cfg_id == cur_cfg_id) {
|
||||||
|
pw_log_warn("requested %u and same current %u id", req_cfg_id,
|
||||||
|
cur_cfg_id);
|
||||||
|
has_failed = true;
|
||||||
|
} else {
|
||||||
|
entity_desc->current_configuration = cfg->configuration_index;
|
||||||
|
has_failed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Always contains the current value,
|
||||||
|
* that is itcontains the new value if the command succeeds or the old
|
||||||
|
* value if it fails.
|
||||||
|
*/
|
||||||
|
if (has_failed) {
|
||||||
|
cfg->configuration_index = entity_desc->current_configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = reply_success(aecp, buf, len);
|
||||||
|
if (rc) {
|
||||||
|
pw_log_error("Reply Failed");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if(!has_failed) {
|
||||||
|
return handle_unsol_set_configuration_milan_v12(aecp, desc,
|
||||||
|
tobe64(p->aecp.controller_guid));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common handler for GET_CONFIGURATION command
|
||||||
|
* Milan v1.2, Sec. 5.4.2.6
|
||||||
|
* IEEE 1722.1-2021, Sec. 7.4.8
|
||||||
|
*/
|
||||||
|
int handle_cmd_get_configuration_common(struct aecp *aecp, int64_t now,
|
||||||
|
const void *m, int len)
|
||||||
|
{
|
||||||
|
uint8_t buf[2048];
|
||||||
|
struct server *server = aecp->server;
|
||||||
|
const struct avb_ethernet_header *h = m;
|
||||||
|
const struct avb_packet_aecp_aem *p = SPA_PTROFF(h, sizeof(*h), void);
|
||||||
|
/* Reply */
|
||||||
|
struct avb_ethernet_header *h_reply;
|
||||||
|
struct avb_packet_aecp_aem *p_reply;
|
||||||
|
struct avb_packet_aecp_aem_setget_configuration *cfg;
|
||||||
|
|
||||||
|
/* Information about the current entity */
|
||||||
|
struct avb_aem_desc_entity *entity_desc;
|
||||||
|
struct descriptor *desc;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
memcpy(buf, m, len);
|
||||||
|
h_reply = (struct avb_ethernet_header *)buf;
|
||||||
|
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||||
|
|
||||||
|
cfg = (struct avb_packet_aecp_aem_setget_configuration*) p_reply->payload;
|
||||||
|
entity_desc = (struct avb_aem_desc_entity*) desc->ptr;
|
||||||
|
|
||||||
|
if (entity_desc->entity_id != p->aecp.target_guid) {
|
||||||
|
pw_log_error("Invalid entity id");
|
||||||
|
return reply_status(aecp,
|
||||||
|
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg->configuration_index = entity_desc->current_configuration;
|
||||||
|
|
||||||
|
rc = reply_success(aecp, buf, len);
|
||||||
|
if (rc) {
|
||||||
|
pw_log_error("Reply Failed");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
#ifndef __AECP_AEM_CMD_GET_SET_CONFIGURATION_H__
|
||||||
|
#define __AECP_AEM_CMD_GET_SET_CONFIGURATION_H__
|
||||||
|
|
||||||
|
int handle_cmd_set_configuration_milan_v12(struct aecp *aecp, int64_t now,
|
||||||
|
const void *m, int len);
|
||||||
|
|
||||||
|
int handle_cmd_get_configuration_common(struct aecp *aecp, int64_t now,
|
||||||
|
const void *m, int len);
|
||||||
|
|
||||||
|
#endif //__AECP_AEM_CMD_GET_SET_CONFIGURATION_H__
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
/* The headers including the command and response of the system */
|
/* The headers including the command and response of the system */
|
||||||
#include "aecp-aem-cmds-resps/cmd-available.h"
|
#include "aecp-aem-cmds-resps/cmd-available.h"
|
||||||
|
#include "aecp-aem-cmds-resps/cmd-get-set-configuration.h"
|
||||||
|
#include "aecp-aem-cmds-resps/cmd-lock-entity.h"
|
||||||
#include "aecp-aem-cmds-resps/cmd-register-unsolicited-notifications.h"
|
#include "aecp-aem-cmds-resps/cmd-register-unsolicited-notifications.h"
|
||||||
#include "aecp-aem-cmds-resps/cmd-deregister-unsolicited-notifications.h"
|
#include "aecp-aem-cmds-resps/cmd-deregister-unsolicited-notifications.h"
|
||||||
#include "aecp-aem-cmds-resps/cmd-get-set-name.h"
|
#include "aecp-aem-cmds-resps/cmd-get-set-name.h"
|
||||||
|
|
@ -276,6 +278,9 @@ static const struct cmd_info cmd_info_avb_legacy[] = {
|
||||||
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_LOCK_ENTITY, true,
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_LOCK_ENTITY, true,
|
||||||
handle_lock_entity_avb_legacy),
|
handle_lock_entity_avb_legacy),
|
||||||
|
|
||||||
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_GET_CONFIGURATION, false,
|
||||||
|
handle_cmd_get_configuration_common),
|
||||||
|
|
||||||
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_READ_DESCRIPTOR, true,
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_READ_DESCRIPTOR, true,
|
||||||
handle_read_descriptor_common),
|
handle_read_descriptor_common),
|
||||||
|
|
||||||
|
|
@ -300,6 +305,12 @@ static const struct cmd_info cmd_info_milan_v12[] = {
|
||||||
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_GET_STREAM_FORMAT, true,
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_GET_STREAM_FORMAT, true,
|
||||||
handle_cmd_get_stream_format_milan_v12),
|
handle_cmd_get_stream_format_milan_v12),
|
||||||
|
|
||||||
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_SET_CONFIGURATION, false,
|
||||||
|
handle_cmd_set_configuration_milan_v12),
|
||||||
|
|
||||||
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_GET_CONFIGURATION, false,
|
||||||
|
handle_cmd_get_configuration_common),
|
||||||
|
|
||||||
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_READ_DESCRIPTOR, true,
|
AECP_AEM_HANDLE_CMD(AVB_AECP_AEM_CMD_READ_DESCRIPTOR, true,
|
||||||
handle_read_descriptor_common),
|
handle_read_descriptor_common),
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue