diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index c0a53ea..661843a 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
static GSList *setups = NULL;
static unsigned int cb_id = 0;
+struct a2dp_error {
+ const char *error_name;
+ uint8_t error_code;
+};
+
+#define A2DP_ERROR_PREFIX ERROR_INTERFACE ".A2DP."
+
+static struct a2dp_error config_errors[] = {
+ {"InvalidCodecType", A2DP_INVALID_CODEC_TYPE},
+ {"NotSupportedCodecType", A2DP_NOT_SUPPORTED_CODEC_TYPE},
+ {"InvalidSamplingFrequency", A2DP_INVALID_SAMPLING_FREQUENCY},
+ {"NotSupportedSamplingFrequency",
+ A2DP_NOT_SUPPORTED_SAMPLING_FREQUENCY},
+ {"InvalidChannelMode", A2DP_INVALID_CHANNEL_MODE},
+ {"NotSupportedChannelMode", A2DP_NOT_SUPPORTED_CHANNEL_MODE},
+ {"InvalidSubbands", A2DP_INVALID_SUBBANDS},
+ {"NotSupportedSubbands", A2DP_NOT_SUPPORTED_SUBBANDS},
+ {"InvalidAllocationMethod", A2DP_INVALID_ALLOCATION_METHOD},
+ {"NotSupportedAllocationMethod", A2DP_NOT_SUPPORTED_ALLOCATION_METHOD},
+ {"InvalidMinimumBitpoolValue",
+ A2DP_INVALID_MINIMUM_BITPOOL_VALUE},
+ {"NotSupportedMinimumBitpoolValue",
+ A2DP_NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE},
+ {"InvalidMaximumBitpoolValue", A2DP_INVALID_MAXIMUM_BITPOOL_VALUE},
+ {"NotSupportedMaximumBitpoolValue",
+ A2DP_NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE},
+ {"InvalidInvalidLayer", A2DP_INVALID_INVALID_LAYER},
+ {"NotSupportedLayer", A2DP_NOT_SUPPORTED_LAYER},
+ {"NotSupporterdCRC", A2DP_NOT_SUPPORTERD_CRC},
+ {"NotSupporterdMPF", A2DP_NOT_SUPPORTERD_MPF},
+ {"NotSupporterdVBR", A2DP_NOT_SUPPORTERD_VBR},
+ {"InvalidBitRate", A2DP_INVALID_BIT_RATE},
+ {"NotSupportedBitRate", A2DP_NOT_SUPPORTED_BIT_RATE},
+ {"InvalidObjectType", A2DP_INVALID_OBJECT_TYPE},
+ {"NotSupportedObjectType", A2DP_NOT_SUPPORTED_OBJECT_TYPE},
+ {"InvalidChannels", A2DP_INVALID_CHANNELS},
+ {"NotSupportedChannels", A2DP_NOT_SUPPORTED_CHANNELS},
+ {"InvalidVersion", A2DP_INVALID_VERSION},
+ {"NotSupportedVersion", A2DP_NOT_SUPPORTED_VERSION},
+ {"NotSupportedMaximumSUL", A2DP_NOT_SUPPORTED_MAXIMUM_SUL},
+ {"InvalidBlockLength", A2DP_INVALID_BLOCK_LENGTH},
+ {"InvalidCPType", A2DP_INVALID_CP_TYPE},
+ {"InvalidCPFormat", A2DP_INVALID_CP_FORMAT},
+ {"InvalidCodecParameter", A2DP_INVALID_CODEC_PARAMETER},
+ {"NotSupportedCodecParameter", A2DP_NOT_SUPPORTED_CODEC_PARAMETER},
+ {"InvalidDRC", A2DP_INVALID_DRC},
+ {"NotSupportedDRC", A2DP_NOT_SUPPORTED_DRC}
+};
+
+uint8_t a2dp_parse_config_error(const char *error_name)
+{
+ size_t prefix_length;
+ size_t i;
+
+ prefix_length = strlen(A2DP_ERROR_PREFIX);
+ if (strncmp(A2DP_ERROR_PREFIX, error_name, prefix_length))
+ return AVDTP_UNSUPPORTED_CONFIGURATION;
+
+ error_name += prefix_length;
+ for (i = 0; i < ARRAY_SIZE(config_errors); i++) {
+ if (strcmp(config_errors[i].error_name, error_name) == 0)
+ return config_errors[i].error_code;
+ }
+
+ return AVDTP_UNSUPPORTED_CONFIGURATION;
+}
+
static struct a2dp_setup *setup_ref(struct a2dp_setup *setup)
{
setup->ref++;
return FALSE;
}
-static void endpoint_setconf_cb(struct a2dp_setup *setup, gboolean ret)
+static void endpoint_setconf_cb(struct a2dp_setup *setup, uint8_t error_code)
{
- if (ret == FALSE)
- setup_error_init(setup, AVDTP_MEDIA_CODEC,
- AVDTP_UNSUPPORTED_CONFIGURATION);
+ if (error_code != 0)
+ setup_error_init(setup, AVDTP_MEDIA_CODEC, error_code);
auto_config(setup);
setup_unref(setup);
return TRUE;
}
-static void endpoint_open_cb(struct a2dp_setup *setup, gboolean ret)
+static void endpoint_open_cb(struct a2dp_setup *setup, uint8_t error_code)
{
int err = error_to_errno(setup->err);
- if (ret == FALSE) {
+ if (error_code != 0) {
setup->stream = NULL;
finalize_setup_errno(setup, -EPERM, finalize_config, NULL);
goto done;
diff --git a/profiles/audio/a2dp.h b/profiles/audio/a2dp.h
index c698bc9..bcdb4d4 100644
--- a/profiles/audio/a2dp.h
+++ b/profiles/audio/a2dp.h
typedef void (*a2dp_endpoint_select_t) (struct a2dp_setup *setup, void *ret,
int size);
-typedef void (*a2dp_endpoint_config_t) (struct a2dp_setup *setup, gboolean ret);
+typedef void (*a2dp_endpoint_config_t) (struct a2dp_setup *setup,
+ uint8_t error_code);
struct a2dp_endpoint {
const char *(*get_name) (struct a2dp_sep *sep, void *user_data);
unsigned int a2dp_config(struct avdtp *session, struct a2dp_sep *sep,
a2dp_config_cb_t cb, GSList *caps,
void *user_data);
+uint8_t a2dp_parse_config_error(const char *error_name);
+
unsigned int a2dp_resume(struct avdtp *session, struct a2dp_sep *sep,
a2dp_stream_cb_t cb, void *user_data);
unsigned int a2dp_suspend(struct avdtp *session, struct a2dp_sep *sep,
struct btd_device *a2dp_setup_get_device(struct a2dp_setup *setup);
const char *a2dp_setup_remote_path(struct a2dp_setup *setup);
struct avdtp *a2dp_avdtp_get(struct btd_device *device);
+
+enum a2dp_error_codes {
+ A2DP_INVALID_CODEC_TYPE = 0xc1,
+ A2DP_NOT_SUPPORTED_CODEC_TYPE = 0xc2,
+ A2DP_INVALID_SAMPLING_FREQUENCY = 0xc3,
+ A2DP_NOT_SUPPORTED_SAMPLING_FREQUENCY = 0xc4,
+ A2DP_INVALID_CHANNEL_MODE = 0xc5,
+ A2DP_NOT_SUPPORTED_CHANNEL_MODE = 0xc6,
+ A2DP_INVALID_SUBBANDS = 0xc7,
+ A2DP_NOT_SUPPORTED_SUBBANDS = 0xc8,
+ A2DP_INVALID_ALLOCATION_METHOD = 0xc9,
+ A2DP_NOT_SUPPORTED_ALLOCATION_METHOD = 0xca,
+ A2DP_INVALID_MINIMUM_BITPOOL_VALUE = 0xcb,
+ A2DP_NOT_SUPPORTED_MINIMUM_BITPOOL_VALUE = 0xcc,
+ A2DP_INVALID_MAXIMUM_BITPOOL_VALUE = 0xcd,
+ A2DP_NOT_SUPPORTED_MAXIMUM_BITPOOL_VALUE = 0xce,
+ A2DP_INVALID_INVALID_LAYER = 0xcf,
+ A2DP_NOT_SUPPORTED_LAYER = 0xd0,
+ A2DP_NOT_SUPPORTERD_CRC = 0xd1,
+ A2DP_NOT_SUPPORTERD_MPF = 0xd2,
+ A2DP_NOT_SUPPORTERD_VBR = 0xd3,
+ A2DP_INVALID_BIT_RATE = 0xd4,
+ A2DP_NOT_SUPPORTED_BIT_RATE = 0xd5,
+ A2DP_INVALID_OBJECT_TYPE = 0xd6,
+ A2DP_NOT_SUPPORTED_OBJECT_TYPE = 0xd7,
+ A2DP_INVALID_CHANNELS = 0xd8,
+ A2DP_NOT_SUPPORTED_CHANNELS = 0xd9,
+ A2DP_INVALID_VERSION = 0xda,
+ A2DP_NOT_SUPPORTED_VERSION = 0xdb,
+ A2DP_NOT_SUPPORTED_MAXIMUM_SUL = 0xdc,
+ A2DP_INVALID_BLOCK_LENGTH = 0xdd,
+ A2DP_INVALID_CP_TYPE = 0xe0,
+ A2DP_INVALID_CP_FORMAT = 0xe1,
+ A2DP_INVALID_CODEC_PARAMETER = 0xe2,
+ A2DP_NOT_SUPPORTED_CODEC_PARAMETER = 0xe3,
+ A2DP_INVALID_DRC = 0xe4,
+ A2DP_NOT_SUPPORTED_DRC = 0xe5,
+};
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 3064825..ed4e22b 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
struct conf_rej rej;
if (err != NULL) {
- rej.error = AVDTP_UNSUPPORTED_CONFIGURATION;
- rej.category = err->err.error_code;
+ rej.error = err->err.error_code;
+ rej.category = AVDTP_UNSUPPORTED_CONFIGURATION;
avdtp_send(session, session->in_cmd.transaction,
AVDTP_MSG_TYPE_REJECT, AVDTP_SET_CONFIGURATION,
&rej, sizeof(rej));
diff --git a/profiles/audio/media.c b/profiles/audio/media.c
index 9b3042c..332f643 100644
--- a/profiles/audio/media.c
+++ b/profiles/audio/media.c
DBusMessage *reply;
DBusMessageIter args, props;
DBusError err;
- gboolean value;
+ uint8_t error_code;
void *ret = NULL;
int size = -1;
if (dbus_message_is_method_call(request->msg,
MEDIA_ENDPOINT_INTERFACE,
- "SetConfiguration"))
+ "SetConfiguration")) {
endpoint_remove_transport(endpoint, request->transport);
+ error_code = a2dp_parse_config_error(err.name);
+ ret = &error_code;
+ size = 1;
+ }
dbus_error_free(&err);
goto done;
}
size = 1;
- value = TRUE;
- ret = &value;
+ error_code = 0;
+ ret = &error_code;
done:
dbus_message_unref(reply);
void *user_data)
{
struct a2dp_config_data *data = user_data;
- gboolean *ret_value = ret;
+ uint8_t *ret_value = ret;
- data->cb(data->setup, ret_value ? *ret_value : FALSE);
+ data->cb(data->setup, ret_value ? *ret_value : 1);
}
static int set_config(struct a2dp_sep *sep, uint8_t *configuration,
void *user_data)
{
struct pac_config_data *data = user_data;
- gboolean *ret_value = ret;
+ uint8_t *error_code = ret;
struct media_transport *transport;
/* If transport was cleared, configuration was cancelled */
if (!transport)
return;
- data->cb(data->stream, ret_value ? 0 : -EINVAL);
+ data->cb(data->stream, error_code == 0 ? 0 : -EINVAL);
}
static struct media_transport *pac_ucast_config(struct bt_bap_stream *stream,