• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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