1 /****************************************************************************** 2 * 3 * Copyright (C) 2014 Google, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19 #include <gtest/gtest.h> 20 21 #include "AllocationTestHarness.h" 22 23 extern "C" { 24 #include <stdint.h> 25 #include <sys/types.h> 26 #include <sys/socket.h> 27 #include <unistd.h> 28 29 #include "osi/include/osi.h" 30 #include "osi/include/semaphore.h" 31 #include "hci_hal.h" 32 #include "test_stubs.h" 33 #include "vendor.h" 34 } 35 36 DECLARE_TEST_MODES( 37 init, 38 open, 39 close_fn, 40 transmit, 41 read_synchronous, 42 read_async_reentry 43 ); 44 45 static char sample_data1[100] = "A point is that which has no part."; 46 static char sample_data2[100] = "A line is breadthless length."; 47 static char sample_data3[100] = "The ends of a line are points."; 48 static char acl_data[100] = "A straight line is a line which lies evenly with the points on itself."; 49 static char event_data[100] = "The edges of a surface are lines."; 50 51 static const hci_hal_t *hal; 52 static int command_out_fd; 53 static int acl_out_fd; 54 static int acl_in_fd; 55 static int event_in_fd; 56 static int reentry_i = 0; 57 58 static semaphore_t *done; 59 static semaphore_t *reentry_semaphore; 60 61 static void expect_packet_synchronous(serial_data_type_t type, char *packet_data) { 62 int length = strlen(packet_data); 63 for (int i = 0; i < length; i++) { 64 uint8_t byte; 65 EXPECT_EQ((size_t)1, hal->read_data(type, &byte, 1)); 66 EXPECT_EQ(packet_data[i], byte); 67 } 68 69 hal->packet_finished(type); 70 } 71 72 STUB_FUNCTION(int, vendor_send_command, (vendor_opcode_t opcode, void *param)) 73 DURING(open) AT_CALL(0) { 74 EXPECT_EQ(VENDOR_OPEN_USERIAL, opcode); 75 ((int *)param)[CH_CMD] = command_out_fd; 76 ((int *)param)[CH_ACL_OUT] = acl_out_fd; 77 ((int *)param)[CH_ACL_IN] = acl_in_fd; 78 ((int *)param)[CH_EVT] = event_in_fd; 79 return 4; 80 } 81 82 DURING(close_fn) AT_CALL(0) { 83 EXPECT_EQ(VENDOR_CLOSE_USERIAL, opcode); 84 return 0; 85 } 86 87 UNEXPECTED_CALL; 88 return 0; 89 } 90 91 STUB_FUNCTION(void, data_ready_callback, (serial_data_type_t type)) 92 DURING(read_synchronous) { 93 AT_CALL(0) { 94 EXPECT_EQ(DATA_TYPE_ACL, type); 95 expect_packet_synchronous(type, acl_data); 96 semaphore_post(done); 97 return; 98 } 99 AT_CALL(1) { 100 EXPECT_EQ(DATA_TYPE_EVENT, type); 101 expect_packet_synchronous(type, event_data); 102 semaphore_post(done); 103 return; 104 } 105 } 106 107 DURING(read_async_reentry) { 108 EXPECT_EQ(DATA_TYPE_ACL, type); 109 110 uint8_t byte; 111 size_t bytes_read; 112 while ((bytes_read = hal->read_data(type, &byte, 1)) != 0) { 113 EXPECT_EQ(sample_data3[reentry_i], byte); 114 semaphore_post(reentry_semaphore); 115 reentry_i++; 116 if (reentry_i == (int)strlen(sample_data3)) { 117 hal->packet_finished(type); 118 return; 119 } 120 } 121 122 return; 123 } 124 125 UNEXPECTED_CALL; 126 } 127 128 static void reset_for(TEST_MODES_T next) { 129 RESET_CALL_COUNT(vendor_send_command); 130 RESET_CALL_COUNT(data_ready_callback); 131 CURRENT_TEST_MODE = next; 132 } 133 134 class HciHalMctTest : public AllocationTestHarness { 135 protected: 136 virtual void SetUp() { 137 AllocationTestHarness::SetUp(); 138 hal = hci_hal_mct_get_test_interface(&vendor); 139 vendor.send_command = vendor_send_command; 140 callbacks.data_ready = data_ready_callback; 141 142 socketpair(AF_LOCAL, SOCK_STREAM, 0, command_sockfd); 143 socketpair(AF_LOCAL, SOCK_STREAM, 0, event_sockfd); 144 socketpair(AF_LOCAL, SOCK_STREAM, 0, acl_in_sockfd); 145 socketpair(AF_LOCAL, SOCK_STREAM, 0, acl_out_sockfd); 146 command_out_fd = command_sockfd[0]; 147 acl_out_fd = acl_out_sockfd[0]; 148 acl_in_fd = acl_in_sockfd[0]; 149 event_in_fd = event_sockfd[0]; 150 151 done = semaphore_new(0); 152 thread = thread_new("hal_test"); 153 154 reset_for(init); 155 EXPECT_TRUE(hal->init(&callbacks, thread)); 156 157 reset_for(open); 158 EXPECT_TRUE(hal->open()); 159 EXPECT_CALL_COUNT(vendor_send_command, 1); 160 } 161 162 virtual void TearDown() { 163 reset_for(close_fn); 164 hal->close(); 165 EXPECT_CALL_COUNT(vendor_send_command, 1); 166 167 semaphore_free(done); 168 thread_free(thread); 169 AllocationTestHarness::TearDown(); 170 } 171 172 int command_sockfd[2]; 173 int event_sockfd[2]; 174 int acl_in_sockfd[2]; 175 int acl_out_sockfd[2]; 176 vendor_t vendor; 177 thread_t *thread; 178 hci_hal_callbacks_t callbacks; 179 }; 180 181 static void expect_socket_data(int fd, char *data) { 182 int length = strlen(data); 183 int i; 184 185 for (i = 0; i < length; i++) { 186 fd_set read_fds; 187 FD_ZERO(&read_fds); 188 FD_SET(fd, &read_fds); 189 select(fd + 1, &read_fds, NULL, NULL, NULL); 190 191 char byte; 192 read(fd, &byte, 1); 193 194 EXPECT_EQ(data[i], byte); 195 } 196 } 197 198 static void write_packet(int fd, char *data) { 199 write(fd, data, strlen(data)); 200 } 201 202 static void write_packet_reentry(int fd, char *data) { 203 int length = strlen(data); 204 for (int i = 0; i < length; i++) { 205 write(fd, &data[i], 1); 206 semaphore_wait(reentry_semaphore); 207 } 208 } 209 210 TEST_F(HciHalMctTest, test_transmit) { 211 reset_for(transmit); 212 213 // Send a command packet 214 hal->transmit_data(DATA_TYPE_COMMAND, (uint8_t *)(sample_data1), strlen(sample_data1)); 215 expect_socket_data(command_sockfd[1], sample_data1); 216 217 // Send an acl packet 218 hal->transmit_data(DATA_TYPE_ACL, (uint8_t *)(sample_data2), strlen(sample_data2)); 219 expect_socket_data(acl_out_sockfd[1], sample_data2); 220 } 221 222 TEST_F(HciHalMctTest, test_read_synchronous) { 223 reset_for(read_synchronous); 224 225 write_packet(acl_in_sockfd[1], acl_data); 226 semaphore_wait(done); 227 228 write_packet(event_sockfd[1], event_data); 229 semaphore_wait(done); 230 231 EXPECT_CALL_COUNT(data_ready_callback, 2); 232 } 233 234 TEST_F(HciHalMctTest, test_read_async_reentry) { 235 reset_for(read_async_reentry); 236 237 reentry_semaphore = semaphore_new(0); 238 reentry_i = 0; 239 240 write_packet_reentry(acl_in_sockfd[1], sample_data3); 241 242 // write_packet_reentry ensures the data has been received 243 semaphore_free(reentry_semaphore); 244 } 245