1 // 2 // Copyright 2017 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #define LOG_TAG "bt_h4_unittest" 18 19 #include "mct_protocol.h" 20 #include <gmock/gmock.h> 21 #include <gtest/gtest.h> 22 #include <condition_variable> 23 #include <cstdint> 24 #include <cstring> 25 #include <mutex> 26 #include <vector> 27 28 #include <log/log.h> 29 #include <sys/socket.h> 30 #include <sys/types.h> 31 #include <unistd.h> 32 33 namespace android { 34 namespace hardware { 35 namespace bluetooth { 36 namespace V1_0 { 37 namespace implementation { 38 39 using ::testing::Eq; 40 using hci::MctProtocol; 41 42 static char sample_data1[100] = "A point is that which has no part."; 43 static char sample_data2[100] = "A line is breadthless length."; 44 static char acl_data[100] = 45 "A straight line is a line which lies evenly with the points on itself."; 46 static char event_data[100] = "The edges of a surface are lines."; 47 48 MATCHER_P3(HidlVecMatches, preamble, preamble_length, payload, "") { 49 size_t length = strlen(payload) + preamble_length; 50 if (length != arg.size()) { 51 return false; 52 } 53 54 if (memcmp(preamble, arg.data(), preamble_length) != 0) { 55 return false; 56 } 57 58 return memcmp(payload, arg.data() + preamble_length, 59 length - preamble_length) == 0; 60 }; 61 62 ACTION_P2(Notify, mutex, condition) { 63 ALOGD("%s", __func__); 64 std::unique_lock<std::mutex> lock(*mutex); 65 condition->notify_one(); 66 } 67 68 class MctProtocolTest : public ::testing::Test { 69 protected: 70 void SetUp() override { 71 ALOGD("%s", __func__); 72 73 int mct_fds[CH_MAX]; 74 MakeFakeUartFd(CH_CMD, mct_fds, fake_uart_); 75 MakeFakeUartFd(CH_EVT, mct_fds, fake_uart_); 76 MakeFakeUartFd(CH_ACL_IN, mct_fds, fake_uart_); 77 MakeFakeUartFd(CH_ACL_OUT, mct_fds, fake_uart_); 78 79 MctProtocol* mct_hci = new MctProtocol(mct_fds, event_cb_.AsStdFunction(), 80 acl_cb_.AsStdFunction()); 81 fd_watcher_.WatchFdForNonBlockingReads( 82 mct_fds[CH_EVT], [mct_hci](int fd) { mct_hci->OnEventDataReady(fd); }); 83 fd_watcher_.WatchFdForNonBlockingReads( 84 mct_fds[CH_ACL_IN], [mct_hci](int fd) { mct_hci->OnAclDataReady(fd); }); 85 protocol_ = mct_hci; 86 } 87 88 void MakeFakeUartFd(int index, int* host_side, int* controller_side) { 89 int sockfd[2]; 90 socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd); 91 host_side[index] = sockfd[0]; 92 controller_side[index] = sockfd[1]; 93 } 94 95 void TearDown() override { fd_watcher_.StopWatchingFileDescriptors(); } 96 97 void SendAndReadUartOutbound(uint8_t type, char* data, int outbound_fd) { 98 ALOGD("%s sending", __func__); 99 int data_length = strlen(data); 100 protocol_->Send(type, (uint8_t*)data, data_length); 101 102 ALOGD("%s reading", __func__); 103 int i; 104 for (i = 0; i < data_length; i++) { 105 fd_set read_fds; 106 FD_ZERO(&read_fds); 107 FD_SET(outbound_fd, &read_fds); 108 TEMP_FAILURE_RETRY(select(outbound_fd + 1, &read_fds, NULL, NULL, NULL)); 109 110 char byte; 111 TEMP_FAILURE_RETRY(read(outbound_fd, &byte, 1)); 112 113 EXPECT_EQ(data[i], byte); 114 } 115 116 EXPECT_EQ(i, data_length); 117 } 118 119 void WriteAndExpectInboundAclData(char* payload) { 120 // handle[2] + size[2] 121 char preamble[4] = {19, 92, 0, 0}; 122 int length = strlen(payload); 123 preamble[2] = length & 0xFF; 124 preamble[3] = (length >> 8) & 0xFF; 125 126 ALOGD("%s writing", __func__); 127 TEMP_FAILURE_RETRY( 128 write(fake_uart_[CH_ACL_IN], preamble, sizeof(preamble))); 129 TEMP_FAILURE_RETRY(write(fake_uart_[CH_ACL_IN], payload, strlen(payload))); 130 131 ALOGD("%s waiting", __func__); 132 std::mutex mutex; 133 std::condition_variable done; 134 EXPECT_CALL(acl_cb_, 135 Call(HidlVecMatches(preamble, sizeof(preamble), payload))) 136 .WillOnce(Notify(&mutex, &done)); 137 138 // Fail if it takes longer than 100 ms. 139 auto timeout_time = 140 std::chrono::steady_clock::now() + std::chrono::milliseconds(100); 141 { 142 std::unique_lock<std::mutex> lock(mutex); 143 done.wait_until(lock, timeout_time); 144 } 145 } 146 147 void WriteAndExpectInboundEvent(char* payload) { 148 // event_code[1] + size[1] 149 char preamble[2] = {9, 0}; 150 preamble[1] = strlen(payload) & 0xFF; 151 152 ALOGD("%s writing", __func__); 153 TEMP_FAILURE_RETRY(write(fake_uart_[CH_EVT], preamble, sizeof(preamble))); 154 TEMP_FAILURE_RETRY(write(fake_uart_[CH_EVT], payload, strlen(payload))); 155 156 ALOGD("%s waiting", __func__); 157 std::mutex mutex; 158 std::condition_variable done; 159 EXPECT_CALL(event_cb_, 160 Call(HidlVecMatches(preamble, sizeof(preamble), payload))) 161 .WillOnce(Notify(&mutex, &done)); 162 163 // Fail if it takes longer than 100 ms. 164 auto timeout_time = 165 std::chrono::steady_clock::now() + std::chrono::milliseconds(100); 166 { 167 std::unique_lock<std::mutex> lock(mutex); 168 done.wait_until(lock, timeout_time); 169 } 170 } 171 172 testing::MockFunction<void(const hidl_vec<uint8_t>&)> event_cb_; 173 testing::MockFunction<void(const hidl_vec<uint8_t>&)> acl_cb_; 174 async::AsyncFdWatcher fd_watcher_; 175 MctProtocol* protocol_; 176 int fake_uart_[CH_MAX]; 177 }; 178 179 // Test sending data sends correct data onto the UART 180 TEST_F(MctProtocolTest, TestSends) { 181 SendAndReadUartOutbound(HCI_PACKET_TYPE_COMMAND, sample_data1, 182 fake_uart_[CH_CMD]); 183 SendAndReadUartOutbound(HCI_PACKET_TYPE_ACL_DATA, sample_data2, 184 fake_uart_[CH_ACL_OUT]); 185 } 186 187 // Ensure we properly parse data coming from the UART 188 TEST_F(MctProtocolTest, TestReads) { 189 WriteAndExpectInboundAclData(acl_data); 190 WriteAndExpectInboundEvent(event_data); 191 } 192 193 } // namespace implementation 194 } // namespace V1_0 195 } // namespace bluetooth 196 } // namespace hardware 197 } // namespace android 198