summaryrefslogtreecommitdiff
path: root/cras/src/server/cras_hfp_alsa_iodev.c
diff options
context:
space:
mode:
Diffstat (limited to 'cras/src/server/cras_hfp_alsa_iodev.c')
-rw-r--r--cras/src/server/cras_hfp_alsa_iodev.c336
1 files changed, 0 insertions, 336 deletions
diff --git a/cras/src/server/cras_hfp_alsa_iodev.c b/cras/src/server/cras_hfp_alsa_iodev.c
deleted file mode 100644
index c1b60b30..00000000
--- a/cras/src/server/cras_hfp_alsa_iodev.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* Copyright 2019 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <syslog.h>
-
-#include "cras_audio_area.h"
-#include "cras_hfp_slc.h"
-#include "cras_iodev.h"
-#include "cras_system_state.h"
-#include "cras_util.h"
-#include "utlist.h"
-#include "cras_bt_device.h"
-
-#include "cras_hfp_alsa_iodev.h"
-
-/* Object to represent a special HFP iodev which would be managed by bt_io but
- * playback/capture via an inner ALSA iodev.
- * Members:
- * base - The base class cras_iodev.
- * device - The corresponding remote BT device.
- * slc - The service level connection.
- * aio - The effective iodev for playback/capture.
- */
-struct hfp_alsa_io {
- struct cras_iodev base;
- struct cras_bt_device *device;
- struct hfp_slc_handle *slc;
- struct cras_iodev *aio;
-};
-
-static int hfp_alsa_get_valid_frames(struct cras_iodev *iodev,
- struct timespec *hw_tstamp)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- return aio->get_valid_frames(aio, hw_tstamp);
-}
-
-static int hfp_alsa_open_dev(struct cras_iodev *iodev)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- return aio->open_dev(aio);
-}
-
-static int hfp_alsa_update_supported_formats(struct cras_iodev *iodev)
-{
- /* 16 bit, mono, 8kHz (narrow band speech); */
- free(iodev->supported_rates);
- iodev->supported_rates = malloc(2 * sizeof(*iodev->supported_rates));
- if (!iodev->supported_rates)
- return -ENOMEM;
- iodev->supported_rates[0] = 8000;
- iodev->supported_rates[1] = 0;
-
- free(iodev->supported_channel_counts);
- iodev->supported_channel_counts =
- malloc(2 * sizeof(*iodev->supported_channel_counts));
- if (!iodev->supported_channel_counts)
- return -ENOMEM;
- iodev->supported_channel_counts[0] = 1;
- iodev->supported_channel_counts[1] = 0;
-
- free(iodev->supported_formats);
- iodev->supported_formats =
- malloc(2 * sizeof(*iodev->supported_formats));
- if (!iodev->supported_formats)
- return -ENOMEM;
- iodev->supported_formats[0] = SND_PCM_FORMAT_S16_LE;
- iodev->supported_formats[1] = 0;
-
- return 0;
-}
-
-static int hfp_alsa_configure_dev(struct cras_iodev *iodev)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
- int rc;
-
- /* Fill back the format iodev is using. */
- if (aio->format == NULL) {
- aio->format = (struct cras_audio_format *)malloc(
- sizeof(*aio->format));
- if (!aio->format)
- return -ENOMEM;
- *aio->format = *iodev->format;
- }
-
- rc = aio->configure_dev(aio);
- if (rc) {
- syslog(LOG_ERR, "Failed to configure aio: %d\n", rc);
- return rc;
- }
-
- rc = cras_bt_device_get_sco(
- hfp_alsa_io->device,
- hfp_slc_get_selected_codec(hfp_alsa_io->slc));
- if (rc < 0) {
- syslog(LOG_ERR, "Failed to get sco: %d\n", rc);
- return rc;
- }
-
- hfp_set_call_status(hfp_alsa_io->slc, 1);
- iodev->buffer_size = aio->buffer_size;
-
- return 0;
-}
-
-static int hfp_alsa_close_dev(struct cras_iodev *iodev)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- hfp_set_call_status(hfp_alsa_io->slc, 0);
- cras_bt_device_put_sco(hfp_alsa_io->device);
- cras_iodev_free_format(iodev);
- return aio->close_dev(aio);
-}
-
-static int hfp_alsa_frames_queued(const struct cras_iodev *iodev,
- struct timespec *tstamp)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- return aio->frames_queued(aio, tstamp);
-}
-
-static int hfp_alsa_delay_frames(const struct cras_iodev *iodev)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- return aio->delay_frames(aio);
-}
-
-static int hfp_alsa_get_buffer(struct cras_iodev *iodev,
- struct cras_audio_area **area, unsigned *frames)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- return aio->get_buffer(aio, area, frames);
-}
-
-static int hfp_alsa_put_buffer(struct cras_iodev *iodev, unsigned nwritten)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- return aio->put_buffer(aio, nwritten);
-}
-
-static int hfp_alsa_flush_buffer(struct cras_iodev *iodev)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- return aio->flush_buffer(aio);
-}
-
-static void hfp_alsa_update_active_node(struct cras_iodev *iodev,
- unsigned node_idx, unsigned dev_enabled)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- aio->update_active_node(aio, node_idx, dev_enabled);
-}
-
-static int hfp_alsa_start(const struct cras_iodev *iodev)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- return aio->start(aio);
-}
-
-static void hfp_alsa_set_volume(struct cras_iodev *iodev)
-{
- size_t volume;
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
-
- volume = cras_system_get_volume();
- if (iodev->active_node)
- volume = cras_iodev_adjust_node_volume(iodev->active_node,
- volume);
-
- hfp_event_speaker_gain(hfp_alsa_io->slc, volume);
-}
-
-static int hfp_alsa_no_stream(struct cras_iodev *iodev, int enable)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- /*
- * Copy iodev->min_cb_level and iodev->max_cb_level from the parent
- * (i.e. hfp_alsa_iodev). no_stream() of alsa_io will use them.
- */
- aio->min_cb_level = iodev->min_cb_level;
- aio->max_cb_level = iodev->max_cb_level;
- return aio->no_stream(aio, enable);
-}
-
-static int hfp_alsa_is_free_running(const struct cras_iodev *iodev)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- return aio->is_free_running(aio);
-}
-
-static int hfp_alsa_output_underrun(struct cras_iodev *iodev)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- /*
- * Copy iodev->min_cb_level and iodev->max_cb_level from the parent
- * (i.e. hfp_alsa_iodev). output_underrun() of alsa_io will use them.
- */
- aio->min_cb_level = iodev->min_cb_level;
- aio->max_cb_level = iodev->max_cb_level;
-
- return aio->output_underrun(aio);
-}
-
-struct cras_iodev *hfp_alsa_iodev_create(struct cras_iodev *aio,
- struct cras_bt_device *device,
- struct hfp_slc_handle *slc,
- enum cras_bt_device_profile profile)
-{
- struct hfp_alsa_io *hfp_alsa_io;
- struct cras_iodev *iodev;
- struct cras_ionode *node;
- const char *name;
-
- hfp_alsa_io = calloc(1, sizeof(*hfp_alsa_io));
- if (!hfp_alsa_io)
- return NULL;
-
- iodev = &hfp_alsa_io->base;
- iodev->direction = aio->direction;
-
- hfp_alsa_io->device = device;
- hfp_alsa_io->slc = slc;
- hfp_alsa_io->aio = aio;
-
- /* Set iodev's name to device readable name or the address. */
- name = cras_bt_device_name(device);
- if (!name)
- name = cras_bt_device_object_path(device);
- snprintf(iodev->info.name, sizeof(iodev->info.name), "%s", name);
- iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = 0;
- iodev->info.stable_id = cras_bt_device_get_stable_id(device);
-
- iodev->open_dev = hfp_alsa_open_dev;
- iodev->update_supported_formats = hfp_alsa_update_supported_formats;
- iodev->configure_dev = hfp_alsa_configure_dev;
- iodev->close_dev = hfp_alsa_close_dev;
-
- iodev->frames_queued = hfp_alsa_frames_queued;
- iodev->delay_frames = hfp_alsa_delay_frames;
- iodev->get_buffer = hfp_alsa_get_buffer;
- iodev->put_buffer = hfp_alsa_put_buffer;
- iodev->flush_buffer = hfp_alsa_flush_buffer;
-
- iodev->update_active_node = hfp_alsa_update_active_node;
- iodev->start = hfp_alsa_start;
- iodev->set_volume = hfp_alsa_set_volume;
- iodev->get_valid_frames = hfp_alsa_get_valid_frames;
- iodev->no_stream = hfp_alsa_no_stream;
- iodev->is_free_running = hfp_alsa_is_free_running;
- iodev->output_underrun = hfp_alsa_output_underrun;
-
- iodev->min_buffer_level = aio->min_buffer_level;
-
- node = calloc(1, sizeof(*node));
- node->dev = iodev;
- strcpy(node->name, iodev->info.name);
-
- node->plugged = 1;
- /* If headset mic uses legacy narrow band, i.e CVSD codec, report a
- * different node type so UI can set different plug priority. */
- node->type = CRAS_NODE_TYPE_BLUETOOTH;
- if ((hfp_slc_get_selected_codec(hfp_alsa_io->slc) ==
- HFP_CODEC_ID_CVSD) &&
- (iodev->direction == CRAS_STREAM_INPUT))
- node->type = CRAS_NODE_TYPE_BLUETOOTH_NB_MIC;
- node->volume = 100;
- gettimeofday(&node->plugged_time, NULL);
-
- /* Prepare active node before append, so bt_io can extract correct
- * info from hfp_alsa iodev and node. */
- cras_iodev_add_node(iodev, node);
- cras_iodev_set_active_node(iodev, node);
- cras_bt_device_append_iodev(device, iodev, profile);
-
- /* Record max supported channels into cras_iodev_info. */
- iodev->info.max_supported_channels = 1;
-
- /* Specifically disable EWMA calculation on this and the child iodev. */
- ewma_power_disable(&iodev->ewma);
- ewma_power_disable(&aio->ewma);
-
- return iodev;
-}
-
-void hfp_alsa_iodev_destroy(struct cras_iodev *iodev)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_ionode *node;
-
- cras_bt_device_rm_iodev(hfp_alsa_io->device, iodev);
-
- node = iodev->active_node;
- if (node) {
- cras_iodev_rm_node(iodev, node);
- free(node);
- }
-
- free(iodev->supported_channel_counts);
- free(iodev->supported_rates);
- free(iodev->supported_formats);
- cras_iodev_free_resources(iodev);
-
- free(hfp_alsa_io);
-}