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); 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, static int acmp_generic_srp_evt_lt_handler_milan_v12(struct acmp *acmp,
uint64_t entity_id, enum fsm_acmp_evt_milan_v12 event) 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; 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; struct descriptor *desc;
enum fsm_acmp_state_milan_v12 fsm_state;
uint16_t desc_type = AVB_AEM_DESC_STREAM_INPUT; 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++) { for (uint16_t desc_index = 0; desc_index < UINT16_MAX; desc_index++) {
desc = server_find_descriptor(acmp->server, desc_type, 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; break;
si_state = (struct aecp_aem_stream_input_state_milan_v12 *)desc->ptr; 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[si_state->acmp_status.fsm_acmp_state][event];
cmd = &cmd_listeners_states[fsm_state][event]; if (!cmd->state_handler) {
pw_log_warn("No handler: STATE:%s EVT:%s - ignoring",
if (!cmd) { fsm_acmp_state_milan_v12_str[si_state->acmp_status.fsm_acmp_state],
pw_log_warn("Invalid transition STATE:%s EVT:%s - ignoring",
fsm_acmp_state_milan_v12_str[fsm_state],
fsm_acmp_evt_milan_v12_str[event]); fsm_acmp_evt_milan_v12_str[event]);
continue; continue;
} }
rc = cmd->state_handler(acmp, si_state, NULL, 0, 0); rc = cmd->state_handler(acmp, si_state, NULL, 0, now);
if (rc){ if (rc)
pw_log_error("cmd failed for stream %p", si_state); 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) int acmp_init_talker_stream_milan_v12(struct acmp *acmp, void *acmp_status)
{ {
return 0; 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); 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, return acmp_generic_adp_evt_lt_handler_milan_v12(acmp, talker_guid,
FSM_ACMP_EVT_MILAN_V12_TK_DISCOVERED); 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, return acmp_generic_adp_evt_lt_handler_milan_v12(acmp, talker_guid,
FSM_ACMP_EVT_MILAN_V12_TK_DEPARTED); 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, return acmp_generic_srp_evt_lt_handler_milan_v12(acmp, msrp_attr,
FSM_ACMP_EVT_MILAN_V12_TK_REGISTERED); 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, return acmp_generic_srp_evt_lt_handler_milan_v12(acmp, msrp_attr,
FSM_ACMP_EVT_MILAN_V12_TK_UNREGISTERED); FSM_ACMP_EVT_MILAN_V12_TK_UNREGISTERED, now);
} }
int handle_probe_tx_command_milan_v12(struct acmp *acmp, uint64_t now, int handle_probe_tx_command_milan_v12(struct acmp *acmp, uint64_t now,

View file

@ -6,6 +6,7 @@
#include <stdint.h> #include <stdint.h>
#include "acmp-common.h" #include "acmp-common.h"
#include "../msrp.h"
/** Milan v1.2 ACMP */ /** Milan v1.2 ACMP */
enum fsm_acmp_state_milan_v12 { 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, int handle_get_rx_state_command_milan_v12(struct acmp *acmp, uint64_t now,
const void *m, int len); const void *m, int len);
int handle_evt_tk_discovered_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); 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_registered_milan_v12(struct acmp *acmp,
int handle_evt_tk_unregistered_milan_v12(struct acmp *acmp, uint64_t talker_guid); 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_no_resp_milan_v12(struct acmp *acmp, uint64_t now);
int acmp_tmr_retry_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; struct acmp *acmp = (struct acmp*)avb_acmp;
switch (acmp->server->avb_mode) { switch (acmp->server->avb_mode) {
case AVB_MODE_MILAN_V12: 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; break;
case AVB_MODE_LEGACY: case AVB_MODE_LEGACY:
pw_log_warn("not implemented for legacy avb"); 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; 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; struct acmp *acmp = (struct acmp*)avb_acmp;
switch (acmp->server->avb_mode) { switch (acmp->server->avb_mode) {
case AVB_MODE_MILAN_V12: 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; break;
case AVB_MODE_LEGACY: case AVB_MODE_LEGACY:
pw_log_warn("not implemented for legacy avb"); 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; 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; struct acmp *acmp = (struct acmp*)avb_acmp;
switch (acmp->server->avb_mode) { switch (acmp->server->avb_mode) {
case AVB_MODE_MILAN_V12: 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; break;
case AVB_MODE_LEGACY: case AVB_MODE_LEGACY:
pw_log_warn("not implemented for legacy avb"); 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; 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; struct acmp *acmp = (struct acmp*)avb_acmp;
switch (acmp->server->avb_mode) { switch (acmp->server->avb_mode) {
case AVB_MODE_MILAN_V12: 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; break;
case AVB_MODE_LEGACY: case AVB_MODE_LEGACY:
pw_log_warn("not implemented for legacy avb"); 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); struct avb_acmp *avb_acmp_register(struct server *server);
void avb_acmp_unregister(struct avb_acmp *acmp); 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_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); 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_registered(struct avb_acmp *avb_acmp,
int handle_evt_tk_unregistered(struct avb_acmp *avb_acmp, uint64_t entity); 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 */ #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) { if (server->avb_mode == AVB_MODE_MILAN_V12) {
//Milan V1.2 Section 5.6.4.5.1 //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"); pw_log_info("handling available event");
return -1; 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); SPA_PTROFF(h_saved, sizeof(*h_saved), void);
if (p_saved->available_index != p->available_index) { 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"); pw_log_info("handling departing event");
return -1; return -1;
} }
@ -162,7 +162,7 @@ static int adp_message(void *data, uint64_t now, const void *message, int len)
return 0; 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"); pw_log_warn("handling available event");
return -1; return -1;
} }
@ -178,7 +178,7 @@ static int adp_message(void *data, uint64_t now, const void *message, int len)
if (e != NULL) { if (e != NULL) {
if (server->avb_mode == AVB_MODE_MILAN_V12) { if (server->avb_mode == AVB_MODE_MILAN_V12) {
// Milan v1.2 Section 5.6.4.5.3 // 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", 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", pw_log_info("entity %s timeout",
avb_utils_format_id(buf, sizeof(buf), e->entity_id)); 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) if (e->advertise)
send_departing(adp, now, e); send_departing(adp, now, e);

View file

@ -12,6 +12,7 @@
#include "utils.h" #include "utils.h"
#include "msrp.h" #include "msrp.h"
#include "acmp.h"
static const uint8_t msrp_mac[6] = AVB_MSRP_MAC; 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)); pw_log_info("> notify talker advertise: %s", avb_mrp_notify_name(notify));
if (msrp->server->avb_mode == AVB_MODE_MILAN_V12) { 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; const struct avb_packet_msrp_talker *t = m;
struct attr *a; 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 && if (a->attr->type == attr_type &&
a->attr->attr.talker.stream_id == t->stream_id) { a->attr->attr.talker.stream_id == t->stream_id) {
a->attr->attr.talker = *t; a->attr->attr.talker = *t;
avb_mrp_attribute_rx_event(a->attr->mrp, now, event); avb_mrp_attribute_rx_event(a->attr->mrp, now, event);
} }
}
return 0; return 0;
} }
static int encode_talker(struct msrp *msrp, struct attr *a, void *m) 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)); pw_log_info("> notify listener: %s", avb_mrp_notify_name(notify));
debug_msrp_listener(&attr->attr->attr.listener, attr->attr->param); 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, static int process_listener(struct msrp *msrp, uint64_t now, uint8_t attr_type,