Skip to content

Commit

Permalink
Keep A2DP configuration check in codec files
Browse files Browse the repository at this point in the history
In order to simplify error handling, the check function stops on first
error. Now, the D-Bus API for codec selection returns human readable
error message describing the cause of error.
  • Loading branch information
arkq committed Jan 8, 2024
1 parent 5f2bdc0 commit a8b10fe
Show file tree
Hide file tree
Showing 13 changed files with 406 additions and 242 deletions.
43 changes: 39 additions & 4 deletions src/a2dp-aac.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,43 @@ static int a2dp_aac_configuration_select(
return 0;
}

static int a2dp_aac_configuration_check(
const struct a2dp_codec *codec,
const void *configuration) {

const a2dp_aac_t *conf = configuration;
a2dp_aac_t conf_v = *conf;

/* validate configuration against BlueALSA capabilities */
if (a2dp_filter_capabilities(codec, &codec->capabilities,
&conf_v, sizeof(conf_v)) != 0)
return A2DP_CHECK_ERR_SIZE;

switch (conf_v.object_type) {
case AAC_OBJECT_TYPE_MPEG2_AAC_LC:
case AAC_OBJECT_TYPE_MPEG4_AAC_LC:
case AAC_OBJECT_TYPE_MPEG4_AAC_LTP:
case AAC_OBJECT_TYPE_MPEG4_AAC_SCA:
break;
default:
debug("AAC: Invalid object type: %#x", conf->object_type);
return A2DP_CHECK_ERR_OBJECT_TYPE;
}

const uint16_t conf_frequency = AAC_GET_FREQUENCY(conf_v);
if (a2dp_sampling_lookup(a2dp_aac_samplings, conf_frequency) == NULL) {
debug("AAC: Invalid sampling frequency: %#x", AAC_GET_FREQUENCY(*conf));
return A2DP_CHECK_ERR_SAMPLING;
}

if (a2dp_channel_mode_lookup(a2dp_aac_channels, conf_v.channels) == NULL) {
debug("AAC: Invalid channel mode: %#x", conf->channels);
return A2DP_CHECK_ERR_CHANNEL_MODE;
}

return A2DP_CHECK_OK;
}

static int a2dp_aac_transport_init(struct ba_transport *t) {

const struct a2dp_channel_mode *chm;
Expand Down Expand Up @@ -630,11 +667,10 @@ struct a2dp_codec a2dp_aac_source = {
AAC_INIT_BITRATE(320000)
},
.capabilities_size = sizeof(a2dp_aac_t),
.channels[0] = a2dp_aac_channels,
.samplings[0] = a2dp_aac_samplings,
.init = a2dp_aac_source_init,
.capabilities_filter = a2dp_aac_capabilities_filter,
.configuration_select = a2dp_aac_configuration_select,
.configuration_check = a2dp_aac_configuration_check,
.transport_init = a2dp_aac_transport_init,
.transport_start = a2dp_aac_source_transport_start,
.enabled = true,
Expand Down Expand Up @@ -691,11 +727,10 @@ struct a2dp_codec a2dp_aac_sink = {
AAC_INIT_BITRATE(320000)
},
.capabilities_size = sizeof(a2dp_aac_t),
.channels[0] = a2dp_aac_channels,
.samplings[0] = a2dp_aac_samplings,
.init = a2dp_aac_sink_init,
.capabilities_filter = a2dp_aac_capabilities_filter,
.configuration_select = a2dp_aac_configuration_select,
.configuration_check = a2dp_aac_configuration_check,
.transport_init = a2dp_aac_transport_init,
.transport_start = a2dp_aac_sink_transport_start,
.enabled = true,
Expand Down
31 changes: 27 additions & 4 deletions src/a2dp-aptx-hd.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,31 @@ static int a2dp_aptx_hd_configuration_select(
return 0;
}

static int a2dp_aptx_hd_configuration_check(
const struct a2dp_codec *codec,
const void *configuration) {

const a2dp_aptx_hd_t *conf = configuration;
a2dp_aptx_hd_t conf_v = *conf;

/* validate configuration against BlueALSA capabilities */
if (a2dp_filter_capabilities(codec, &codec->capabilities,
&conf_v, sizeof(conf_v)) != 0)
return A2DP_CHECK_ERR_SIZE;

if (a2dp_sampling_lookup(a2dp_aptx_hd_samplings, conf_v.aptx.frequency) == NULL) {
debug("apt-X HD: Invalid sampling frequency: %#x", conf->aptx.frequency);
return A2DP_CHECK_ERR_SAMPLING;
}

if (a2dp_channel_mode_lookup(a2dp_aptx_hd_channels, conf_v.aptx.channel_mode) == NULL) {
debug("apt-X HD: Invalid channel mode: %#x", conf->aptx.channel_mode);
return A2DP_CHECK_ERR_CHANNEL_MODE;
}

return A2DP_CHECK_OK;
}

static int a2dp_aptx_hd_transport_init(struct ba_transport *t) {

const struct a2dp_channel_mode *chm;
Expand Down Expand Up @@ -361,10 +386,9 @@ struct a2dp_codec a2dp_aptx_hd_source = {
APTX_SAMPLING_FREQ_48000,
},
.capabilities_size = sizeof(a2dp_aptx_hd_t),
.channels[0] = a2dp_aptx_hd_channels,
.samplings[0] = a2dp_aptx_hd_samplings,
.init = a2dp_aptx_hd_source_init,
.configuration_select = a2dp_aptx_hd_configuration_select,
.configuration_check = a2dp_aptx_hd_configuration_check,
.transport_init = a2dp_aptx_hd_transport_init,
.transport_start = a2dp_aptx_hd_source_transport_start,
};
Expand Down Expand Up @@ -392,9 +416,8 @@ struct a2dp_codec a2dp_aptx_hd_sink = {
APTX_SAMPLING_FREQ_48000,
},
.capabilities_size = sizeof(a2dp_aptx_hd_t),
.channels[0] = a2dp_aptx_hd_channels,
.samplings[0] = a2dp_aptx_hd_samplings,
.configuration_select = a2dp_aptx_hd_configuration_select,
.configuration_check = a2dp_aptx_hd_configuration_check,
.transport_init = a2dp_aptx_hd_transport_init,
.transport_start = a2dp_aptx_hd_sink_transport_start,
};
Expand Down
31 changes: 27 additions & 4 deletions src/a2dp-aptx.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,31 @@ static int a2dp_aptx_configuration_select(
return 0;
}

static int a2dp_aptx_configuration_check(
const struct a2dp_codec *codec,
const void *configuration) {

const a2dp_aptx_t *conf = configuration;
a2dp_aptx_t conf_v = *conf;

/* validate configuration against BlueALSA capabilities */
if (a2dp_filter_capabilities(codec, &codec->capabilities,
&conf_v, sizeof(conf_v)) != 0)
return A2DP_CHECK_ERR_SIZE;

if (a2dp_sampling_lookup(a2dp_aptx_samplings, conf_v.frequency) == NULL) {
debug("apt-X: Invalid sampling frequency: %#x", conf->frequency);
return A2DP_CHECK_ERR_SAMPLING;
}

if (a2dp_channel_mode_lookup(a2dp_aptx_channels, conf_v.channel_mode) == NULL) {
debug("apt-X: Invalid channel mode: %#x", conf->channel_mode);
return A2DP_CHECK_ERR_CHANNEL_MODE;
}

return A2DP_CHECK_OK;
}

static int a2dp_aptx_transport_init(struct ba_transport *t) {

const struct a2dp_channel_mode *chm;
Expand Down Expand Up @@ -324,10 +349,9 @@ struct a2dp_codec a2dp_aptx_source = {
APTX_SAMPLING_FREQ_48000,
},
.capabilities_size = sizeof(a2dp_aptx_t),
.channels[0] = a2dp_aptx_channels,
.samplings[0] = a2dp_aptx_samplings,
.init = a2dp_aptx_source_init,
.configuration_select = a2dp_aptx_configuration_select,
.configuration_check = a2dp_aptx_configuration_check,
.transport_init = a2dp_aptx_transport_init,
.transport_start = a2dp_aptx_source_transport_start,
};
Expand Down Expand Up @@ -355,9 +379,8 @@ struct a2dp_codec a2dp_aptx_sink = {
APTX_SAMPLING_FREQ_48000,
},
.capabilities_size = sizeof(a2dp_aptx_t),
.channels[0] = a2dp_aptx_channels,
.samplings[0] = a2dp_aptx_samplings,
.configuration_select = a2dp_aptx_configuration_select,
.configuration_check = a2dp_aptx_configuration_check,
.transport_init = a2dp_aptx_transport_init,
.transport_start = a2dp_aptx_sink_transport_start,
};
Expand Down
40 changes: 36 additions & 4 deletions src/a2dp-faststream.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,40 @@ static int a2dp_faststream_configuration_select(
return 0;
}

static int a2dp_faststream_configuration_check(
const struct a2dp_codec *codec,
const void *configuration) {

const a2dp_faststream_t *conf = configuration;
a2dp_faststream_t conf_v = *conf;

/* validate configuration against BlueALSA capabilities */
if (a2dp_filter_capabilities(codec, &codec->capabilities,
&conf_v, sizeof(conf_v)) != 0)
return A2DP_CHECK_ERR_SIZE;

switch (conf_v.direction) {
case FASTSTREAM_DIRECTION_MUSIC:
case FASTSTREAM_DIRECTION_VOICE:
break;
default:
debug("FastStream: Invalid direction: %#x", conf->direction);
return A2DP_CHECK_ERR_DIRECTIONS;
}

if (a2dp_sampling_lookup(a2dp_faststream_samplings_voice, conf_v.frequency_voice) == NULL) {
debug("FastStream: Invalid voice sampling frequency: %#x", conf->frequency_voice);
return A2DP_CHECK_ERR_SAMPLING_VOICE;
}

if (a2dp_sampling_lookup(a2dp_faststream_samplings_music, conf_v.frequency_music) == NULL) {
debug("FastStream: Invalid music sampling frequency: %#x", conf->frequency_music);
return A2DP_CHECK_ERR_SAMPLING_MUSIC;
}

return A2DP_CHECK_OK;
}

static int a2dp_faststream_transport_init(struct ba_transport *t) {

if (t->a2dp.configuration.faststream.direction & FASTSTREAM_DIRECTION_MUSIC) {
Expand Down Expand Up @@ -356,10 +390,9 @@ struct a2dp_codec a2dp_faststream_source = {
FASTSTREAM_SAMPLING_FREQ_VOICE_16000,
},
.capabilities_size = sizeof(a2dp_faststream_t),
.samplings[0] = a2dp_faststream_samplings_music,
.samplings[1] = a2dp_faststream_samplings_voice,
.init = a2dp_faststream_source_init,
.configuration_select = a2dp_faststream_configuration_select,
.configuration_check = a2dp_faststream_configuration_check,
.transport_init = a2dp_faststream_transport_init,
.transport_start = a2dp_faststream_source_transport_start,
};
Expand Down Expand Up @@ -392,9 +425,8 @@ struct a2dp_codec a2dp_faststream_sink = {
FASTSTREAM_SAMPLING_FREQ_VOICE_16000,
},
.capabilities_size = sizeof(a2dp_faststream_t),
.samplings[0] = a2dp_faststream_samplings_music,
.samplings[1] = a2dp_faststream_samplings_voice,
.configuration_select = a2dp_faststream_configuration_select,
.configuration_check = a2dp_faststream_configuration_check,
.transport_init = a2dp_faststream_transport_init,
.transport_start = a2dp_faststream_sink_transport_start,
};
42 changes: 38 additions & 4 deletions src/a2dp-lc3plus.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,42 @@ static int a2dp_lc3plus_configuration_select(
return 0;
}

static int a2dp_lc3plus_configuration_check(
const struct a2dp_codec *codec,
const void *configuration) {

const a2dp_lc3plus_t *conf = configuration;
a2dp_lc3plus_t conf_v = *conf;

/* validate configuration against BlueALSA capabilities */
if (a2dp_filter_capabilities(codec, &codec->capabilities,
&conf_v, sizeof(conf_v)) != 0)
return A2DP_CHECK_ERR_SIZE;

switch (conf_v.frame_duration) {
case LC3PLUS_FRAME_DURATION_025:
case LC3PLUS_FRAME_DURATION_050:
case LC3PLUS_FRAME_DURATION_100:
break;
default:
debug("LC3plus: Invalid frame duration: %#x", conf->frame_duration);
return A2DP_CHECK_ERR_FRAME_DURATION;
}

if (a2dp_channel_mode_lookup(a2dp_lc3plus_channels, conf_v.channels) == NULL) {
debug("LC3plus: Invalid channel mode: %#x", conf->channels);
return A2DP_CHECK_ERR_CHANNEL_MODE;
}

uint16_t conf_frequency = LC3PLUS_GET_FREQUENCY(conf_v);
if (a2dp_sampling_lookup(a2dp_lc3plus_samplings, conf_frequency) == NULL) {
debug("LC3plus: Invalid sampling frequency: %#x", LC3PLUS_GET_FREQUENCY(*conf));
return A2DP_CHECK_ERR_SAMPLING;
}

return A2DP_CHECK_OK;
}

static int a2dp_lc3plus_transport_init(struct ba_transport *t) {

const struct a2dp_channel_mode *chm;
Expand Down Expand Up @@ -639,10 +675,9 @@ struct a2dp_codec a2dp_lc3plus_source = {
LC3PLUS_SAMPLING_FREQ_96000)
},
.capabilities_size = sizeof(a2dp_lc3plus_t),
.channels[0] = a2dp_lc3plus_channels,
.samplings[0] = a2dp_lc3plus_samplings,
.init = a2dp_lc3plus_source_init,
.configuration_select = a2dp_lc3plus_configuration_select,
.configuration_check = a2dp_lc3plus_configuration_check,
.transport_init = a2dp_lc3plus_transport_init,
.transport_start = a2dp_lc3plus_source_transport_start,
};
Expand All @@ -669,9 +704,8 @@ struct a2dp_codec a2dp_lc3plus_sink = {
LC3PLUS_SAMPLING_FREQ_96000)
},
.capabilities_size = sizeof(a2dp_lc3plus_t),
.channels[0] = a2dp_lc3plus_channels,
.samplings[0] = a2dp_lc3plus_samplings,
.configuration_select = a2dp_lc3plus_configuration_select,
.configuration_check = a2dp_lc3plus_configuration_check,
.transport_init = a2dp_lc3plus_transport_init,
.transport_start = a2dp_lc3plus_sink_transport_start,
};
31 changes: 27 additions & 4 deletions src/a2dp-ldac.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,31 @@ static int a2dp_ldac_configuration_select(
return 0;
}

static int a2dp_ldac_configuration_check(
const struct a2dp_codec *codec,
const void *configuration) {

const a2dp_ldac_t *conf = configuration;
a2dp_ldac_t conf_v = *conf;

/* validate configuration against BlueALSA capabilities */
if (a2dp_filter_capabilities(codec, &codec->capabilities,
&conf_v, sizeof(conf_v)) != 0)
return A2DP_CHECK_ERR_SIZE;

if (a2dp_sampling_lookup(a2dp_ldac_samplings, conf_v.frequency) == NULL) {
debug("LDAC: Invalid sampling frequency: %#x", conf->frequency);
return A2DP_CHECK_ERR_SAMPLING;
}

if (a2dp_channel_mode_lookup(a2dp_ldac_channels, conf_v.channel_mode) == NULL) {
debug("LDAC: Invalid channel mode: %#x", conf->channel_mode);
return A2DP_CHECK_ERR_CHANNEL_MODE;
}

return A2DP_CHECK_OK;
}

static int a2dp_ldac_transport_init(struct ba_transport *t) {

const struct a2dp_channel_mode *chm;
Expand Down Expand Up @@ -420,10 +445,9 @@ struct a2dp_codec a2dp_ldac_source = {
LDAC_SAMPLING_FREQ_96000,
},
.capabilities_size = sizeof(a2dp_ldac_t),
.channels[0] = a2dp_ldac_channels,
.samplings[0] = a2dp_ldac_samplings,
.init = a2dp_ldac_source_init,
.configuration_select = a2dp_ldac_configuration_select,
.configuration_check = a2dp_ldac_configuration_check,
.transport_init = a2dp_ldac_transport_init,
.transport_start = a2dp_ldac_source_transport_start,
};
Expand Down Expand Up @@ -453,9 +477,8 @@ struct a2dp_codec a2dp_ldac_sink = {
LDAC_SAMPLING_FREQ_96000,
},
.capabilities_size = sizeof(a2dp_ldac_t),
.channels[0] = a2dp_ldac_channels,
.samplings[0] = a2dp_ldac_samplings,
.configuration_select = a2dp_ldac_configuration_select,
.configuration_check = a2dp_ldac_configuration_check,
.transport_init = a2dp_ldac_transport_init,
.transport_start = a2dp_ldac_sink_transport_start,
};
Expand Down
Loading

0 comments on commit a8b10fe

Please sign in to comment.