1 /* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include <gtest/gtest.h>
7 #include <stdint.h>
8 #include <sys/socket.h>
9
10 #include <stdio.h>
11
12 extern "C" {
13 #include "cras_hfp_slc.h"
14 #include "cras_telephony.h"
15 }
16
17 static struct hfp_slc_handle *handle;
18 static struct cras_telephony_handle fake_telephony;
19 static int cras_bt_device_update_hardware_volume_called;
20 static int slc_initialized_cb_called;
21 static int slc_disconnected_cb_called;
22 static int cras_system_add_select_fd_called;
23 static void(*slc_cb)(void *data);
24 static void *slc_cb_data;
25 static int fake_errno;
26 static struct cras_bt_device *device =
27 reinterpret_cast<struct cras_bt_device *>(2);
28
29 int slc_initialized_cb(struct hfp_slc_handle *handle);
30 int slc_disconnected_cb(struct hfp_slc_handle *handle);
31
ResetStubData()32 void ResetStubData() {
33 slc_initialized_cb_called = 0;
34 cras_system_add_select_fd_called = 0;
35 cras_bt_device_update_hardware_volume_called = 0;
36 slc_cb = NULL;
37 slc_cb_data = NULL;
38 }
39
40 namespace {
41
TEST(HfpSlc,CreateSlcHandle)42 TEST(HfpSlc, CreateSlcHandle) {
43 ResetStubData();
44
45 handle = hfp_slc_create(0, 0, device, slc_initialized_cb,
46 slc_disconnected_cb);
47 ASSERT_EQ(1, cras_system_add_select_fd_called);
48 ASSERT_EQ(handle, slc_cb_data);
49
50 hfp_slc_destroy(handle);
51 }
52
TEST(HfpSlc,InitializeSlc)53 TEST(HfpSlc, InitializeSlc) {
54 int err;
55 int sock[2];
56 char buf[256];
57 char *chp;
58 ResetStubData();
59
60 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
61 handle = hfp_slc_create(sock[0], 0, device, slc_initialized_cb,
62 slc_disconnected_cb);
63
64 err = write(sock[1], "AT+CIND=?\r", 10);
65 ASSERT_EQ(10, err);
66 slc_cb(slc_cb_data);
67 err = read(sock[1], buf, 256);
68
69 /* Assert "\r\n+CIND: ... \r\n" response is received */
70 chp = strstr(buf, "\r\n");
71 ASSERT_NE((void *)NULL, (void *)chp);
72 ASSERT_EQ(0, strncmp("\r\n+CIND:", chp, 8));
73 chp+=2;
74 chp = strstr(chp, "\r\n");
75 ASSERT_NE((void *)NULL, (void *)chp);
76
77 /* Assert "\r\nOK\r\n" response is received */
78 chp+=2;
79 chp = strstr(chp, "\r\n");
80 ASSERT_NE((void *)NULL, (void *)chp);
81 ASSERT_EQ(0, strncmp("\r\nOK", chp, 4));
82
83 err = write(sock[1], "AT+CMER=3,0,0,1\r", 16);
84 ASSERT_EQ(16, err);
85 slc_cb(slc_cb_data);
86
87 ASSERT_EQ(1, slc_initialized_cb_called);
88
89 /* Assert "\r\nOK\r\n" response is received */
90 err = read(sock[1], buf, 256);
91
92 chp = strstr(buf, "\r\n");
93 ASSERT_NE((void *)NULL, (void *)chp);
94 ASSERT_EQ(0, strncmp("\r\nOK", chp, 4));
95
96 err = write(sock[1], "AT+VGS=13\r", 10);
97 ASSERT_EQ(err, 10);
98 slc_cb(slc_cb_data);
99
100 err = read(sock[1], buf, 256);
101
102 chp = strstr(buf, "\r\n");
103 ASSERT_NE((void *)NULL, (void *)chp);
104 ASSERT_EQ(0, strncmp("\r\nOK", chp, 4));
105
106 ASSERT_EQ(1, cras_bt_device_update_hardware_volume_called);
107
108 hfp_slc_destroy(handle);
109 }
110
TEST(HfpSlc,DisconnectSlc)111 TEST(HfpSlc, DisconnectSlc) {
112 int sock[2];
113 ResetStubData();
114
115 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
116 handle = hfp_slc_create(sock[0], 0, device, slc_initialized_cb,
117 slc_disconnected_cb);
118 /* Close socket right away to make read() get negative err code, and
119 * fake the errno to ECONNRESET. */
120 close(sock[0]);
121 close(sock[1]);
122 fake_errno = 104;
123 slc_cb(slc_cb_data);
124
125 ASSERT_EQ(1, slc_disconnected_cb_called);
126
127 hfp_slc_destroy(handle);
128 }
129 } // namespace
130
slc_initialized_cb(struct hfp_slc_handle * handle)131 int slc_initialized_cb(struct hfp_slc_handle *handle) {
132 slc_initialized_cb_called++;
133 return 0;
134 }
135
slc_disconnected_cb(struct hfp_slc_handle * handle)136 int slc_disconnected_cb(struct hfp_slc_handle *handle) {
137 slc_disconnected_cb_called++;
138 return 0;
139 }
140
141 extern "C" {
cras_system_add_select_fd(int fd,void (* callback)(void * data),void * callback_data)142 int cras_system_add_select_fd(int fd,
143 void (*callback)(void *data),
144 void *callback_data) {
145 cras_system_add_select_fd_called++;
146 slc_cb = callback;
147 slc_cb_data = callback_data;
148 return 0;
149 }
150
cras_system_rm_select_fd(int fd)151 void cras_system_rm_select_fd(int fd) {
152 }
153
cras_bt_device_update_hardware_volume(struct cras_bt_device * device,int volume)154 void cras_bt_device_update_hardware_volume(struct cras_bt_device *device,
155 int volume)
156 {
157 cras_bt_device_update_hardware_volume_called++;
158 }
159
160 /* To return fake errno */
__errno_location()161 int *__errno_location() {
162 return &fake_errno;
163 }
164 }
165
166 // For telephony
cras_telephony_get()167 struct cras_telephony_handle* cras_telephony_get()
168 {
169 return &fake_telephony;
170 }
171
cras_telephony_store_dial_number(int len,const char * num)172 void cras_telephony_store_dial_number(int len, const char* num)
173 {
174 }
175
cras_telephony_event_answer_call()176 int cras_telephony_event_answer_call()
177 {
178 return 0;
179 }
180
cras_telephony_event_terminate_call()181 int cras_telephony_event_terminate_call()
182 {
183 return 0;
184 }
185
main(int argc,char ** argv)186 int main(int argc, char **argv) {
187 ::testing::InitGoogleTest(&argc, argv);
188 return RUN_ALL_TESTS();
189 }
190