CRAS: hfp - Consolidate SCO connection functions
The cras_hfp_alsa_iodev path requires SCO connection
setup but doesn't do HCI SCO packets read/write.
This change refactors the functions of cras_sco in
a few ways:
(1) pass cras_sco instance to cras_hfp_alsa_iodev
constructor and tracks its reference through
add/remove dev just like how cras_hfp_iodev does it.
(2) expose set/get_fd for cras_hfp_alsa_iodev usage
With above we can remove the old cras_bt_device_get/put
SCO function and consolidate offloading and non-offloading
path to use the single cras_bt_device_connect_sco APi.
This will benefit future change to extend SCO connection
configuration.
BUG=b:183594508
TEST=emerge, unittest
Change-Id: I0a2e87f2d61b1c80aa485ff28e029162e5e7f135
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/adhd/+/2853171
Reviewed-by: Hsinyu Chao <hychao@chromium.org>
Commit-Queue: Hsinyu Chao <hychao@chromium.org>
Tested-by: Hsinyu Chao <hychao@chromium.org>
diff --git a/cras/src/server/cras_bt_device.c b/cras/src/server/cras_bt_device.c
index 7c77b5b..2a577b1 100644
--- a/cras/src/server/cras_bt_device.c
+++ b/cras/src/server/cras_bt_device.c
@@ -89,8 +89,6 @@
* suspend_timer - The timer used to suspend device.
* switch_profile_timer - The timer used to delay enabling iodev after
* profile switch.
- * sco_fd - The file descriptor of the SCO connection.
- * sco_ref_count - The reference counts of the SCO connection.
* suspend_reason - The reason code for why suspend is scheduled.
* stable_id - The unique and persistent id of this bt_device.
*/
@@ -114,8 +112,6 @@
struct cras_timer *conn_watch_timer;
struct cras_timer *suspend_timer;
struct cras_timer *switch_profile_timer;
- int sco_fd;
- size_t sco_ref_count;
enum cras_bt_device_suspend_reason suspend_reason;
unsigned int stable_id;
@@ -1373,24 +1369,3 @@
iodev->active_node->volume = volume;
cras_iodev_list_notify_node_volume(iodev->active_node);
}
-
-int cras_bt_device_get_sco(struct cras_bt_device *device, int codec)
-{
- if (device->sco_ref_count == 0) {
- device->sco_fd = cras_bt_device_sco_connect(device, codec);
- if (device->sco_fd < 0)
- return device->sco_fd;
- }
-
- ++device->sco_ref_count;
- return 0;
-}
-
-void cras_bt_device_put_sco(struct cras_bt_device *device)
-{
- if (device->sco_ref_count == 0)
- return;
-
- if (--device->sco_ref_count == 0)
- close(device->sco_fd);
-}
diff --git a/cras/src/server/cras_hfp_ag_profile.c b/cras/src/server/cras_hfp_ag_profile.c
index d0581f9..9e5de92 100644
--- a/cras/src/server/cras_hfp_ag_profile.c
+++ b/cras/src/server/cras_hfp_ag_profile.c
@@ -291,6 +291,7 @@
if (ag->idev)
return 0;
+ ag->sco = cras_sco_create();
if (need_go_sco_pcm(device)) {
struct cras_iodev *in_aio, *out_aio;
@@ -298,11 +299,10 @@
out_aio = cras_iodev_list_get_sco_pcm_iodev(CRAS_STREAM_OUTPUT);
ag->idev = hfp_alsa_iodev_create(in_aio, ag->device,
- ag->slc_handle);
+ ag->slc_handle, ag->sco);
ag->odev = hfp_alsa_iodev_create(out_aio, ag->device,
- ag->slc_handle);
+ ag->slc_handle, ag->sco);
} else {
- ag->sco = cras_sco_create();
cras_sco_set_wbs_logger(ag->sco, &wbs_logger);
ag->idev = hfp_iodev_create(CRAS_STREAM_INPUT, ag->device,
ag->slc_handle, ag->sco);
diff --git a/cras/src/server/cras_hfp_alsa_iodev.c b/cras/src/server/cras_hfp_alsa_iodev.c
index 1615e51..c563d1e 100644
--- a/cras/src/server/cras_hfp_alsa_iodev.c
+++ b/cras/src/server/cras_hfp_alsa_iodev.c
@@ -24,12 +24,14 @@
* device - The corresponding remote BT device.
* slc - The service level connection.
* aio - The effective iodev for playback/capture.
+ * sco - The cras_sco instance for configuring audio path.
*/
struct hfp_alsa_io {
struct cras_iodev base;
struct cras_bt_device *device;
struct hfp_slc_handle *slc;
struct cras_iodev *aio;
+ struct cras_sco *sco;
};
static int hfp_alsa_get_valid_frames(struct cras_iodev *iodev,
@@ -105,9 +107,17 @@
return rc;
}
+ /* Check the associated SCO object first. Because configuring
+ * the shared SCO object can only be done once for the HFP
+ * input and output devices pair.
+ */
+ rc = cras_sco_get_fd(hfp_alsa_io->sco);
+ if (rc >= 0)
+ goto add_dev;
+
hfp_slc_codec_connection_setup(hfp_alsa_io->slc);
- rc = cras_bt_device_get_sco(
+ rc = cras_bt_device_sco_connect(
hfp_alsa_io->device,
hfp_slc_get_selected_codec(hfp_alsa_io->slc));
if (rc < 0) {
@@ -115,7 +125,11 @@
return rc;
}
+ cras_sco_set_fd(hfp_alsa_io->sco, rc);
hfp_set_call_status(hfp_alsa_io->slc, 1);
+
+add_dev:
+ cras_sco_add_iodev(hfp_alsa_io->sco, iodev->direction, iodev->format);
iodev->buffer_size = aio->buffer_size;
return 0;
@@ -126,8 +140,16 @@
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_sco_rm_iodev(hfp_alsa_io->sco, iodev->direction);
+
+ /* Check the associated SCO object because cleaning up the
+ * shared SLC and SCO objects should be done when the later
+ * of HFP input or output device gets closed.
+ */
+ if (!cras_sco_has_iodev(hfp_alsa_io->sco)) {
+ hfp_set_call_status(hfp_alsa_io->slc, 0);
+ cras_sco_close_fd(hfp_alsa_io->sco);
+ }
cras_iodev_free_format(iodev);
return aio->close_dev(aio);
}
@@ -243,7 +265,8 @@
struct cras_iodev *hfp_alsa_iodev_create(struct cras_iodev *aio,
struct cras_bt_device *device,
- struct hfp_slc_handle *slc)
+ struct hfp_slc_handle *slc,
+ struct cras_sco *sco)
{
struct hfp_alsa_io *hfp_alsa_io;
struct cras_iodev *iodev;
@@ -259,6 +282,7 @@
hfp_alsa_io->device = device;
hfp_alsa_io->slc = slc;
+ hfp_alsa_io->sco = sco;
hfp_alsa_io->aio = aio;
/* Set iodev's name to device readable name or the address. */
diff --git a/cras/src/server/cras_hfp_alsa_iodev.h b/cras/src/server/cras_hfp_alsa_iodev.h
index e09efba..523eba8 100644
--- a/cras/src/server/cras_hfp_alsa_iodev.h
+++ b/cras/src/server/cras_hfp_alsa_iodev.h
@@ -22,7 +22,8 @@
*/
struct cras_iodev *hfp_alsa_iodev_create(struct cras_iodev *aio,
struct cras_bt_device *device,
- struct hfp_slc_handle *slc);
+ struct hfp_slc_handle *slc,
+ struct cras_sco *sco);
void hfp_alsa_iodev_destroy(struct cras_iodev *iodev);
diff --git a/cras/src/server/cras_hfp_iodev.c b/cras/src/server/cras_hfp_iodev.c
index ad2f6d4..ad123c6 100644
--- a/cras/src/server/cras_hfp_iodev.c
+++ b/cras/src/server/cras_hfp_iodev.c
@@ -153,11 +153,12 @@
if (sk < 0)
goto error;
+ cras_sco_set_fd(hfpio->sco, sk);
mtu = cras_bt_device_sco_packet_size(
hfpio->device, sk, hfp_slc_get_selected_codec(hfpio->slc));
/* Start cras_sco */
- err = cras_sco_start(sk, mtu, hfp_slc_get_selected_codec(hfpio->slc),
+ err = cras_sco_start(mtu, hfp_slc_get_selected_codec(hfpio->slc),
hfpio->sco);
if (err)
goto error;
@@ -183,6 +184,7 @@
cras_sco_rm_iodev(hfpio->sco, iodev->direction);
if (cras_sco_running(hfpio->sco) && !cras_sco_has_iodev(hfpio->sco)) {
cras_sco_stop(hfpio->sco);
+ cras_sco_close_fd(hfpio->sco);
hfp_set_call_status(hfpio->slc, 0);
}
diff --git a/cras/src/server/cras_sco.c b/cras/src/server/cras_sco.c
index 4e0306d..9300d4c 100644
--- a/cras/src/server/cras_sco.c
+++ b/cras/src/server/cras_sco.c
@@ -755,14 +755,38 @@
sco->wbs_logger = wbs_logger;
}
+int cras_sco_set_fd(struct cras_sco *sco, int fd)
+{
+ /* Valid only when existing fd isn't set and the new fd is
+ * non-negative to prevent leak. */
+ if (sco->fd >= 0 || fd < 0)
+ return -EINVAL;
+ sco->fd = fd;
+ return 0;
+}
+
+int cras_sco_get_fd(struct cras_sco *sco)
+{
+ return sco->fd;
+}
+
+void cras_sco_close_fd(struct cras_sco *sco)
+{
+ if (sco->fd < 0)
+ return;
+ close(sco->fd);
+ sco->fd = -1;
+}
+
int cras_sco_running(struct cras_sco *sco)
{
return sco->started;
}
-int cras_sco_start(int fd, unsigned int mtu, int codec, struct cras_sco *sco)
+int cras_sco_start(unsigned int mtu, int codec, struct cras_sco *sco)
{
- sco->fd = fd;
+ if (sco->fd == 0)
+ return -EINVAL;
sco->mtu = mtu;
/* Initialize to MTU, it may change when actually read the socket. */
@@ -826,9 +850,6 @@
audio_thread_rm_callback_sync(cras_iodev_list_get_audio_thread(),
sco->fd);
-
- close(sco->fd);
- sco->fd = -1;
sco->started = 0;
/* Unset the write/read callbacks. */
diff --git a/cras/src/server/cras_sco.h b/cras/src/server/cras_sco.h
index 05eb1c5..3674134 100644
--- a/cras/src/server/cras_sco.h
+++ b/cras/src/server/cras_sco.h
@@ -34,15 +34,26 @@
void cras_sco_set_wbs_logger(struct cras_sco *sco,
struct packet_status_logger *wbs_logger);
+/* Sets the file descriptor to cras_sco. */
+int cras_sco_set_fd(struct cras_sco *sco, int fd);
+
+/* Gets the file descriptor of cras_sco. */
+int cras_sco_get_fd(struct cras_sco *sco);
+
+/* Closes the file descriptor of cras_sco. */
+void cras_sco_close_fd(struct cras_sco *sco);
+
/* Checks if given cras_sco is running. */
int cras_sco_running(struct cras_sco *sco);
/* Starts the cras_sco to transmit and reveice samples to and from the file
* descriptor of a SCO socket. This should be called from main thread.
* Args:
+ * mtu - The packet size of HCI SCO packet.
* codec - 1 for CVSD, 2 for mSBC per HFP 1.7 specification.
+ * sco - The cras_sco instance.
*/
-int cras_sco_start(int fd, unsigned int mtu, int codec, struct cras_sco *sco);
+int cras_sco_start(unsigned int mtu, int codec, struct cras_sco *sco);
/* Stops given cras_sco. This implies sample transmission will
* stop and socket be closed. This should be called from main thread.
diff --git a/cras/src/tests/cras_sco_unittest.cc b/cras/src/tests/cras_sco_unittest.cc
index f96d034..353edb5 100644
--- a/cras/src/tests/cras_sco_unittest.cc
+++ b/cras/src/tests/cras_sco_unittest.cc
@@ -79,13 +79,17 @@
TEST(CrasSco, AcquirePlaybackBuffer) {
unsigned buffer_frames, buffer_frames2, queued;
uint8_t* samples;
+ int sock[2];
ResetStubData();
+ ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
+
sco = cras_sco_create();
ASSERT_NE(sco, (void*)NULL);
- cras_sco_start(1, 48, HFP_CODEC_ID_CVSD, sco);
+ cras_sco_set_fd(sco, sock[1]);
+ cras_sco_start(48, HFP_CODEC_ID_CVSD, sco);
dev.direction = CRAS_STREAM_OUTPUT;
ASSERT_EQ(0, cras_sco_add_iodev(sco, dev.direction, dev.format));
@@ -121,19 +125,24 @@
ASSERT_GE(sco->playback_buf->used_size / 2, buffer_frames + buffer_frames2);
+ cras_sco_stop(sco);
+ cras_sco_close_fd(sco);
cras_sco_destroy(sco);
}
TEST(CrasSco, AcquireCaptureBuffer) {
unsigned buffer_frames, buffer_frames2;
uint8_t* samples;
+ int sock[2];
ResetStubData();
+ ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
sco = cras_sco_create();
ASSERT_NE(sco, (void*)NULL);
- cras_sco_start(1, 48, HFP_CODEC_ID_CVSD, sco);
+ cras_sco_set_fd(sco, sock[1]);
+ cras_sco_start(48, HFP_CODEC_ID_CVSD, sco);
dev.direction = CRAS_STREAM_INPUT;
ASSERT_EQ(0, cras_sco_add_iodev(sco, dev.direction, dev.format));
@@ -164,6 +173,8 @@
ASSERT_GE(sco->capture_buf->used_size / 2, buffer_frames + buffer_frames2);
+ cras_sco_stop(sco);
+ cras_sco_close_fd(sco);
cras_sco_destroy(sco);
}
@@ -182,7 +193,8 @@
ASSERT_NE(sco, (void*)NULL);
dev.direction = CRAS_STREAM_INPUT;
- cras_sco_start(sock[1], 48, HFP_CODEC_ID_CVSD, sco);
+ cras_sco_set_fd(sco, sock[1]);
+ cras_sco_start(48, HFP_CODEC_ID_CVSD, sco);
ASSERT_EQ(0, cras_sco_add_iodev(sco, dev.direction, dev.format));
/* Mock the sco fd and send some fake data */
@@ -221,6 +233,7 @@
rc = recv(sock[0], sample, 48, 0);
ASSERT_EQ(48, rc);
+ cras_sco_close_fd(sco);
cras_sco_destroy(sco);
}
@@ -232,7 +245,8 @@
sco = cras_sco_create();
ASSERT_NE(sco, (void*)NULL);
- cras_sco_start(sock[0], 48, HFP_CODEC_ID_CVSD, sco);
+ cras_sco_set_fd(sco, sock[0]);
+ cras_sco_start(48, HFP_CODEC_ID_CVSD, sco);
ASSERT_EQ(1, cras_sco_running(sco));
ASSERT_EQ(cb_data, (void*)sco);
@@ -240,6 +254,7 @@
ASSERT_EQ(0, cras_sco_running(sco));
ASSERT_EQ(NULL, cb_data);
+ cras_sco_close_fd(sco);
cras_sco_destroy(sco);
}
@@ -256,7 +271,8 @@
ASSERT_NE(sco, (void*)NULL);
/* Start and send two chunk of fake data */
- cras_sco_start(sock[1], 48, HFP_CODEC_ID_CVSD, sco);
+ cras_sco_set_fd(sco, sock[1]);
+ cras_sco_start(48, HFP_CODEC_ID_CVSD, sco);
send(sock[0], sample, 48, 0);
send(sock[0], sample, 48, 0);
@@ -285,6 +301,7 @@
cras_sco_stop(sco);
ASSERT_EQ(0, cras_sco_running(sco));
+ cras_sco_close_fd(sco);
cras_sco_destroy(sco);
}
@@ -300,7 +317,8 @@
sco = cras_sco_create();
ASSERT_NE(sco, (void*)NULL);
- cras_sco_start(sock[1], 48, HFP_CODEC_ID_CVSD, sco);
+ cras_sco_set_fd(sco, sock[1]);
+ cras_sco_start(48, HFP_CODEC_ID_CVSD, sco);
send(sock[0], sample, 48, 0);
send(sock[0], sample, 48, 0);
@@ -327,6 +345,7 @@
ASSERT_EQ(480, cras_sco_buf_queued(sco, dev.direction));
cras_sco_stop(sco);
+ cras_sco_close_fd(sco);
cras_sco_destroy(sco);
}
@@ -388,7 +407,8 @@
ASSERT_EQ(0, cras_msbc_plc_create_called);
/* Start and send an mSBC packets with all zero samples */
- cras_sco_start(sock[1], 63, HFP_CODEC_ID_MSBC, sco);
+ cras_sco_set_fd(sco, sock[1]);
+ cras_sco_start(63, HFP_CODEC_ID_MSBC, sco);
ASSERT_EQ(2, get_msbc_codec_create_called());
ASSERT_EQ(1, cras_msbc_plc_create_called);
send_mSBC_packet(sock[0], pkt_count++, 0);
@@ -467,6 +487,7 @@
cras_sco_stop(sco);
ASSERT_EQ(0, cras_sco_running(sco));
+ cras_sco_close_fd(sco);
cras_sco_destroy(sco);
}
@@ -483,7 +504,8 @@
sco = cras_sco_create();
ASSERT_NE(sco, (void*)NULL);
- cras_sco_start(sock[1], 63, HFP_CODEC_ID_MSBC, sco);
+ cras_sco_set_fd(sco, sock[1]);
+ cras_sco_start(63, HFP_CODEC_ID_MSBC, sco);
send(sock[0], sample, 63, 0);
/* Trigger thread callback */
@@ -506,6 +528,7 @@
ASSERT_EQ(0, cras_sco_buf_queued(sco, dev.direction));
cras_sco_stop(sco);
+ cras_sco_close_fd(sco);
cras_sco_destroy(sco);
}
diff --git a/cras/src/tests/hfp_alsa_iodev_unittest.cc b/cras/src/tests/hfp_alsa_iodev_unittest.cc
index ff4f8e1..e7e60bc 100644
--- a/cras/src/tests/hfp_alsa_iodev_unittest.cc
+++ b/cras/src/tests/hfp_alsa_iodev_unittest.cc
@@ -19,6 +19,7 @@
struct cras_iodev* aio;
};
+static struct cras_sco* fake_sco;
static struct cras_iodev fake_sco_out, fake_sco_in;
static struct cras_bt_device* fake_device;
static struct hfp_slc_handle* fake_slc;
@@ -82,6 +83,7 @@
hfp_set_call_status_called = 0;
hfp_event_speaker_gain_called = 0;
+ fake_sco = reinterpret_cast<struct cras_sco*>(0x123);
fake_sco_out.open_dev = fake_sco_in.open_dev =
(int (*)(struct cras_iodev*))fake_open_dev;
fake_open_dev_called = 0;
@@ -157,7 +159,7 @@
struct hfp_alsa_io* hfp_alsa_io;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
hfp_alsa_io = (struct hfp_alsa_io*)iodev;
EXPECT_EQ(CRAS_STREAM_OUTPUT, iodev->direction);
@@ -178,7 +180,7 @@
struct hfp_alsa_io* hfp_alsa_io;
fake_sco_in.direction = CRAS_STREAM_INPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_in, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_in, fake_device, fake_slc, fake_sco);
hfp_alsa_io = (struct hfp_alsa_io*)iodev;
EXPECT_EQ(CRAS_STREAM_INPUT, iodev->direction);
@@ -200,7 +202,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->open_dev(iodev);
EXPECT_EQ(1, fake_open_dev_called);
@@ -220,7 +222,7 @@
fake_sco_out.supported_formats = supported_formats;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->update_supported_formats(iodev);
// update_supported_format on alsa_io is not called.
@@ -241,7 +243,7 @@
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
fake_sco_out.buffer_size = buf_size;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
hfp_alsa_io = (struct hfp_alsa_io*)iodev;
iodev->format = &fake_format;
iodev->configure_dev(iodev);
@@ -264,7 +266,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->close_dev(iodev);
EXPECT_EQ(1, hfp_set_call_status_called);
@@ -278,7 +280,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->frames_queued(iodev, (struct timespec*)NULL);
EXPECT_EQ(1, fake_frames_queued_called);
@@ -290,7 +292,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->delay_frames(iodev);
EXPECT_EQ(1, fake_delay_frames_called);
@@ -302,7 +304,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->get_buffer(iodev, (struct cras_audio_area**)NULL, (unsigned*)NULL);
EXPECT_EQ(1, fake_get_buffer_called);
@@ -314,7 +316,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->put_buffer(iodev, 0xdeadbeef);
EXPECT_EQ(1, fake_put_buffer_called);
@@ -326,7 +328,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->flush_buffer(iodev);
EXPECT_EQ(1, fake_flush_buffer_called);
@@ -338,7 +340,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->update_active_node(iodev, 0xdeadbeef, 0xdeadbeef);
EXPECT_EQ(1, fake_update_active_node_called);
@@ -350,7 +352,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->start(iodev);
EXPECT_EQ(1, fake_start_called);
@@ -362,7 +364,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->set_volume(iodev);
EXPECT_EQ(1, hfp_event_speaker_gain_called);
@@ -374,7 +376,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->min_cb_level = 0xab;
iodev->max_cb_level = 0xcd;
@@ -391,7 +393,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->is_free_running(iodev);
EXPECT_EQ(1, fake_is_free_running_called);
@@ -403,7 +405,7 @@
struct cras_iodev* iodev;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->min_cb_level = 0xab;
iodev->max_cb_level = 0xcd;
@@ -421,7 +423,7 @@
struct timespec ts;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc);
+ iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc, fake_sco);
iodev->get_valid_frames(iodev, &ts);
@@ -515,11 +517,35 @@
return 0;
}
-int cras_bt_device_get_sco(struct cras_bt_device* device, int codec) {
+int cras_bt_device_sco_connect(struct cras_bt_device* device, int codec) {
return 0;
}
-void cras_bt_device_put_sco(struct cras_bt_device* device) {}
+int cras_sco_add_iodev(struct cras_sco* sco,
+ enum CRAS_STREAM_DIRECTION direction,
+ struct cras_audio_format* format) {
+ return 0;
+}
+
+int cras_sco_rm_iodev(struct cras_sco* sco,
+ enum CRAS_STREAM_DIRECTION direction) {
+ return 0;
+}
+
+int cras_sco_has_iodev(struct cras_sco* sco) {
+ return 0;
+}
+
+int cras_sco_set_fd(struct cras_sco* sco, int fd) {
+ return 0;
+}
+
+int cras_sco_get_fd(struct cras_sco* sco) {
+ return -1;
+}
+void cras_sco_close_fd(struct cras_sco* sco) {
+ return;
+}
int hfp_slc_get_selected_codec(struct hfp_slc_handle* handle) {
return HFP_CODEC_ID_CVSD;
diff --git a/cras/src/tests/hfp_iodev_unittest.cc b/cras/src/tests/hfp_iodev_unittest.cc
index 339b3f7..ec21e68 100644
--- a/cras/src/tests/hfp_iodev_unittest.cc
+++ b/cras/src/tests/hfp_iodev_unittest.cc
@@ -307,7 +307,7 @@
return cras_sco_running_return_val;
}
-int cras_sco_start(int fd, unsigned int mtu, int codec, struct cras_sco* sco) {
+int cras_sco_start(unsigned int mtu, int codec, struct cras_sco* sco) {
cras_sco_start_called++;
return 0;
}
@@ -317,6 +317,13 @@
return 0;
}
+int cras_sco_set_fd(struct cras_sco* sco, int fd) {
+ return 0;
+}
+void cras_sco_close_fd(struct cras_sco* sco) {
+ return;
+}
+
int cras_sco_buf_queued(struct cras_sco* sco,
const enum CRAS_STREAM_DIRECTION direction) {
return 0;