milan-avb: adjust the msrp/adp and acmp state machine to communicate talker discovery and srp reserveration

This commit is contained in:
hackerman-kl 2026-04-12 11:12:15 +02:00 committed by Wim Taymans
parent 219adaa456
commit f5e97f0f6b
6 changed files with 97 additions and 57 deletions

View file

@ -1977,15 +1977,41 @@ static int acmp_generic_timer_handler_milan_v12(struct acmp *acmp, uint64_t now,
return cmd->state_handler(acmp, si_state, tmr->saved_packet, tmr->saved_packet_len, now);
}
static int acmp_generic_adp_srp_evt_lt_handler_milan_v12(struct acmp *acmp,
uint64_t entity_id, enum fsm_acmp_evt_milan_v12 event)
static int acmp_generic_srp_evt_lt_handler_milan_v12(struct acmp *acmp,
struct avb_msrp_attribute *msrp_attr,
enum fsm_acmp_evt_milan_v12 event, uint64_t now)
{
const struct listener_fsm_cmd *cmd;
struct stream_common *sc;
struct aecp_aem_stream_input_state *stream_in;
struct aecp_aem_stream_input_state_milan_v12 *si_state;
const struct listener_fsm_cmd *cmd;
sc = SPA_CONTAINER_OF(msrp_attr, struct stream_common, lstream_attr);
stream_in = SPA_CONTAINER_OF(sc, struct aecp_aem_stream_input_state, common);
si_state = SPA_CONTAINER_OF(stream_in,
struct aecp_aem_stream_input_state_milan_v12, stream_in_sta);
cmd = &cmd_listeners_states[si_state->acmp_status.fsm_acmp_state][event];
if (!cmd->state_handler) {
pw_log_warn("No handler: STATE:%s EVT:%s - ignoring",
fsm_acmp_state_milan_v12_str[si_state->acmp_status.fsm_acmp_state],
fsm_acmp_evt_milan_v12_str[event]);
return 0;
}
return cmd->state_handler(acmp, si_state, NULL, 0, now);
}
static int acmp_generic_adp_evt_lt_handler_milan_v12(struct acmp *acmp,
uint64_t entity_id, enum fsm_acmp_evt_milan_v12 event, uint64_t now)
{
struct aecp_aem_stream_input_state_milan_v12 *si_state;
const struct listener_fsm_cmd *cmd;
struct descriptor *desc;
enum fsm_acmp_state_milan_v12 fsm_state;
uint16_t desc_type = AVB_AEM_DESC_STREAM_INPUT;
int rc;
int rc = 0;
(void)entity_id;
for (uint16_t desc_index = 0; desc_index < UINT16_MAX; desc_index++) {
desc = server_find_descriptor(acmp->server, desc_type, desc_index);
@ -1993,33 +2019,22 @@ static int acmp_generic_adp_srp_evt_lt_handler_milan_v12(struct acmp *acmp,
break;
si_state = (struct aecp_aem_stream_input_state_milan_v12 *)desc->ptr;
fsm_state = si_state->acmp_status.fsm_acmp_state;
cmd = &cmd_listeners_states[fsm_state][event];
if (!cmd) {
pw_log_warn("Invalid transition STATE:%s EVT:%s - ignoring",
fsm_acmp_state_milan_v12_str[fsm_state],
cmd = &cmd_listeners_states[si_state->acmp_status.fsm_acmp_state][event];
if (!cmd->state_handler) {
pw_log_warn("No handler: STATE:%s EVT:%s - ignoring",
fsm_acmp_state_milan_v12_str[si_state->acmp_status.fsm_acmp_state],
fsm_acmp_evt_milan_v12_str[event]);
continue;
}
rc = cmd->state_handler(acmp, si_state, NULL, 0, 0);
if (rc){
rc = cmd->state_handler(acmp, si_state, NULL, 0, now);
if (rc)
pw_log_error("cmd failed for stream %p", si_state);
}
}
return 0;
return rc;
}
#if 0
static int acmp_generic_srp_evt_handler_milan_v12(struct acmp *acmp, uint64_t now,
uint64_t entity_id, enum fsm_acmp_evt_milan_v12 event)
{
return 0;
}
#endif
int acmp_init_talker_stream_milan_v12(struct acmp *acmp, void *acmp_status)
{
return 0;
@ -2061,28 +2076,32 @@ int handle_get_rx_state_command_milan_v12(struct acmp *acmp, uint64_t now,
FSM_ACMP_EVT_MILAN_V12_RCV_GET_RX_STATE);
}
int handle_evt_tk_discovered_milan_v12(struct acmp *acmp, uint64_t talker_guid)
int handle_evt_tk_discovered_milan_v12(struct acmp *acmp, uint64_t talker_guid,
uint64_t now)
{
return acmp_generic_adp_srp_evt_lt_handler_milan_v12(acmp, talker_guid,
FSM_ACMP_EVT_MILAN_V12_TK_DISCOVERED);
return acmp_generic_adp_evt_lt_handler_milan_v12(acmp, talker_guid,
FSM_ACMP_EVT_MILAN_V12_TK_DISCOVERED, now);
}
int handle_evt_tk_departed_milan_v12(struct acmp *acmp, uint64_t talker_guid)
int handle_evt_tk_departed_milan_v12(struct acmp *acmp, uint64_t talker_guid,
uint64_t now)
{
return acmp_generic_adp_srp_evt_lt_handler_milan_v12(acmp, talker_guid,
FSM_ACMP_EVT_MILAN_V12_TK_DEPARTED);
return acmp_generic_adp_evt_lt_handler_milan_v12(acmp, talker_guid,
FSM_ACMP_EVT_MILAN_V12_TK_DEPARTED, now);
}
int handle_evt_tk_registered_milan_v12(struct acmp *acmp, uint64_t talker_guid)
int handle_evt_tk_registered_milan_v12(struct acmp *acmp,
struct avb_msrp_attribute *msrp_attr, uint64_t now)
{
return acmp_generic_adp_srp_evt_lt_handler_milan_v12(acmp, talker_guid,
FSM_ACMP_EVT_MILAN_V12_TK_REGISTERED);
return acmp_generic_srp_evt_lt_handler_milan_v12(acmp, msrp_attr,
FSM_ACMP_EVT_MILAN_V12_TK_REGISTERED, now);
}
int handle_evt_tk_unregistered_milan_v12(struct acmp *acmp, uint64_t talker_guid)
int handle_evt_tk_unregistered_milan_v12(struct acmp *acmp,
struct avb_msrp_attribute *msrp_attr, uint64_t now)
{
return acmp_generic_adp_srp_evt_lt_handler_milan_v12(acmp, talker_guid,
FSM_ACMP_EVT_MILAN_V12_TK_UNREGISTERED);
return acmp_generic_srp_evt_lt_handler_milan_v12(acmp, msrp_attr,
FSM_ACMP_EVT_MILAN_V12_TK_UNREGISTERED, now);
}
int handle_probe_tx_command_milan_v12(struct acmp *acmp, uint64_t now,

View file

@ -6,6 +6,7 @@
#include <stdint.h>
#include "acmp-common.h"
#include "../msrp.h"
/** Milan v1.2 ACMP */
enum fsm_acmp_state_milan_v12 {
@ -51,11 +52,13 @@ int handle_probe_tx_response_milan_v12(struct acmp *acmp, uint64_t now,
int handle_get_rx_state_command_milan_v12(struct acmp *acmp, uint64_t now,
const void *m, int len);
int handle_evt_tk_discovered_milan_v12(struct acmp *acmp, uint64_t entity);
int handle_evt_tk_departed_milan_v12(struct acmp *acmp, uint64_t entity);
int handle_evt_tk_discovered_milan_v12(struct acmp *acmp, uint64_t entity, uint64_t now);
int handle_evt_tk_departed_milan_v12(struct acmp *acmp, uint64_t entity, uint64_t now);
int handle_evt_tk_registered_milan_v12(struct acmp *acmp, uint64_t talker_guid);
int handle_evt_tk_unregistered_milan_v12(struct acmp *acmp, uint64_t talker_guid);
int handle_evt_tk_registered_milan_v12(struct acmp *acmp,
struct avb_msrp_attribute *msrp_attr, uint64_t now);
int handle_evt_tk_unregistered_milan_v12(struct acmp *acmp,
struct avb_msrp_attribute *msrp_attr, uint64_t now);
int acmp_tmr_no_resp_milan_v12(struct acmp *acmp, uint64_t now);
int acmp_tmr_retry_milan_v12(struct acmp *acmp, uint64_t now);

View file

@ -254,13 +254,13 @@ static void acmp_periodic(void *data, uint64_t now)
}
int handle_evt_tk_discovered(struct avb_acmp *avb_acmp, uint64_t entity)
int handle_evt_tk_discovered(struct avb_acmp *avb_acmp, uint64_t entity, uint64_t now)
{
struct acmp *acmp = (struct acmp*)avb_acmp;
switch (acmp->server->avb_mode) {
case AVB_MODE_MILAN_V12:
return handle_evt_tk_discovered_milan_v12(acmp, entity);
return handle_evt_tk_discovered_milan_v12(acmp, entity, now);
break;
case AVB_MODE_LEGACY:
pw_log_warn("not implemented for legacy avb");
@ -273,13 +273,13 @@ int handle_evt_tk_discovered(struct avb_acmp *avb_acmp, uint64_t entity)
return -1;
}
int handle_evt_tk_departed(struct avb_acmp *avb_acmp, uint64_t entity)
int handle_evt_tk_departed(struct avb_acmp *avb_acmp, uint64_t entity, uint64_t now)
{
struct acmp *acmp = (struct acmp*)avb_acmp;
switch (acmp->server->avb_mode) {
case AVB_MODE_MILAN_V12:
return handle_evt_tk_departed_milan_v12(acmp, entity);
return handle_evt_tk_departed_milan_v12(acmp, entity, now);
break;
case AVB_MODE_LEGACY:
pw_log_warn("not implemented for legacy avb");
@ -292,13 +292,14 @@ int handle_evt_tk_departed(struct avb_acmp *avb_acmp, uint64_t entity)
return 0;
}
int handle_evt_tk_registered(struct avb_acmp *avb_acmp, uint64_t entity)
int handle_evt_tk_registered(struct avb_acmp *avb_acmp,
struct avb_msrp_attribute *msrp_attr, uint64_t now)
{
struct acmp *acmp = (struct acmp*)avb_acmp;
switch (acmp->server->avb_mode) {
case AVB_MODE_MILAN_V12:
return handle_evt_tk_registered_milan_v12(acmp, entity);
return handle_evt_tk_registered_milan_v12(acmp, msrp_attr, now);
break;
case AVB_MODE_LEGACY:
pw_log_warn("not implemented for legacy avb");
@ -311,13 +312,14 @@ int handle_evt_tk_registered(struct avb_acmp *avb_acmp, uint64_t entity)
return -1;
}
int handle_evt_tk_unregistered(struct avb_acmp *avb_acmp, uint64_t entity)
int handle_evt_tk_unregistered(struct avb_acmp *avb_acmp,
struct avb_msrp_attribute *msrp_attr, uint64_t now)
{
struct acmp *acmp = (struct acmp*)avb_acmp;
switch (acmp->server->avb_mode) {
case AVB_MODE_MILAN_V12:
return handle_evt_tk_unregistered_milan_v12(acmp, entity);
return handle_evt_tk_unregistered_milan_v12(acmp, msrp_attr, now);
break;
case AVB_MODE_LEGACY:
pw_log_warn("not implemented for legacy avb");

View file

@ -105,10 +105,12 @@ int acmp_fini_listener_stream(struct avb_acmp *avb_acmp,
struct avb_acmp *avb_acmp_register(struct server *server);
void avb_acmp_unregister(struct avb_acmp *acmp);
int handle_evt_tk_discovered(struct avb_acmp *avb_acmp, uint64_t entity);
int handle_evt_tk_departed(struct avb_acmp *avb_acmp, uint64_t entity);
int handle_evt_tk_discovered(struct avb_acmp *avb_acmp, uint64_t entity, uint64_t now);
int handle_evt_tk_departed(struct avb_acmp *avb_acmp, uint64_t entity, uint64_t now);
int handle_evt_tk_registered(struct avb_acmp *avb_acmp, uint64_t entity);
int handle_evt_tk_unregistered(struct avb_acmp *avb_acmp, uint64_t entity);
int handle_evt_tk_registered(struct avb_acmp *avb_acmp,
struct avb_msrp_attribute *msrp_attr, uint64_t now);
int handle_evt_tk_unregistered(struct avb_acmp *avb_acmp,
struct avb_msrp_attribute *msrp_attr, uint64_t now);
#endif /* AVB_ACMP_H */

View file

@ -132,7 +132,7 @@ static int adp_message(void *data, uint64_t now, const void *message, int len)
if (server->avb_mode == AVB_MODE_MILAN_V12) {
//Milan V1.2 Section 5.6.4.5.1
if (handle_evt_tk_discovered(server->acmp, entity_id)) {
if (handle_evt_tk_discovered(server->acmp, entity_id, now)) {
pw_log_info("handling available event");
return -1;
}
@ -146,7 +146,7 @@ static int adp_message(void *data, uint64_t now, const void *message, int len)
SPA_PTROFF(h_saved, sizeof(*h_saved), void);
if (p_saved->available_index != p->available_index) {
if (handle_evt_tk_departed(server->acmp, entity_id)) {
if (handle_evt_tk_departed(server->acmp, entity_id, now)) {
pw_log_info("handling departing event");
return -1;
}
@ -162,7 +162,7 @@ static int adp_message(void *data, uint64_t now, const void *message, int len)
return 0;
}
if (handle_evt_tk_discovered(server->acmp, entity_id)) {
if (handle_evt_tk_discovered(server->acmp, entity_id, now)) {
pw_log_warn("handling available event");
return -1;
}
@ -178,7 +178,7 @@ static int adp_message(void *data, uint64_t now, const void *message, int len)
if (e != NULL) {
if (server->avb_mode == AVB_MODE_MILAN_V12) {
// Milan v1.2 Section 5.6.4.5.3
handle_evt_tk_departed(server->acmp, entity_id);
handle_evt_tk_departed(server->acmp, entity_id, now);
}
pw_log_info("entity %s departing",
@ -232,7 +232,7 @@ static void check_timeout(struct adp *adp, uint64_t now)
pw_log_info("entity %s timeout",
avb_utils_format_id(buf, sizeof(buf), e->entity_id));
handle_evt_tk_departed(avb_acmp, e->entity_id);
handle_evt_tk_departed(avb_acmp, e->entity_id, now);
if (e->advertise)
send_departing(adp, now, e);

View file

@ -12,6 +12,7 @@
#include "utils.h"
#include "msrp.h"
#include "acmp.h"
static const uint8_t msrp_mac[6] = AVB_MSRP_MAC;
@ -55,6 +56,11 @@ static void notify_talker(struct msrp *msrp, uint64_t now, struct attr *attr, ui
{
pw_log_info("> notify talker advertise: %s", avb_mrp_notify_name(notify));
if (msrp->server->avb_mode == AVB_MODE_MILAN_V12) {
uint64_t stream_id = be64toh(attr->attr->attr.talker.stream_id);
if (notify == AVB_MRP_NOTIFY_NEW || notify == AVB_MRP_NOTIFY_JOIN)
handle_evt_tk_discovered(msrp->server->acmp, stream_id, now);
else if (notify == AVB_MRP_NOTIFY_LEAVE)
handle_evt_tk_departed(msrp->server->acmp, stream_id, now);
}
}
@ -71,12 +77,14 @@ static int process_talker(struct msrp *msrp, uint64_t now, uint8_t attr_type,
{
const struct avb_packet_msrp_talker *t = m;
struct attr *a;
spa_list_for_each(a, &msrp->attributes, link)
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;
avb_mrp_attribute_rx_event(a->attr->mrp, now, event);
}
}
return 0;
}
static int encode_talker(struct msrp *msrp, struct attr *a, void *m)
@ -146,6 +154,12 @@ static void notify_listener(struct msrp *msrp, uint64_t now, struct attr *attr,
pw_log_info("> notify listener: %s", avb_mrp_notify_name(notify));
debug_msrp_listener(&attr->attr->attr.listener, attr->attr->param);
if (msrp->server->avb_mode == AVB_MODE_MILAN_V12) {
if (notify == AVB_MRP_NOTIFY_NEW || notify == AVB_MRP_NOTIFY_JOIN)
handle_evt_tk_registered(msrp->server->acmp, attr->attr, now);
else if (notify == AVB_MRP_NOTIFY_LEAVE)
handle_evt_tk_unregistered(msrp->server->acmp, attr->attr, now);
}
}
static int process_listener(struct msrp *msrp, uint64_t now, uint8_t attr_type,