mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-29 06:46:38 -04:00
milan-avb: move teh descriptor FAM at the end of the structure to avoid overflow
This commit is contained in:
parent
4d33f57325
commit
0bf4864d84
14 changed files with 126 additions and 204 deletions
|
|
@ -2197,18 +2197,20 @@ int handle_evt_tk_registration_failed_milan_v12(struct acmp *acmp,
|
|||
}
|
||||
|
||||
static bool stream_output_on_this_iface(struct server *server,
|
||||
struct aecp_aem_stream_output_state *stream_out)
|
||||
struct descriptor *stream_out_desc)
|
||||
{
|
||||
struct descriptor *avb_if_desc;
|
||||
struct aecp_aem_avb_interface_state *avb_if_state;
|
||||
uint16_t avb_if_index = ntohs(stream_out->desc.avb_interface_index);
|
||||
const struct avb_aem_desc_stream *stream_body = descriptor_body(stream_out_desc);
|
||||
const struct avb_aem_desc_avb_interface *avb_if_body;
|
||||
uint16_t avb_if_index = ntohs(stream_body->avb_interface_index);
|
||||
|
||||
avb_if_desc = server_find_descriptor(server, AVB_AEM_DESC_AVB_INTERFACE, avb_if_index);
|
||||
if (avb_if_desc == NULL)
|
||||
if (avb_if_desc == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
avb_if_state = avb_if_desc->ptr;
|
||||
return memcmp(avb_if_state->desc.mac_address, server->mac_addr,
|
||||
avb_if_body = descriptor_body(avb_if_desc);
|
||||
return memcmp(avb_if_body->mac_address, server->mac_addr,
|
||||
sizeof(server->mac_addr)) == 0;
|
||||
}
|
||||
|
||||
|
|
@ -2241,7 +2243,7 @@ int handle_probe_tx_command_milan_v12(struct acmp *acmp, uint64_t now,
|
|||
|
||||
stream_out = desc->ptr;
|
||||
|
||||
if (!stream_output_on_this_iface(server, stream_out)) {
|
||||
if (!stream_output_on_this_iface(server, desc)) {
|
||||
status = AVB_ACMP_STATUS_INCOMPATIBLE_REQUEST;
|
||||
goto done;
|
||||
}
|
||||
|
|
@ -2282,7 +2284,6 @@ int handle_disconnect_tx_command_milan_v12(struct acmp *acmp, uint64_t now,
|
|||
struct avb_ethernet_header *h_reply = (struct avb_ethernet_header *)buf;
|
||||
struct avb_packet_acmp *reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||
struct descriptor *desc;
|
||||
struct aecp_aem_stream_output_state *stream_out;
|
||||
int status = AVB_ACMP_STATUS_SUCCESS;
|
||||
|
||||
if (be64toh(p->talker_guid) != server->entity_id)
|
||||
|
|
@ -2298,9 +2299,9 @@ int handle_disconnect_tx_command_milan_v12(struct acmp *acmp, uint64_t now,
|
|||
goto done;
|
||||
}
|
||||
|
||||
stream_out = desc->ptr;
|
||||
if (!stream_output_on_this_iface(server, stream_out))
|
||||
if (!stream_output_on_this_iface(server, desc)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
reply->stream_id = 0;
|
||||
memset(reply->stream_dest_mac, 0, sizeof(reply->stream_dest_mac));
|
||||
|
|
@ -2341,8 +2342,9 @@ int handle_get_tx_state_command_milan_v12(struct acmp *acmp, uint64_t now,
|
|||
|
||||
stream_out = desc->ptr;
|
||||
|
||||
if (!stream_output_on_this_iface(server, stream_out))
|
||||
if (!stream_output_on_this_iface(server, desc)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
reply->stream_id = stream_out->common.tastream_attr.attr.talker.stream_id;
|
||||
memcpy(reply->stream_dest_mac, stream_out->common.stream.addr,
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ static int check_advertise(struct adp *adp, uint64_t now)
|
|||
if (d == NULL)
|
||||
return -1;
|
||||
|
||||
entity = d->ptr;
|
||||
entity = descriptor_body(d);
|
||||
entity_id = be64toh(entity->entity_id);
|
||||
|
||||
if ((e = find_entity_by_id(adp, entity_id)) != NULL) {
|
||||
|
|
@ -290,7 +290,7 @@ static int check_advertise(struct adp *adp, uint64_t now)
|
|||
}
|
||||
|
||||
d = server_find_descriptor(server, AVB_AEM_DESC_AVB_INTERFACE, 0);
|
||||
avb_interface = d ? d->ptr : NULL;
|
||||
avb_interface = d ? descriptor_body(d) : NULL;
|
||||
|
||||
pw_log_info("entity %s advertise",
|
||||
avb_utils_format_id(buf, sizeof(buf), entity_id));
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
|
|||
if (entity_desc == NULL)
|
||||
return reply_status(aecp, AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
|
||||
|
||||
entity = (const struct avb_aem_desc_entity *)entity_desc->ptr;
|
||||
entity = (const struct avb_aem_desc_entity *)descriptor_body(entity_desc);
|
||||
if (config_idx >= ntohs(entity->configurations_count))
|
||||
return reply_status(aecp, AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
|
|||
switch (d->type) {
|
||||
case AVB_AEM_DESC_ENTITY: {
|
||||
const struct avb_aem_desc_entity *e =
|
||||
(const struct avb_aem_desc_entity *)d->ptr;
|
||||
(const struct avb_aem_desc_entity *)descriptor_body(d);
|
||||
struct avb_aem_dynamic_info_entity rec;
|
||||
|
||||
if (size + sizeof(rec) > sizeof(buf)) {
|
||||
|
|
@ -95,7 +95,7 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
|
|||
}
|
||||
case AVB_AEM_DESC_AUDIO_UNIT: {
|
||||
const struct avb_aem_desc_audio_unit *au =
|
||||
(const struct avb_aem_desc_audio_unit *)d->ptr;
|
||||
(const struct avb_aem_desc_audio_unit *)descriptor_body(d);
|
||||
struct avb_aem_dynamic_info_audio_unit rec;
|
||||
|
||||
if (size + sizeof(rec) > sizeof(buf)) {
|
||||
|
|
@ -112,8 +112,8 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
|
|||
break;
|
||||
}
|
||||
case AVB_AEM_DESC_STREAM_INPUT: {
|
||||
const struct aecp_aem_stream_input_state *state =
|
||||
(const struct aecp_aem_stream_input_state *)d->ptr;
|
||||
const struct avb_aem_desc_stream *body =
|
||||
(const struct avb_aem_desc_stream *)descriptor_body(d);
|
||||
struct avb_aem_dynamic_info_stream rec;
|
||||
|
||||
if (size + sizeof(rec) > sizeof(buf)) {
|
||||
|
|
@ -124,10 +124,11 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
|
|||
rec.hdr.descriptor_type = htons(d->type);
|
||||
rec.hdr.descriptor_index = htons(d->index);
|
||||
rec.stream_id = 0;
|
||||
rec.stream_format = state->desc.current_format;
|
||||
if (state->desc.current_format != 0)
|
||||
rec.stream_format = body->current_format;
|
||||
if (body->current_format != 0) {
|
||||
rec.stream_info_flags =
|
||||
htonl(AVB_AEM_STREAM_INFO_FLAG_STREAM_FORMAT_VALID);
|
||||
}
|
||||
memcpy(ptr, &rec, sizeof(rec));
|
||||
ptr += sizeof(rec);
|
||||
psize += sizeof(rec);
|
||||
|
|
@ -135,8 +136,8 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
|
|||
break;
|
||||
}
|
||||
case AVB_AEM_DESC_STREAM_OUTPUT: {
|
||||
const struct aecp_aem_stream_output_state *state =
|
||||
(const struct aecp_aem_stream_output_state *)d->ptr;
|
||||
const struct avb_aem_desc_stream *body =
|
||||
(const struct avb_aem_desc_stream *)descriptor_body(d);
|
||||
struct avb_aem_dynamic_info_stream rec;
|
||||
|
||||
if (size + sizeof(rec) > sizeof(buf)) {
|
||||
|
|
@ -147,10 +148,11 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
|
|||
rec.hdr.descriptor_type = htons(d->type);
|
||||
rec.hdr.descriptor_index = htons(d->index);
|
||||
rec.stream_id = 0;
|
||||
rec.stream_format = state->desc.current_format;
|
||||
if (state->desc.current_format != 0)
|
||||
rec.stream_format = body->current_format;
|
||||
if (body->current_format != 0) {
|
||||
rec.stream_info_flags =
|
||||
htonl(AVB_AEM_STREAM_INFO_FLAG_STREAM_FORMAT_VALID);
|
||||
}
|
||||
memcpy(ptr, &rec, sizeof(rec));
|
||||
ptr += sizeof(rec);
|
||||
psize += sizeof(rec);
|
||||
|
|
@ -159,7 +161,7 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
|
|||
}
|
||||
case AVB_AEM_DESC_CLOCK_DOMAIN: {
|
||||
const struct avb_aem_desc_clock_domain *cd =
|
||||
(const struct avb_aem_desc_clock_domain *)d->ptr;
|
||||
(const struct avb_aem_desc_clock_domain *)descriptor_body(d);
|
||||
struct avb_aem_dynamic_info_clock_domain rec;
|
||||
|
||||
if (size + sizeof(rec) > sizeof(buf)) {
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ int handle_cmd_get_clock_source_milan_v12(struct aecp *aecp, int64_t now,
|
|||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
|
||||
|
||||
dclk_domain = (struct avb_aem_desc_clock_domain*) desc->ptr;
|
||||
dclk_domain = (struct avb_aem_desc_clock_domain*) descriptor_body(desc);
|
||||
|
||||
/** Descriptors always keep the network endianness */
|
||||
sclk_source->clock_source_index = dclk_domain->clock_source_index;
|
||||
|
|
@ -134,7 +134,7 @@ int handle_cmd_set_clock_source_milan_v12(struct aecp *aecp, int64_t now,
|
|||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
|
||||
|
||||
dclk_domain = (struct avb_aem_desc_clock_domain *) desc->ptr;
|
||||
dclk_domain = (struct avb_aem_desc_clock_domain *) descriptor_body(desc);
|
||||
if (clock_src_index >= dclk_domain->clock_sources_count) {
|
||||
return reply_invalid_clock_source(aecp, dclk_domain, m, len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ static int handle_unsol_set_configuration_milan_v12(struct aecp *aecp, struct de
|
|||
int rc;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
entity_desc = (struct avb_aem_desc_entity*) desc->ptr;
|
||||
entity_desc = (struct avb_aem_desc_entity*) descriptor_body(desc);
|
||||
cfg = (struct avb_packet_aecp_aem_setget_configuration *) p->payload;
|
||||
cfg->configuration_index = htons(entity_desc->current_configuration);
|
||||
p->aecp.target_guid = htobe64(aecp->server->entity_id);
|
||||
|
|
@ -97,7 +97,7 @@ int handle_cmd_set_configuration_milan_v12(struct aecp *aecp, int64_t now,
|
|||
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||
|
||||
cfg = (struct avb_packet_aecp_aem_setget_configuration*) p_reply->payload;
|
||||
entity_desc = (struct avb_aem_desc_entity*) desc->ptr;
|
||||
entity_desc = (struct avb_aem_desc_entity*) descriptor_body(desc);
|
||||
cur_cfg_id = ntohs(entity_desc->current_configuration);
|
||||
req_cfg_id = ntohs(cfg->configuration_index);
|
||||
cfg_count = ntohs(entity_desc->configurations_count);
|
||||
|
|
@ -182,7 +182,7 @@ int handle_cmd_get_configuration_common(struct aecp *aecp, int64_t now,
|
|||
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||
|
||||
cfg = (struct avb_packet_aecp_aem_setget_configuration*) p_reply->payload;
|
||||
entity_desc = (struct avb_aem_desc_entity*) desc->ptr;
|
||||
entity_desc = (struct avb_aem_desc_entity*) descriptor_body(desc);
|
||||
|
||||
if (entity_desc->entity_id != p->aecp.target_guid) {
|
||||
pw_log_error("Invalid entity id");
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ static int handle_cmd_get_control_identify(struct aecp *aecp, struct descriptor
|
|||
struct avb_packet_aecp_aem_setget_control *ae_reply;
|
||||
int pkt_size;
|
||||
|
||||
ctrl_desc = desc->ptr;
|
||||
ctrl_desc = descriptor_body(desc);
|
||||
desc_formats = ctrl_desc->value_format;
|
||||
|
||||
if (len < 0 || (size_t)len > sizeof(buf))
|
||||
|
|
@ -145,7 +145,7 @@ static int handle_cmd_set_control_identify(struct aecp *aecp, struct descriptor
|
|||
int rc;
|
||||
|
||||
control = (struct avb_packet_aecp_aem_setget_control*)p->payload;
|
||||
ctrl_desc = desc->ptr;
|
||||
ctrl_desc = descriptor_body(desc);
|
||||
desc_formats = ctrl_desc->value_format;
|
||||
old_value_format = desc_formats;
|
||||
value_req = (uint8_t *)control->payload;
|
||||
|
|
@ -265,7 +265,7 @@ int handle_cmd_set_control_milan_v12(struct aecp *aecp, int64_t now,
|
|||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
|
||||
|
||||
ctrl_desc = desc->ptr;
|
||||
ctrl_desc = descriptor_body(desc);
|
||||
control_type = htobe64(ctrl_desc->control_type);
|
||||
setter_cb = get_ctrl_setter_common(controls_handlers,
|
||||
SPA_N_ELEMENTS(controls_handlers), control_type);
|
||||
|
|
@ -307,7 +307,7 @@ int handle_cmd_get_control_milan_v12(struct aecp *aecp, int64_t now,
|
|||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
|
||||
|
||||
ctrl_desc = desc->ptr;
|
||||
ctrl_desc = descriptor_body(desc);
|
||||
control_type = htobe64(ctrl_desc->control_type);
|
||||
getter_cb = get_ctrl_getter_common(controls_handlers,
|
||||
SPA_N_ELEMENTS(controls_handlers), control_type);
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ int handle_cmd_get_name_common(struct aecp *aecp, int64_t now,
|
|||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
|
||||
|
||||
name_ptr = get_name_ptr(desc_type, desc->ptr, name_index);
|
||||
name_ptr = get_name_ptr(desc_type, descriptor_body(desc), name_index);
|
||||
if (name_ptr == NULL)
|
||||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||
|
|
@ -169,7 +169,7 @@ int handle_cmd_set_name_common(struct aecp *aecp, int64_t now,
|
|||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
|
||||
|
||||
name_ptr = get_name_ptr(desc_type, desc->ptr, name_index);
|
||||
name_ptr = get_name_ptr(desc_type, descriptor_body(desc), name_index);
|
||||
if (name_ptr == NULL)
|
||||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ int handle_cmd_set_sampling_rate_milan_v12(struct aecp *aecp, int64_t now,
|
|||
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
|
||||
|
||||
if (desc_type == AVB_AEM_DESC_AUDIO_UNIT) {
|
||||
struct avb_aem_desc_audio_unit *unit = desc->ptr;
|
||||
struct avb_aem_desc_audio_unit *unit = descriptor_body(desc);
|
||||
/* TODO check if the STREAM_PORT associated with it supportes
|
||||
* the SSRC/ASRC bit.
|
||||
*/
|
||||
|
|
@ -218,7 +218,7 @@ int handle_cmd_get_sampling_rate_common(struct aecp *aecp, int64_t now,
|
|||
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
|
||||
|
||||
if (desc_type == AVB_AEM_DESC_AUDIO_UNIT) {
|
||||
struct avb_aem_desc_audio_unit *unit = desc->ptr;
|
||||
struct avb_aem_desc_audio_unit *unit = descriptor_body(desc);
|
||||
memcpy(&pullfreq, &unit->current_sampling_rate, sizeof(pullfreq));
|
||||
} else {
|
||||
return reply_status(aecp,
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ int handle_cmd_get_stream_format_milan_v12(struct aecp *aecp, int64_t now,
|
|||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||
|
||||
stream_desc = (struct avb_aem_desc_stream *)desc->ptr;
|
||||
stream_desc = (struct avb_aem_desc_stream *)descriptor_body(desc);
|
||||
|
||||
if (len < 0 || (size_t)len > sizeof(buf))
|
||||
return reply_status(aecp,
|
||||
|
|
@ -120,7 +120,7 @@ int handle_cmd_set_stream_format_milan_v12(struct aecp *aecp, int64_t now,
|
|||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||
}
|
||||
|
||||
stream_desc = (struct avb_aem_desc_stream *)desc->ptr;
|
||||
stream_desc = (struct avb_aem_desc_stream *)descriptor_body(desc);
|
||||
for (i = 0; i < ntohs(stream_desc->number_of_formats); i++) {
|
||||
if (stream_desc->stream_formats[i] == new_format) {
|
||||
found = true;
|
||||
|
|
|
|||
|
|
@ -92,9 +92,11 @@ static int build_stream_info_response(struct aecp *aecp, const void *m, int len,
|
|||
}
|
||||
|
||||
static void populate_input_response(struct aecp *aecp,
|
||||
struct aecp_aem_stream_input_state_milan_v12 *si,
|
||||
struct descriptor *desc,
|
||||
struct avb_packet_aecp_aem_setget_stream_info *reply)
|
||||
{
|
||||
struct aecp_aem_stream_input_state_milan_v12 *si = desc->ptr;
|
||||
const struct avb_aem_desc_stream *stream_body = descriptor_body(desc);
|
||||
struct stream_common *sc = &si->stream_in_sta.common;
|
||||
struct avb_msrp_attribute *lattr = &sc->lstream_attr;
|
||||
struct avb_msrp_attribute *taattr = &sc->tastream_attr;
|
||||
|
|
@ -111,7 +113,7 @@ static void populate_input_response(struct aecp *aecp,
|
|||
bool bound, settled, ta_observed, tf_observed, registering;
|
||||
(void)aecp;
|
||||
|
||||
stream_format_be = si->stream_in_sta.desc.current_format;
|
||||
stream_format_be = stream_body->current_format;
|
||||
|
||||
/* Milan Section 5.3.8.2: bound iff the listener has a saved talker stream id. */
|
||||
bound = (lattr->attr.listener.stream_id != 0);
|
||||
|
|
@ -194,7 +196,7 @@ static void populate_input_response(struct aecp *aecp,
|
|||
}
|
||||
|
||||
static int handle_get_stream_input(struct aecp *aecp, const void *m, int len,
|
||||
struct aecp_aem_stream_input_state_milan_v12 *si)
|
||||
struct descriptor *desc)
|
||||
{
|
||||
uint8_t buf[2048];
|
||||
struct avb_ethernet_header *h_reply;
|
||||
|
|
@ -207,15 +209,17 @@ static int handle_get_stream_input(struct aecp *aecp, const void *m, int len,
|
|||
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||
reply = (struct avb_packet_aecp_aem_setget_stream_info *)p_reply->payload;
|
||||
|
||||
populate_input_response(aecp, si, reply);
|
||||
populate_input_response(aecp, desc, reply);
|
||||
|
||||
return reply_success(aecp, buf, AVB_AECP_GET_STREAM_INFO_RESPONSE_LEN);
|
||||
}
|
||||
|
||||
static void populate_output_response(struct aecp *aecp, uint16_t desc_index,
|
||||
struct aecp_aem_stream_output_state *so,
|
||||
struct descriptor *desc,
|
||||
struct avb_packet_aecp_aem_setget_stream_info *reply)
|
||||
{
|
||||
struct aecp_aem_stream_output_state *so = desc->ptr;
|
||||
const struct avb_aem_desc_stream *stream_body = descriptor_body(desc);
|
||||
struct stream_common *sc = &so->common;
|
||||
struct avb_msrp_attribute *taattr = &sc->tastream_attr;
|
||||
const uint8_t zero_mac[6] = {0};
|
||||
|
|
@ -275,21 +279,21 @@ static void populate_output_response(struct aecp *aecp, uint16_t desc_index,
|
|||
build_stream_info_response(aecp, NULL, 0, reply,
|
||||
flags_host, flags_ex_host,
|
||||
0, 0,
|
||||
so->desc.current_format, stream_id_be,
|
||||
stream_body->current_format, stream_id_be,
|
||||
so->presentation_time_offset_ns, dest_mac,
|
||||
0, 0, vlan_id_host);
|
||||
|
||||
pw_log_debug("populate STREAM_OUTPUT stream_format=0x%016" PRIx64
|
||||
" flags=0x%08x flags_ex=0x%08x pres_time_off=%u "
|
||||
"stream_id=0x%016" PRIx64,
|
||||
be64toh(so->desc.current_format),
|
||||
be64toh(stream_body->current_format),
|
||||
flags_host, flags_ex_host,
|
||||
so->presentation_time_offset_ns,
|
||||
be64toh(stream_id_be));
|
||||
}
|
||||
|
||||
static int handle_get_stream_output(struct aecp *aecp, const void *m, int len,
|
||||
uint16_t desc_index, struct aecp_aem_stream_output_state *so)
|
||||
uint16_t desc_index, struct descriptor *desc)
|
||||
{
|
||||
uint8_t buf[2048];
|
||||
struct avb_ethernet_header *h_reply;
|
||||
|
|
@ -302,7 +306,7 @@ static int handle_get_stream_output(struct aecp *aecp, const void *m, int len,
|
|||
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||
reply = (struct avb_packet_aecp_aem_setget_stream_info *)p_reply->payload;
|
||||
|
||||
populate_output_response(aecp, desc_index, so, reply);
|
||||
populate_output_response(aecp, desc_index, desc, reply);
|
||||
|
||||
return reply_success(aecp, buf, AVB_AECP_GET_STREAM_INFO_RESPONSE_LEN);
|
||||
}
|
||||
|
|
@ -324,12 +328,12 @@ int handle_cmd_get_stream_info_milan_v12(struct aecp *aecp, int64_t now,
|
|||
if (desc == NULL)
|
||||
return reply_status(aecp, AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
|
||||
|
||||
if (desc_type == AVB_AEM_DESC_STREAM_INPUT)
|
||||
return handle_get_stream_input(aecp, m, len,
|
||||
(struct aecp_aem_stream_input_state_milan_v12 *)desc->ptr);
|
||||
if (desc_type == AVB_AEM_DESC_STREAM_OUTPUT)
|
||||
return handle_get_stream_output(aecp, m, len, desc_index,
|
||||
(struct aecp_aem_stream_output_state *)desc->ptr);
|
||||
if (desc_type == AVB_AEM_DESC_STREAM_INPUT) {
|
||||
return handle_get_stream_input(aecp, m, len, desc);
|
||||
}
|
||||
if (desc_type == AVB_AEM_DESC_STREAM_OUTPUT) {
|
||||
return handle_get_stream_output(aecp, m, len, desc_index, desc);
|
||||
}
|
||||
|
||||
return reply_status(aecp, AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||
}
|
||||
|
|
@ -438,14 +442,11 @@ void cmd_get_stream_info_emit_unsol_milan_v12(struct server *server,
|
|||
body->descriptor_type = htons(desc_type);
|
||||
body->descriptor_index = htons(desc_index);
|
||||
|
||||
if (desc_type == AVB_AEM_DESC_STREAM_INPUT)
|
||||
populate_input_response(aecp,
|
||||
(struct aecp_aem_stream_input_state_milan_v12 *)desc->ptr,
|
||||
body);
|
||||
else
|
||||
populate_output_response(aecp, desc_index,
|
||||
(struct aecp_aem_stream_output_state *)desc->ptr,
|
||||
body);
|
||||
if (desc_type == AVB_AEM_DESC_STREAM_INPUT) {
|
||||
populate_input_response(aecp, desc, body);
|
||||
} else {
|
||||
populate_output_response(aecp, desc_index, desc, body);
|
||||
}
|
||||
|
||||
(void)reply_unsolicited_notifications(aecp, &b_state, buf,
|
||||
AVB_AECP_GET_STREAM_INFO_RESPONSE_LEN, true);
|
||||
|
|
|
|||
|
|
@ -92,8 +92,6 @@ struct aecp_aem_avb_interface_counters {
|
|||
};
|
||||
|
||||
struct aecp_aem_avb_interface_state {
|
||||
struct avb_aem_desc_avb_interface desc;
|
||||
|
||||
struct avb_msrp_attribute domain_attr;
|
||||
|
||||
struct avb_mvrp_attribute vlan_attr;
|
||||
|
|
@ -113,7 +111,6 @@ struct aecp_aem_avb_interface_state {
|
|||
* \brief the generic entity state common for all flavor of AVB
|
||||
*/
|
||||
struct aecp_aem_entity_state {
|
||||
struct avb_aem_desc_entity desc;
|
||||
struct aecp_aem_lock_state lock_state;
|
||||
};
|
||||
|
||||
|
|
@ -160,12 +157,7 @@ struct stream_common {
|
|||
struct avb_msrp_attribute tfstream_attr;
|
||||
};
|
||||
|
||||
#define AVB_AEM_STREAM_DESC_EXTRA_SIZE 128
|
||||
|
||||
struct aecp_aem_stream_input_state {
|
||||
struct avb_aem_desc_stream desc;
|
||||
uint8_t desc_extra[AVB_AEM_STREAM_DESC_EXTRA_SIZE];
|
||||
|
||||
struct aecp_aem_stream_input_counters counters;
|
||||
struct stream_common common;
|
||||
struct avb_mvrp_attribute mvrp_attr;
|
||||
|
|
@ -210,9 +202,6 @@ struct aecp_aem_stream_output_counters {
|
|||
};
|
||||
|
||||
struct aecp_aem_stream_output_state {
|
||||
struct avb_aem_desc_stream desc;
|
||||
uint8_t desc_extra[AVB_AEM_STREAM_DESC_EXTRA_SIZE];
|
||||
|
||||
struct aecp_aem_stream_output_counters counters;
|
||||
struct stream_common common;
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ static int handle_read_descriptor_common(struct aecp *aecp, int64_t now, const v
|
|||
|
||||
memcpy(buf, m, len);
|
||||
|
||||
memcpy(buf + size, desc->ptr, desc->size);
|
||||
memcpy(buf + size, descriptor_body(desc), desc->size);
|
||||
size += desc->size;
|
||||
psize += desc->size;
|
||||
|
||||
|
|
@ -158,7 +158,7 @@ static int handle_get_avb_info_common(struct aecp *aecp, int64_t now,
|
|||
if (len < 0 || (size_t)len > sizeof(buf))
|
||||
return reply_status(aecp, AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||
|
||||
avb_interface = desc->ptr;
|
||||
avb_interface = descriptor_body(desc);
|
||||
|
||||
memcpy(buf, m, len);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,121 +7,63 @@
|
|||
#include "aecp-aem-state.h"
|
||||
#include "utils.h"
|
||||
|
||||
/**
|
||||
* \brief The goal of this modules is to create a an entity and
|
||||
* attache the necessary status or resources to it so they
|
||||
* do no have to be seperated and referenced somewhere else.
|
||||
*
|
||||
* In a sense, it encapsulates the descriptor, and the states
|
||||
* information that will be altered either by a aecp/acmp commands
|
||||
* or internal state changes reflected into the counters.
|
||||
*/
|
||||
|
||||
/** The callback type used for the different entity descriptor */
|
||||
typedef struct descriptor *(*es_builder_cb_t) (struct server *server, uint16_t type,
|
||||
uint16_t index, size_t size, void *ptr);
|
||||
uint16_t index, size_t size, const void *ptr);
|
||||
|
||||
/** Structure holding all necessary cb
|
||||
* \todo for the future of compatibility between milan's version
|
||||
* and plain AVB, add the right callback, that would reduce
|
||||
* code complexity and increase reusability.
|
||||
* As well as having multiple entity model defined using different
|
||||
* entity on the same machine
|
||||
*/
|
||||
struct es_builder_st {
|
||||
es_builder_cb_t build_descriptor_cb;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* \brief The Entity keeps track of multiple things, the locks the current
|
||||
* configuration use for instance. That tragets the Milan V1.2 mode only
|
||||
*/
|
||||
static struct descriptor *es_builder_desc_entity_milan_v12(struct server *server,
|
||||
uint16_t type, uint16_t index, size_t size, void *ptr)
|
||||
uint16_t type, uint16_t index, size_t size, const void *ptr)
|
||||
{
|
||||
struct aecp_aem_entity_milan_state entity_state = {0};
|
||||
struct descriptor *desc;
|
||||
struct aecp_aem_entity_state *state =
|
||||
(struct aecp_aem_entity_state *) &entity_state;
|
||||
|
||||
memcpy(&state->desc, ptr, size);
|
||||
|
||||
desc = server_add_descriptor(server, type, index, sizeof(entity_state),
|
||||
&entity_state);
|
||||
|
||||
if (!desc) {
|
||||
pw_log_error("Error during allocation\n");
|
||||
spa_assert(0);
|
||||
}
|
||||
|
||||
return desc;
|
||||
return server_add_descriptor(server, type, index,
|
||||
sizeof(struct aecp_aem_entity_milan_state), size, ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief A generic function to avoid code duplicate for the streams */
|
||||
static struct descriptor *es_buidler_desc_stream_general_prepare(struct server *server,
|
||||
uint16_t type, uint16_t index, size_t size, void *ptr)
|
||||
uint16_t type, uint16_t index, size_t size, const void *ptr)
|
||||
{
|
||||
struct descriptor *desc;
|
||||
struct stream *stream;
|
||||
enum spa_direction direction;
|
||||
|
||||
switch (type) {
|
||||
case AVB_AEM_DESC_STREAM_INPUT:
|
||||
struct aecp_aem_stream_input_state *pstream_input;
|
||||
/* Milan v1.2 ACMP code casts the descriptor pointer to
|
||||
* struct aecp_aem_stream_input_state_milan_v12 * and reads
|
||||
* acmp_sta, which sits *after* the bare stream input state.
|
||||
* Allocate the wrapper size so that read/write of acmp_sta is
|
||||
* within the descriptor buffer. The bare struct is the prefix
|
||||
* of the wrapper, so existing direct-access paths remain valid. */
|
||||
struct aecp_aem_stream_input_state_milan_v12 stream_input_w = { 0 };
|
||||
struct aecp_aem_stream_input_state *stream_input = &stream_input_w.stream_in_sta;
|
||||
if (type == AVB_AEM_DESC_STREAM_INPUT) {
|
||||
struct aecp_aem_stream_input_state_milan_v12 *w;
|
||||
|
||||
memcpy(&stream_input->desc, ptr, size);
|
||||
desc = server_add_descriptor(server, type, index,
|
||||
sizeof(*w), size, ptr);
|
||||
if (!desc) {
|
||||
pw_log_error("Allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
w = desc->ptr;
|
||||
/* Milan v1.2 Section 5.3.8.7: started/stopped state defaults to started. */
|
||||
stream_input->started = true;
|
||||
desc = server_add_descriptor(server, type, index,
|
||||
sizeof(stream_input_w), &stream_input_w);
|
||||
if (!desc) {
|
||||
pw_log_error("Allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pstream_input = desc->ptr;
|
||||
stream = &pstream_input->common.stream;
|
||||
w->stream_in_sta.started = true;
|
||||
stream = &w->stream_in_sta.common.stream;
|
||||
direction = SPA_DIRECTION_INPUT;
|
||||
} else if (type == AVB_AEM_DESC_STREAM_OUTPUT) {
|
||||
struct aecp_aem_stream_output_state_milan_v12 *w;
|
||||
|
||||
break;
|
||||
case AVB_AEM_DESC_STREAM_OUTPUT:
|
||||
struct aecp_aem_stream_output_state *pstream_output;
|
||||
struct aecp_aem_stream_output_state_milan_v12 stream_output_w = { 0 };
|
||||
struct aecp_aem_stream_output_state *stream_output = &stream_output_w.stream_out_sta;
|
||||
|
||||
memcpy(&stream_output->desc, ptr, size);
|
||||
/* Milan v1.2 Section 5.3.7.6: default presentation time offset is 2 ms. */
|
||||
stream_output->presentation_time_offset_ns = 2000000;
|
||||
desc = server_add_descriptor(server, type, index,
|
||||
sizeof(stream_output_w), &stream_output_w);
|
||||
sizeof(*w), size, ptr);
|
||||
if (!desc) {
|
||||
pw_log_error("Allocation failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pstream_output = desc->ptr;
|
||||
stream = &pstream_output->common.stream;
|
||||
w = desc->ptr;
|
||||
/* Milan v1.2 Section 5.3.7.6: default presentation time offset is 2 ms. */
|
||||
w->stream_out_sta.presentation_time_offset_ns = 2000000;
|
||||
stream = &w->stream_out_sta.common.stream;
|
||||
direction = SPA_DIRECTION_OUTPUT;
|
||||
|
||||
break;
|
||||
default:
|
||||
} else {
|
||||
pw_log_error("Only STREAM_INPUT and STREAM_OUTPUT\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* In this place the stream register interanlly SRP / MVRP state machines
|
||||
*/
|
||||
if (!server_create_stream(server, stream, direction, index)) {
|
||||
pw_log_error("Could not create/initialize a stream");
|
||||
return NULL;
|
||||
|
|
@ -131,16 +73,13 @@ static struct descriptor *es_buidler_desc_stream_general_prepare(struct server *
|
|||
}
|
||||
|
||||
static struct descriptor *es_buidler_desc_avb_interface(struct server *server,
|
||||
uint16_t type, uint16_t index, size_t size, void *ptr)
|
||||
uint16_t type, uint16_t index, size_t size, const void *ptr)
|
||||
{
|
||||
struct aecp_aem_avb_interface_state if_state = {0};
|
||||
struct aecp_aem_avb_interface_state *if_ptr;
|
||||
struct descriptor *desc;
|
||||
|
||||
memcpy(&if_state.desc, ptr, size);
|
||||
desc = server_add_descriptor(server, type, index, sizeof(if_state),
|
||||
&if_state);
|
||||
|
||||
desc = server_add_descriptor(server, type, index,
|
||||
sizeof(*if_ptr), size, ptr);
|
||||
if (!desc) {
|
||||
pw_log_error("Error durring allocation\n");
|
||||
spa_assert(0);
|
||||
|
|
@ -171,12 +110,10 @@ static struct descriptor *es_buidler_desc_avb_interface(struct server *server,
|
|||
return desc;
|
||||
}
|
||||
|
||||
// Assign a ID to an specific builder
|
||||
#define HELPER_ES_BUIDLER(type, callback) \
|
||||
[type] = { .build_descriptor_cb = callback }
|
||||
[type] = { .build_descriptor_cb = callback }
|
||||
|
||||
/** All callback that needs a status information for the AVB/Milan V1.2 */
|
||||
static const struct es_builder_st es_builder_milan_v12[] =
|
||||
static const struct es_builder_st es_builder_milan_v12[AVB_AEM_DESC_LAST_RESERVED_17221 + 1] =
|
||||
{
|
||||
HELPER_ES_BUIDLER(AVB_AEM_DESC_ENTITY, es_builder_desc_entity_milan_v12),
|
||||
HELPER_ES_BUIDLER(AVB_AEM_DESC_STREAM_OUTPUT, es_buidler_desc_stream_general_prepare),
|
||||
|
|
@ -184,42 +121,31 @@ static const struct es_builder_st es_builder_milan_v12[] =
|
|||
HELPER_ES_BUIDLER(AVB_AEM_DESC_AVB_INTERFACE, es_buidler_desc_avb_interface),
|
||||
};
|
||||
|
||||
/** All callback that needs a status information for Legacy AVB*/
|
||||
static const struct es_builder_st es_builder_legacy_avb[] =
|
||||
static const struct es_builder_st es_builder_legacy_avb[AVB_AEM_DESC_LAST_RESERVED_17221 + 1] =
|
||||
{
|
||||
HELPER_ES_BUIDLER(AVB_AEM_DESC_STREAM_OUTPUT, es_buidler_desc_stream_general_prepare),
|
||||
HELPER_ES_BUIDLER(AVB_AEM_DESC_STREAM_INPUT, es_buidler_desc_stream_general_prepare),
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief keep the list of the supported avb flavors here
|
||||
*/
|
||||
static const struct {
|
||||
const struct es_builder_st *es_builder;
|
||||
/** Number of elements in the es_builder */
|
||||
size_t count;
|
||||
} es_builders[] = {
|
||||
[AVB_MODE_LEGACY] = {
|
||||
.es_builder = es_builder_legacy_avb,
|
||||
.count = ARRAY_SIZE(es_builder_legacy_avb),
|
||||
.count = SPA_N_ELEMENTS(es_builder_legacy_avb),
|
||||
},
|
||||
|
||||
[AVB_MODE_MILAN_V12] = {
|
||||
.es_builder = es_builder_milan_v12,
|
||||
.count = ARRAY_SIZE(es_builder_milan_v12),
|
||||
.count = SPA_N_ELEMENTS(es_builder_milan_v12),
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief, should be called when creating an a descriptor, it will attach
|
||||
* the right state variable that are necessary for counters, stream info
|
||||
* and so on...
|
||||
*/
|
||||
void es_builder_add_descriptor(struct server *server, uint16_t type,
|
||||
uint16_t index, size_t size, void *ptr_aem)
|
||||
{
|
||||
const struct es_builder_st *es_builder;
|
||||
struct descriptor *desc;
|
||||
enum avb_mode avb_mode;
|
||||
bool std_processing = false;
|
||||
|
||||
|
|
@ -234,34 +160,26 @@ void es_builder_add_descriptor(struct server *server, uint16_t type,
|
|||
spa_assert(0);
|
||||
}
|
||||
|
||||
|
||||
es_builder = es_builders[avb_mode].es_builder;
|
||||
if (type > es_builders[avb_mode].count) {
|
||||
if (type >= es_builders[avb_mode].count) {
|
||||
std_processing = true;
|
||||
} else if (!es_builder[type].build_descriptor_cb) {
|
||||
std_processing = true;
|
||||
} else {
|
||||
if (!es_builder[type].build_descriptor_cb) {
|
||||
std_processing = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (std_processing) {
|
||||
if (!server_add_descriptor(server, type, index, size, ptr_aem)) {
|
||||
if (!server_add_descriptor(server, type, index, 0, size, ptr_aem)) {
|
||||
pw_log_error("Could not allocate descriptor %u at "
|
||||
"index %u the avb aem type\n", type, index);
|
||||
|
||||
spa_assert(0);
|
||||
}
|
||||
} else {
|
||||
desc = es_builder[type].build_descriptor_cb(server, type,
|
||||
index, size, ptr_aem);
|
||||
if (!desc) {
|
||||
if (!es_builder[type].build_descriptor_cb(server, type,
|
||||
index, size, ptr_aem)) {
|
||||
pw_log_error("Could not allocate specific descriptr "
|
||||
"%u at index %u the avb aem type\n",
|
||||
type, index);
|
||||
|
||||
spa_assert(0);
|
||||
}
|
||||
|
||||
desc->size = size;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,9 +67,15 @@ struct descriptor {
|
|||
uint16_t type;
|
||||
uint16_t index;
|
||||
uint32_t size;
|
||||
uint32_t state_size;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
static inline void *descriptor_body(const struct descriptor *d)
|
||||
{
|
||||
return SPA_PTROFF(d->ptr, d->state_size, void);
|
||||
}
|
||||
|
||||
|
||||
enum avb_mode {
|
||||
/** The legacy AVB Mode */
|
||||
|
|
@ -142,20 +148,24 @@ static inline struct descriptor *server_find_descriptor(struct server *server,
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
static inline void *server_add_descriptor(struct server *server,
|
||||
uint16_t type, uint16_t index, size_t size, void *ptr)
|
||||
static inline struct descriptor *server_add_descriptor(struct server *server,
|
||||
uint16_t type, uint16_t index,
|
||||
size_t state_size, size_t desc_size, const void *desc_ptr)
|
||||
{
|
||||
struct descriptor *d;
|
||||
|
||||
if ((d = calloc(1, sizeof(struct descriptor) + size)) == NULL)
|
||||
if ((d = calloc(1, sizeof(*d) + state_size + desc_size)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
d->type = type;
|
||||
d->index = index;
|
||||
d->size = size;
|
||||
d->ptr = SPA_PTROFF(d, sizeof(struct descriptor), void);
|
||||
if (ptr)
|
||||
memcpy(d->ptr, ptr, size);
|
||||
d->size = desc_size;
|
||||
d->state_size = state_size;
|
||||
d->ptr = SPA_PTROFF(d, sizeof(*d), void);
|
||||
if (desc_ptr) {
|
||||
memcpy(SPA_PTROFF(d->ptr, state_size, void), desc_ptr, desc_size);
|
||||
}
|
||||
spa_list_append(&server->descriptors, &d->link);
|
||||
return d;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue