From e34ff8c0880d27c8bd95775a8c964408206f18d5 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 8 Feb 2008 17:43:48 +0000 Subject: Improve handling of different transports. --- audio/unix.c | 118 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 42 deletions(-) diff --git a/audio/unix.c b/audio/unix.c index 3b2d821c..d81291c7 100644 --- a/audio/unix.c +++ b/audio/unix.c @@ -798,49 +798,25 @@ failed: unix_ipc_error(client, BT_GETCAPABILITIES_RSP, EIO); } -static void handle_setconfiguration_req(struct unix_client *client, - struct bt_setconfiguration_req *req) +static int handle_sco_transport(struct unix_client *client, + struct bt_setconfiguration_req *req) { - struct avdtp_service_capability *media_transport, *media_codec; - struct sbc_codec_cap sbc_cap; - struct mpeg_codec_cap mpeg_cap; - struct device *dev; - bdaddr_t bdaddr; - int err = 0; - - if (!req->access_mode) { - err = EINVAL; - goto failed; - } - - str2ba(req->device, &bdaddr); - - if (client->interface) { - g_free(client->interface); - client->interface = NULL; - } - - if (req->transport == BT_CAPABILITIES_TRANSPORT_SCO) - client->interface = g_strdup(AUDIO_HEADSET_INTERFACE); - else if (req->transport == BT_CAPABILITIES_TRANSPORT_A2DP) - client->interface = g_strdup(AUDIO_SINK_INTERFACE); + client->interface = g_strdup(AUDIO_HEADSET_INTERFACE); - if (!manager_find_device(&bdaddr, NULL, FALSE)) { - if (!bacmp(&bdaddr, BDADDR_ANY)) - goto failed; - if (!manager_create_device(&bdaddr, create_cb, client)) - goto failed; - return; - } + info("config sco - device = %s access_mode = %u", req->device, + req->access_mode); - dev = manager_find_device(&bdaddr, client->interface, TRUE); - if (!dev) - dev = manager_find_device(&bdaddr, client->interface, FALSE); + return 0; +} - if (!dev) - goto failed; +static int handle_a2dp_transport(struct unix_client *client, + struct bt_setconfiguration_req *req) +{ + struct avdtp_service_capability *media_transport, *media_codec; + struct sbc_codec_cap sbc_cap; + struct mpeg_codec_cap mpeg_cap; - client->access_mode = req->access_mode; + client->interface = g_strdup(AUDIO_SINK_INTERFACE); if (client->caps) { g_slist_foreach(client->caps, (GFunc) g_free, NULL); @@ -852,7 +828,11 @@ static void handle_setconfiguration_req(struct unix_client *client, client->caps = g_slist_append(client->caps, media_transport); + info("config a2dp - device = %s access_mode = %u", req->device, + req->access_mode); + if (req->mpeg_capabilities.frequency) { + memset(&mpeg_cap, 0, sizeof(mpeg_cap)); mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; @@ -867,12 +847,12 @@ static void handle_setconfiguration_req(struct unix_client *client, media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap, sizeof(mpeg_cap)); - info("config mpeg - frequency = %u channel_mode = %u " + info("codec mpeg12 - frequency = %u channel_mode = %u " "layer = %u crc = %u mpf = %u bitrate = %u", mpeg_cap.frequency, mpeg_cap.channel_mode, mpeg_cap.layer, mpeg_cap.crc, mpeg_cap.mpf, mpeg_cap.bitrate); - } else { + } else if (req->sbc_capabilities.frequency) { memset(&sbc_cap, 0, sizeof(sbc_cap)); sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; @@ -888,16 +868,70 @@ static void handle_setconfiguration_req(struct unix_client *client, media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap, sizeof(sbc_cap)); - info("config sbc - frequency = %u channel_mode = %u " + info("codec sbc - frequency = %u channel_mode = %u " "allocation = %u subbands = %u blocks = %u " "bitpool = %u", sbc_cap.frequency, sbc_cap.channel_mode, sbc_cap.allocation_method, sbc_cap.subbands, sbc_cap.block_length, sbc_cap.max_bitpool); - } + } else + return -EINVAL; client->caps = g_slist_append(client->caps, media_codec); + return 0; +} + +static void handle_setconfiguration_req(struct unix_client *client, + struct bt_setconfiguration_req *req) +{ + struct device *dev; + bdaddr_t bdaddr; + int err = 0; + + if (!req->access_mode) { + err = EINVAL; + goto failed; + } + + str2ba(req->device, &bdaddr); + + if (client->interface) { + g_free(client->interface); + client->interface = NULL; + } + + if (req->transport == BT_CAPABILITIES_TRANSPORT_SCO) { + err = handle_sco_transport(client, req); + if (err < 0) { + err = -err; + goto failed; + } + } else if (req->transport == BT_CAPABILITIES_TRANSPORT_A2DP) { + err = handle_a2dp_transport(client, req); + if (err < 0) { + err = -err; + goto failed; + } + } + + if (!manager_find_device(&bdaddr, NULL, FALSE)) { + if (!bacmp(&bdaddr, BDADDR_ANY)) + goto failed; + if (!manager_create_device(&bdaddr, create_cb, client)) + goto failed; + return; + } + + dev = manager_find_device(&bdaddr, client->interface, TRUE); + if (!dev) + dev = manager_find_device(&bdaddr, client->interface, FALSE); + + if (!dev) + goto failed; + + client->access_mode = req->access_mode; + start_config(dev, client); return; -- cgit