mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-05-06 06:46:29 -04:00
milan-avb: aecp-vendor-unique-milan-v12: dispatch via per-cmd table per Milan v1.2 Section 5.4.4
This commit is contained in:
parent
deeea620f6
commit
a16f3d704e
8 changed files with 217 additions and 108 deletions
|
|
@ -0,0 +1,84 @@
|
|||
/* SPDX-FileCopyrightText: Copyright © 2025 Alexandre Malki <alexandre.malki@kebag-logic.com> */
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <pipewire/pipewire.h>
|
||||
#include <spa/utils/defs.h>
|
||||
|
||||
#include "../aecp.h"
|
||||
#include "../aecp-vendor-unique-milan-v12.h"
|
||||
#include "../internal.h"
|
||||
|
||||
#include "cmd-get-milan-info.h"
|
||||
#include "cmd-resp-helpers.h"
|
||||
|
||||
/* Milan v1.2 Section 5.4.4.1 GET_MILAN_INFO Response payload. */
|
||||
struct avb_packet_aecp_mvu_get_milan_info_rsp {
|
||||
uint32_t protocol_version;
|
||||
uint32_t features_flags;
|
||||
uint32_t certification_version;
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
/* Milan v1.2 Section 5.4.4.1: protocol_version is 1 across every Milan release. */
|
||||
#define MILAN_MVU_PROTOCOL_VERSION 0x00000001u
|
||||
|
||||
/* Milan v1.2 Section 5.4.4.1 Table 5.20: features_flags bit 0 = REDUNDANCY (not
|
||||
* implemented), upper bits reserved. */
|
||||
#define MILAN_MVU_FEATURES_FLAGS 0x00000000u
|
||||
|
||||
/* Milan v1.2 Section 5.4.4.1: certification_version byte-encoded
|
||||
* major.minor.revision.build. Milan v1.2 = 0x01020000. */
|
||||
#define MILAN_MVU_CERTIFICATION_VERSION 0x01020000u
|
||||
|
||||
int handle_cmd_mvu_get_milan_info_milan_v12(struct aecp *aecp, int64_t now,
|
||||
const void *m, int len)
|
||||
{
|
||||
struct server *server = aecp->server;
|
||||
uint8_t buf[2048];
|
||||
struct avb_ethernet_header *h_reply;
|
||||
struct avb_packet_aecp_header *aecp_hdr;
|
||||
struct avb_packet_aecp_vendor_unique *vu_reply;
|
||||
struct avb_packet_aecp_mvu_get_milan_info_rsp *body;
|
||||
int total = (int)(sizeof(struct avb_ethernet_header) +
|
||||
sizeof(struct avb_packet_aecp_vendor_unique) +
|
||||
sizeof(struct avb_packet_aecp_mvu_get_milan_info_rsp));
|
||||
int wire = total < 60 ? 60 : total;
|
||||
|
||||
(void)now;
|
||||
|
||||
if (wire > (int)sizeof(buf))
|
||||
return -EMSGSIZE;
|
||||
|
||||
memcpy(buf, m, len);
|
||||
if (len < wire)
|
||||
memset(buf + len, 0, wire - len);
|
||||
|
||||
h_reply = (struct avb_ethernet_header *)buf;
|
||||
aecp_hdr = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||
vu_reply = (struct avb_packet_aecp_vendor_unique *)aecp_hdr;
|
||||
|
||||
AVB_PACKET_AECP_SET_MESSAGE_TYPE(aecp_hdr,
|
||||
AVB_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_RESPONSE);
|
||||
AVB_PACKET_AECP_SET_STATUS(aecp_hdr, AVB_AECP_STATUS_SUCCESS);
|
||||
|
||||
/* IEEE 1722-2011 Section 5.3 / IEEE 1722.1-2021 Section 9.2.1.1.7: CDL excludes
|
||||
* the 12-octet AVTPDU common header. */
|
||||
AVB_PACKET_SET_LENGTH(&aecp_hdr->hdr,
|
||||
(uint16_t)(total - sizeof(struct avb_ethernet_header) -
|
||||
sizeof(struct avb_packet_header) -
|
||||
sizeof(uint64_t)));
|
||||
|
||||
((uint8_t *)&vu_reply->command_type)[0] &= 0x7f;
|
||||
vu_reply->reserved = 0;
|
||||
|
||||
body = (struct avb_packet_aecp_mvu_get_milan_info_rsp *)vu_reply->payload;
|
||||
body->protocol_version = htonl(MILAN_MVU_PROTOCOL_VERSION);
|
||||
body->features_flags = htonl(MILAN_MVU_FEATURES_FLAGS);
|
||||
body->certification_version = htonl(MILAN_MVU_CERTIFICATION_VERSION);
|
||||
|
||||
return avb_server_send_packet(server, h_reply->src, AVB_TSN_ETH,
|
||||
buf, wire);
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
/* SPDX-FileCopyrightText: Copyright © 2025 Alexandre Malki <alexandre.malki@kebag-logic.com> */
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#ifndef __AVB_AECP_MVU_CMD_GET_MILAN_INFO_H__
|
||||
#define __AVB_AECP_MVU_CMD_GET_MILAN_INFO_H__
|
||||
|
||||
#include "../aecp-vendor-unique-milan-v12.h"
|
||||
|
||||
int handle_cmd_mvu_get_milan_info_milan_v12(struct aecp *aecp, int64_t now,
|
||||
const void *m, int len);
|
||||
|
||||
#endif /* __AVB_AECP_MVU_CMD_GET_MILAN_INFO_H__ */
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/* SPDX-FileCopyrightText: Copyright © 2025 Alexandre Malki <alexandre.malki@kebag-logic.com> */
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
#ifndef __AVB_AECP_MVU_HELPERS_H__
|
||||
#define __AVB_AECP_MVU_HELPERS_H__
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <spa/utils/defs.h>
|
||||
#include <pipewire/log.h>
|
||||
|
||||
#include "../aecp.h"
|
||||
#include "../aecp-vendor-unique-milan-v12.h"
|
||||
#include "../internal.h"
|
||||
|
||||
/* Milan v1.2 Section 5.4.3.2.2: r bit is reserved (must be 0) in commands and
|
||||
* responses. Command vs response is signalled by AECP message_type. */
|
||||
static inline int reply_mvu_status(struct aecp *aecp, int status,
|
||||
const void *m, int len)
|
||||
{
|
||||
uint8_t buf[2048];
|
||||
struct server *server = aecp->server;
|
||||
struct avb_ethernet_header *h = (void *)buf;
|
||||
struct avb_packet_aecp_header *reply = SPA_PTROFF(h, sizeof(*h), void);
|
||||
struct avb_packet_aecp_vendor_unique *vu_reply;
|
||||
int wire = len < 60 ? 60 : len;
|
||||
|
||||
if (len < 0 || (size_t)wire > sizeof(buf)) {
|
||||
pw_log_warn("reply_mvu_status: invalid len %d", len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(buf, m, len);
|
||||
if (wire > len)
|
||||
memset(buf + len, 0, wire - len);
|
||||
AVB_PACKET_AECP_SET_MESSAGE_TYPE(reply,
|
||||
AVB_AECP_MESSAGE_TYPE_VENDOR_UNIQUE_RESPONSE);
|
||||
AVB_PACKET_AECP_SET_STATUS(reply, status);
|
||||
|
||||
if ((size_t)wire >= sizeof(*h) + sizeof(*vu_reply)) {
|
||||
vu_reply = SPA_PTROFF(h, sizeof(*h), void);
|
||||
((uint8_t *)&vu_reply->command_type)[0] &= 0x7f;
|
||||
}
|
||||
|
||||
return avb_server_send_packet(server, h->src, AVB_TSN_ETH, buf, wire);
|
||||
}
|
||||
|
||||
static inline int reply_mvu_not_implemented(struct aecp *aecp,
|
||||
const void *m, int len)
|
||||
{
|
||||
return reply_mvu_status(aecp, AVB_AECP_STATUS_NOT_IMPLEMENTED, m, len);
|
||||
}
|
||||
|
||||
static inline int direct_reply_mvu_not_implemented(struct aecp *aecp,
|
||||
int64_t now, const void *m, int len)
|
||||
{
|
||||
(void)now;
|
||||
return reply_mvu_not_implemented(aecp, m, len);
|
||||
}
|
||||
|
||||
static inline int reply_mvu_success(struct aecp *aecp,
|
||||
const void *m, int len)
|
||||
{
|
||||
return reply_mvu_status(aecp, AVB_AECP_STATUS_SUCCESS, m, len);
|
||||
}
|
||||
|
||||
#endif /* __AVB_AECP_MVU_HELPERS_H__ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue