| /* Copyright (c) 2013 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 <gtest/gtest.h> |
| #include <stdint.h> |
| #include <sys/socket.h> |
| |
| #include <stdio.h> |
| |
| extern "C" { |
| #include "cras_hfp_slc.h" |
| #include "cras_telephony.h" |
| } |
| |
| static struct hfp_slc_handle *handle; |
| static struct cras_telephony_handle fake_telephony; |
| static int cras_bt_device_update_hardware_volume_called; |
| static int slc_initialized_cb_called; |
| static int slc_disconnected_cb_called; |
| static int cras_system_add_select_fd_called; |
| static void(*slc_cb)(void *data); |
| static void *slc_cb_data; |
| static int fake_errno; |
| static struct cras_bt_device *device = |
| reinterpret_cast<struct cras_bt_device *>(2); |
| |
| int slc_initialized_cb(struct hfp_slc_handle *handle); |
| int slc_disconnected_cb(struct hfp_slc_handle *handle); |
| |
| void ResetStubData() { |
| slc_initialized_cb_called = 0; |
| cras_system_add_select_fd_called = 0; |
| cras_bt_device_update_hardware_volume_called = 0; |
| slc_cb = NULL; |
| slc_cb_data = NULL; |
| } |
| |
| namespace { |
| |
| TEST(HfpSlc, CreateSlcHandle) { |
| ResetStubData(); |
| |
| handle = hfp_slc_create(0, 0, device, slc_initialized_cb, |
| slc_disconnected_cb); |
| ASSERT_EQ(1, cras_system_add_select_fd_called); |
| ASSERT_EQ(handle, slc_cb_data); |
| |
| hfp_slc_destroy(handle); |
| } |
| |
| TEST(HfpSlc, InitializeSlc) { |
| int err; |
| int sock[2]; |
| char buf[256]; |
| char *chp; |
| ResetStubData(); |
| |
| ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock)); |
| handle = hfp_slc_create(sock[0], 0, device, slc_initialized_cb, |
| slc_disconnected_cb); |
| |
| err = write(sock[1], "AT+CIND=?\r", 10); |
| ASSERT_EQ(10, err); |
| slc_cb(slc_cb_data); |
| err = read(sock[1], buf, 256); |
| |
| /* Assert "\r\n+CIND: ... \r\n" response is received */ |
| chp = strstr(buf, "\r\n"); |
| ASSERT_NE((void *)NULL, (void *)chp); |
| ASSERT_EQ(0, strncmp("\r\n+CIND:", chp, 8)); |
| chp+=2; |
| chp = strstr(chp, "\r\n"); |
| ASSERT_NE((void *)NULL, (void *)chp); |
| |
| /* Assert "\r\nOK\r\n" response is received */ |
| chp+=2; |
| chp = strstr(chp, "\r\n"); |
| ASSERT_NE((void *)NULL, (void *)chp); |
| ASSERT_EQ(0, strncmp("\r\nOK", chp, 4)); |
| |
| err = write(sock[1], "AT+CMER=3,0,0,1\r", 16); |
| ASSERT_EQ(16, err); |
| slc_cb(slc_cb_data); |
| |
| ASSERT_EQ(1, slc_initialized_cb_called); |
| |
| /* Assert "\r\nOK\r\n" response is received */ |
| err = read(sock[1], buf, 256); |
| |
| chp = strstr(buf, "\r\n"); |
| ASSERT_NE((void *)NULL, (void *)chp); |
| ASSERT_EQ(0, strncmp("\r\nOK", chp, 4)); |
| |
| err = write(sock[1], "AT+VGS=13\r", 10); |
| ASSERT_EQ(err, 10); |
| slc_cb(slc_cb_data); |
| |
| err = read(sock[1], buf, 256); |
| |
| chp = strstr(buf, "\r\n"); |
| ASSERT_NE((void *)NULL, (void *)chp); |
| ASSERT_EQ(0, strncmp("\r\nOK", chp, 4)); |
| |
| ASSERT_EQ(1, cras_bt_device_update_hardware_volume_called); |
| |
| hfp_slc_destroy(handle); |
| } |
| |
| TEST(HfpSlc, DisconnectSlc) { |
| int sock[2]; |
| ResetStubData(); |
| |
| ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock)); |
| handle = hfp_slc_create(sock[0], 0, device, slc_initialized_cb, |
| slc_disconnected_cb); |
| /* Close socket right away to make read() get negative err code, and |
| * fake the errno to ECONNRESET. */ |
| close(sock[0]); |
| close(sock[1]); |
| fake_errno = 104; |
| slc_cb(slc_cb_data); |
| |
| ASSERT_EQ(1, slc_disconnected_cb_called); |
| |
| hfp_slc_destroy(handle); |
| } |
| } // namespace |
| |
| int slc_initialized_cb(struct hfp_slc_handle *handle) { |
| slc_initialized_cb_called++; |
| return 0; |
| } |
| |
| int slc_disconnected_cb(struct hfp_slc_handle *handle) { |
| slc_disconnected_cb_called++; |
| return 0; |
| } |
| |
| extern "C" { |
| int cras_system_add_select_fd(int fd, |
| void (*callback)(void *data), |
| void *callback_data) { |
| cras_system_add_select_fd_called++; |
| slc_cb = callback; |
| slc_cb_data = callback_data; |
| return 0; |
| } |
| |
| void cras_system_rm_select_fd(int fd) { |
| } |
| |
| void cras_bt_device_update_hardware_volume(struct cras_bt_device *device, |
| int volume) |
| { |
| cras_bt_device_update_hardware_volume_called++; |
| } |
| |
| /* To return fake errno */ |
| int *__errno_location() { |
| return &fake_errno; |
| } |
| } |
| |
| // For telephony |
| struct cras_telephony_handle* cras_telephony_get() |
| { |
| return &fake_telephony; |
| } |
| |
| void cras_telephony_store_dial_number(int len, const char* num) |
| { |
| } |
| |
| int cras_telephony_event_answer_call() |
| { |
| return 0; |
| } |
| |
| int cras_telephony_event_terminate_call() |
| { |
| return 0; |
| } |
| |
| int main(int argc, char **argv) { |
| ::testing::InitGoogleTest(&argc, argv); |
| return RUN_ALL_TESTS(); |
| } |