diff --git a/src/modules/module-avb/mrp.c b/src/modules/module-avb/mrp.c index 3cc3825fb..2879fbb2a 100644 --- a/src/modules/module-avb/mrp.c +++ b/src/modules/module-avb/mrp.c @@ -55,6 +55,10 @@ struct mrp { uint64_t periodic_timeout; struct fsm_leave_all_timer lva_timer; uint64_t join_timeout; + + /* IEEE 802.1Q-2014 Section 10.7.6.3 lva bit: true while the next outgoing + * vector header must carry lva=1 (local LeaveAll being transmitted). */ + bool lva_tx_pending; }; static void mrp_destroy(void *data) @@ -107,6 +111,7 @@ static void mrp_periodic(void *data, uint64_t now) /* 802.1Q-2014 Table 10-5 */ mrp->lva_timer.state = FSM_LVA_ACTIVE; if (mrp->lva_timer.leave_all_timeout > 0) { + mrp->lva_tx_pending = true; global_event(mrp, now, AVB_MRP_EVENT_RX_LVA); leave_all = true; } @@ -118,6 +123,7 @@ static void mrp_periodic(void *data, uint64_t now) global_event(mrp, now, event); } mrp->join_timeout = now + MRP_JOINTIMER_MS * SPA_NSEC_PER_MSEC; + mrp->lva_tx_pending = false; } spa_list_for_each(a, &mrp->attributes, link) { @@ -739,6 +745,11 @@ void avb_mrp_attribute_leave(struct avb_mrp_attribute *attr, uint64_t now) a->joined = false; } +bool avb_mrp_lva_tx_pending(const struct avb_mrp *m) +{ + return ((const struct mrp *)m)->lva_tx_pending; +} + void avb_mrp_destroy(struct avb_mrp *mrp) { mrp_destroy(mrp); diff --git a/src/modules/module-avb/mrp.h b/src/modules/module-avb/mrp.h index 0b63a2817..2719ad6b6 100644 --- a/src/modules/module-avb/mrp.h +++ b/src/modules/module-avb/mrp.h @@ -137,6 +137,9 @@ void avb_mrp_attribute_add_listener(struct avb_mrp_attribute *attr, struct spa_h uint8_t avb_mrp_attribute_get_applicant_state(const struct avb_mrp_attribute *attr); uint8_t avb_mrp_attribute_get_registrar_state(const struct avb_mrp_attribute *attr); +/* IEEE 802.1Q-2014 Section 10.7.6.3: lva bit must be 1 while transmitting our LVA. */ +bool avb_mrp_lva_tx_pending(const struct avb_mrp *m); + struct avb_mrp_parse_info { #define AVB_VERSION_MRP_PARSE_INFO 0 uint32_t version; diff --git a/src/modules/module-avb/msrp.c b/src/modules/module-avb/msrp.c index 04d561bed..5260db095 100644 --- a/src/modules/module-avb/msrp.c +++ b/src/modules/module-avb/msrp.c @@ -124,7 +124,7 @@ static int encode_talker(struct msrp *msrp, struct attr *a, void *m) msg->attribute_list_length = htons(attr_list_length); v = (struct avb_packet_mrp_vector *)msg->attribute_list; - v->lva = 0; + v->lva = avb_mrp_lva_tx_pending(msrp->server->mrp) ? 1 : 0; AVB_MRP_VECTOR_SET_NUM_VALUES(v, 1); t = (struct avb_packet_msrp_talker *)v->first_value; @@ -244,7 +244,7 @@ static int encode_listener(struct msrp *msrp, struct attr *a, void *m) msg->attribute_list_length = htons(attr_list_length); v = (struct avb_packet_mrp_vector *)msg->attribute_list; - v->lva = 0; + v->lva = avb_mrp_lva_tx_pending(msrp->server->mrp) ? 1 : 0; AVB_MRP_VECTOR_SET_NUM_VALUES(v, 1); l = (struct avb_packet_msrp_listener *)v->first_value; @@ -325,7 +325,7 @@ static int encode_domain(struct msrp *msrp, struct attr *a, void *m) msg->attribute_list_length = htons(attr_list_length); v = (struct avb_packet_mrp_vector *)msg->attribute_list; - v->lva = 0; + v->lva = avb_mrp_lva_tx_pending(msrp->server->mrp) ? 1 : 0; AVB_MRP_VECTOR_SET_NUM_VALUES(v, 1); d = (struct avb_packet_msrp_domain *)v->first_value; diff --git a/src/modules/module-avb/mvrp.c b/src/modules/module-avb/mvrp.c index 955c9699b..fb910d83b 100644 --- a/src/modules/module-avb/mvrp.c +++ b/src/modules/module-avb/mvrp.c @@ -77,7 +77,7 @@ static int encode_vid(struct mvrp *mvrp, struct attr *a, void *m) msg->attribute_length = sizeof(*d); v = (struct avb_packet_mrp_vector *)msg->attribute_list; - v->lva = 0; + v->lva = avb_mrp_lva_tx_pending(mvrp->server->mrp) ? 1 : 0; AVB_MRP_VECTOR_SET_NUM_VALUES(v, 1); d = (struct avb_packet_mvrp_vid *)v->first_value;