milan-avb: msrp: state logging, Milan listener_observed and log refinements

This commit is contained in:
hackerman-kl 2026-04-25 08:16:27 +02:00 committed by Wim Taymans
parent 2cc60d6167
commit b126943143
2 changed files with 118 additions and 8 deletions

View file

@ -14,6 +14,8 @@
#include "msrp.h"
#include "acmp.h"
#include "stream.h"
#include "aecp-aem.h"
#include "aecp-aem-state.h"
static const uint8_t msrp_mac[6] = AVB_MSRP_MAC;
@ -58,8 +60,11 @@ static void debug_msrp_talker(const struct avb_packet_msrp_talker *t)
static void notify_talker(struct msrp *msrp, uint64_t now, struct attr *attr, uint8_t notify)
{
struct stream_common *sc;
char label[64];
pw_log_info("> notify talker advertise: %s", avb_mrp_notify_name(notify));
pw_log_debug("> notify talker advertise: %s", avb_mrp_notify_name(notify));
snprintf(label, sizeof(label), "MSRP talker-adv %s", avb_mrp_notify_name(notify));
avb_log_state(msrp->server, label);
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)
@ -79,7 +84,10 @@ static void notify_talker(struct msrp *msrp, uint64_t now, struct attr *attr, ui
static void notify_talker_failed(struct msrp *msrp, uint64_t now, struct attr *attr, uint8_t notify)
{
pw_log_info("> notify talker failed: %s", avb_mrp_notify_name(notify));
char label[64];
pw_log_debug("> notify talker failed: %s", avb_mrp_notify_name(notify));
snprintf(label, sizeof(label), "MSRP talker-fail %s", avb_mrp_notify_name(notify));
avb_log_state(msrp->server, label);
if (msrp->server->avb_mode == AVB_MODE_MILAN_V12) {
if (notify == AVB_MRP_NOTIFY_NEW || notify == AVB_MRP_NOTIFY_JOIN)
@ -166,14 +174,44 @@ static void debug_msrp_listener(const struct avb_packet_msrp_listener *l, uint8_
static void notify_listener(struct msrp *msrp, uint64_t now, struct attr *attr, uint8_t notify)
{
pw_log_info("> notify listener: %s", avb_mrp_notify_name(notify));
debug_msrp_listener(&attr->attr->attr.listener, attr->attr->param);
struct stream_common *sc;
struct stream *s;
char label[64];
if (msrp->server->avb_mode == AVB_MODE_MILAN_V12) {
pw_log_debug("> notify listener: %s", avb_mrp_notify_name(notify));
debug_msrp_listener(&attr->attr->attr.listener, attr->attr->param);
snprintf(label, sizeof(label), "MSRP listener %s", avb_mrp_notify_name(notify));
avb_log_state(msrp->server, label);
if (msrp->server->avb_mode != AVB_MODE_MILAN_V12)
return;
/* Milan Section 4.3.3.1 second condition: a Listener attribute
* matching the Stream Output's stream_id is registered. */
sc = SPA_CONTAINER_OF(attr->attr, struct stream_common, lstream_attr);
s = &sc->stream;
if (s->direction == SPA_DIRECTION_INPUT) {
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);
} else {
struct aecp_aem_stream_output_state *stream_out =
SPA_CONTAINER_OF(sc, struct aecp_aem_stream_output_state, common);
bool prev = stream_out->listener_observed;
if (notify == AVB_MRP_NOTIFY_NEW || notify == AVB_MRP_NOTIFY_JOIN)
stream_out->listener_observed = true;
else if (notify == AVB_MRP_NOTIFY_LEAVE)
stream_out->listener_observed = false;
/* listener_observed flips flags_ex.REGISTERING in the
* GET_STREAM_INFO answer (Milan Table 5.12). Hint AECP to
* re-emit so controllers see the update. */
if (prev != stream_out->listener_observed)
avb_aecp_aem_mark_stream_info_dirty(msrp->server,
AVB_AEM_DESC_STREAM_OUTPUT, s->index);
}
}
@ -234,7 +272,7 @@ static void debug_msrp_domain(const struct avb_packet_msrp_domain *d)
static void notify_domain(struct msrp *msrp, uint64_t now, struct attr *attr, uint8_t notify)
{
pw_log_info("> notify domain: %s", avb_mrp_notify_name(notify));
pw_log_debug("> notify domain: %s", avb_mrp_notify_name(notify));
debug_msrp_domain(&attr->attr->attr.domain);
}
@ -455,13 +493,16 @@ static void msrp_event(void *data, uint64_t now, uint8_t event)
if (dispatch[a->attr->type].encode == NULL)
continue;
pw_log_debug("send %s %s", dispatch[a->attr->type].name,
pw_log_info("MSRP encode %s %s",
dispatch[a->attr->type].name,
avb_mrp_send_name(a->attr->mrp->pending_send));
len = dispatch[a->attr->type].encode(msrp, a, msg);
if (len < 0)
break;
a->attr->mrp->pending_send = 0;
count++;
msg = SPA_PTROFF(msg, len, void);
total += len;
@ -469,9 +510,11 @@ static void msrp_event(void *data, uint64_t now, uint8_t event)
f = (struct avb_packet_mrp_footer *)msg;
f->end_mark = 0;
if (count > 0)
if (count > 0) {
pw_log_info("MSRP send: %d attribute(s), %zu bytes", count, total);
avb_server_send_packet(msrp->server, msrp_mac, AVB_MSRP_ETH,
buffer, total);
}
}
static const struct avb_mrp_events mrp_events = {
@ -480,6 +523,71 @@ static const struct avb_mrp_events mrp_events = {
};
static const char *msrp_attr_type_name(uint8_t type)
{
switch (type) {
case AVB_MSRP_ATTRIBUTE_TYPE_TALKER_ADVERTISE: return "talker-adv";
case AVB_MSRP_ATTRIBUTE_TYPE_TALKER_FAILED: return "talker-fail";
case AVB_MSRP_ATTRIBUTE_TYPE_LISTENER: return "listener";
case AVB_MSRP_ATTRIBUTE_TYPE_DOMAIN: return "domain";
default: return "?";
}
}
void avb_msrp_log_state(struct server *server, const char *label)
{
struct msrp *msrp = (struct msrp *)server->msrp;
struct attr *a;
char buf[64];
int n = 0;
if (msrp == NULL)
return;
spa_list_for_each(a, &msrp->attributes, link)
n++;
pw_log_debug("[%s] MSRP: %d attribute%s", label, n, n == 1 ? "" : "s");
spa_list_for_each(a, &msrp->attributes, link) {
uint8_t app_st = avb_mrp_attribute_get_applicant_state(a->attr->mrp);
uint8_t reg_st = avb_mrp_attribute_get_registrar_state(a->attr->mrp);
switch (a->attr->type) {
case AVB_MSRP_ATTRIBUTE_TYPE_TALKER_ADVERTISE:
case AVB_MSRP_ATTRIBUTE_TYPE_TALKER_FAILED:
pw_log_debug("[%s] %-11s stream_id=%s app=%s reg=%s",
label, msrp_attr_type_name(a->attr->type),
avb_utils_format_id(buf, sizeof(buf),
be64toh(a->attr->attr.talker.stream_id)),
avb_applicant_state_name(app_st),
avb_registrar_state_name(reg_st));
break;
case AVB_MSRP_ATTRIBUTE_TYPE_LISTENER:
pw_log_debug("[%s] %-11s stream_id=%s param=%u app=%s reg=%s",
label, msrp_attr_type_name(a->attr->type),
avb_utils_format_id(buf, sizeof(buf),
be64toh(a->attr->attr.listener.stream_id)),
a->attr->param,
avb_applicant_state_name(app_st),
avb_registrar_state_name(reg_st));
break;
case AVB_MSRP_ATTRIBUTE_TYPE_DOMAIN:
pw_log_debug("[%s] %-11s class_id=%u prio=%u vid=%u app=%s reg=%s",
label, msrp_attr_type_name(a->attr->type),
a->attr->attr.domain.sr_class_id,
a->attr->attr.domain.sr_class_priority,
ntohs(a->attr->attr.domain.sr_class_vid),
avb_applicant_state_name(app_st),
avb_registrar_state_name(reg_st));
break;
default:
pw_log_debug("[%s] type=%u app=%s reg=%s", label, a->attr->type,
avb_applicant_state_name(app_st),
avb_registrar_state_name(reg_st));
break;
}
}
}
struct avb_msrp *avb_msrp_register(struct server *server)
{
struct msrp *msrp;

View file

@ -113,4 +113,6 @@ int avb_msrp_attribute_new(struct avb_msrp *m, struct avb_msrp_attribute *attr,
struct avb_msrp *avb_msrp_register(struct server *server);
void avb_msrp_log_state(struct server *server, const char *label);
#endif /* AVB_MSRP_H */