1f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// 2f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// Copyright 2015 The Android Open Source Project 3f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// 4f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// Licensed under the Apache License, Version 2.0 (the "License"); 5f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// you may not use this file except in compliance with the License. 6f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// You may obtain a copy of the License at 7f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// 8f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// http://www.apache.org/licenses/LICENSE-2.0 9f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// 10f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// Unless required by applicable law or agreed to in writing, software 11f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// distributed under the License is distributed on an "AS IS" BASIS, 12f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// See the License for the specific language governing permissions and 14f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// limitations under the License. 15f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng// 16f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 17f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng#define LOG_TAG "hci_transport" 18f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 19f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng#include "vendor_libs/test_vendor_lib/include/hci_transport.h" 20f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 21a7077ee9b7482708fa7272837a527f64bb470988Dennis Cheng#include "base/logging.h" 22bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng#include "base/bind.h" 23bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng#include "base/thread_task_runner_handle.h" 24f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 25a7077ee9b7482708fa7272837a527f64bb470988Dennis Chengextern "C" { 26f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng#include <sys/socket.h> 27a7077ee9b7482708fa7272837a527f64bb470988Dennis Cheng 28a7077ee9b7482708fa7272837a527f64bb470988Dennis Cheng#include "stack/include/hcidefs.h" 29a7077ee9b7482708fa7272837a527f64bb470988Dennis Cheng#include "osi/include/log.h" 30f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng} // extern "C" 31f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 32f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Chengnamespace test_vendor_lib { 33f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 34bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis ChengHciTransport::HciTransport() : weak_ptr_factory_(this) {} 35bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng 362fc0eba951081bddd15a3482f2189a9125dac48aDennis Chengvoid HciTransport::CloseHciFd() { 372d96c88025c80d4d7e0e341cfdbf278596340b66Dennis Cheng hci_fd_.reset(nullptr); 382fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng} 392fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng 402e00ba9b74536ce9a0d1adf78f92e6478563e49bDennis Chengvoid HciTransport::CloseVendorFd() { 412e00ba9b74536ce9a0d1adf78f92e6478563e49bDennis Cheng vendor_fd_.reset(nullptr); 422e00ba9b74536ce9a0d1adf78f92e6478563e49bDennis Cheng} 432e00ba9b74536ce9a0d1adf78f92e6478563e49bDennis Cheng 44f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Chengint HciTransport::GetHciFd() const { 452fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng return hci_fd_->get(); 46f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng} 47f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 48b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengint HciTransport::GetVendorFd() const { 492fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng return vendor_fd_->get(); 50f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng} 51f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 52b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengbool HciTransport::SetUp() { 532fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng int socketpair_fds[2]; 54f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng // TODO(dennischeng): Use SOCK_SEQPACKET here. 552fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng const int success = socketpair(AF_LOCAL, SOCK_STREAM, 0, socketpair_fds); 566f5f0540f1557c87349d9f3378a90979c175ed1dDennis Cheng if (success < 0) 572fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng return false; 582fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng hci_fd_.reset(new base::ScopedFD(socketpair_fds[0])); 592fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng vendor_fd_.reset(new base::ScopedFD(socketpair_fds[1])); 602fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng return true; 61f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng} 62f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 63b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid HciTransport::OnFileCanReadWithoutBlocking(int fd) { 648bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng CHECK(fd == GetVendorFd()); 652d96c88025c80d4d7e0e341cfdbf278596340b66Dennis Cheng LOG_INFO(LOG_TAG, "Event ready in HciTransport on fd: %d.", fd); 663c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng 672d96c88025c80d4d7e0e341cfdbf278596340b66Dennis Cheng const serial_data_type_t packet_type = packet_stream_.ReceivePacketType(fd); 683c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng switch (packet_type) { 693c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng case (DATA_TYPE_COMMAND): { 703c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng ReceiveReadyCommand(); 71b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng break; 723c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng } 733c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng 743c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng case (DATA_TYPE_ACL): { 753c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng LOG_INFO(LOG_TAG, "ACL data packets not currently supported."); 76b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng break; 773c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng } 783c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng 793c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng case (DATA_TYPE_SCO): { 803c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng LOG_INFO(LOG_TAG, "SCO data packets not currently supported."); 81b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng break; 823c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng } 833c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng 843c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng // TODO(dennischeng): Add debug level assert here. 853c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng default: { 86b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng LOG_INFO(LOG_TAG, "Error received an invalid packet type from the HCI."); 872fc0eba951081bddd15a3482f2189a9125dac48aDennis Cheng break; 883c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng } 893c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng } 903c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng} 913c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng 923c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Chengvoid HciTransport::ReceiveReadyCommand() const { 93f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng std::unique_ptr<CommandPacket> command = 942d96c88025c80d4d7e0e341cfdbf278596340b66Dennis Cheng packet_stream_.ReceiveCommand(GetVendorFd()); 953c0ea3e5a5aca269283854d8f2f584ad0699c951Dennis Cheng LOG_INFO(LOG_TAG, "Received command packet."); 96b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng command_handler_(std::move(command)); 97f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng} 98f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 99b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid HciTransport::RegisterCommandHandler( 100f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng std::function<void(std::unique_ptr<CommandPacket>)> callback) { 101b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Cheng command_handler_ = callback; 102f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng} 103f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 104b2d45eb7cbd4f2de5f0101915981a87392ccf625Dennis Chengvoid HciTransport::OnFileCanWriteWithoutBlocking(int fd) { 1058bb61fe28ac339276acf1b5b1616a6e56e2cccacDennis Cheng CHECK(fd == GetVendorFd()); 106bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng if (!outbound_events_.empty()) { 1077a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng base::TimeTicks current_time = base::TimeTicks::Now(); 1087a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng auto it = outbound_events_.begin(); 1097a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng // Check outbound events for events that can be sent, i.e. events with a 1107a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng // timestamp before the current time. Stop sending events when 1117a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng // |packet_stream_| fails writing. 1127a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng for (auto it = outbound_events_.begin(); it != outbound_events_.end();) { 1137a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng if ((*it)->GetTimeStamp() > current_time) { 1147a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng ++it; 1157a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng continue; 1167a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng } 1177a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng if (!packet_stream_.SendEvent((*it)->GetEvent(), fd)) 1187a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng return; 1197a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng it = outbound_events_.erase(it); 1207a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng } 121bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng } 122bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng} 123bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng 1247a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Chengvoid HciTransport::AddEventToOutboundEvents( 1257a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng std::unique_ptr<TimeStampedEvent> event) { 1267a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng outbound_events_.push_back(std::move(event)); 1277a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng} 1287a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng 1297a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Chengvoid HciTransport::PostEventResponse(std::unique_ptr<EventPacket> event) { 1302e00ba9b74536ce9a0d1adf78f92e6478563e49bDennis Cheng AddEventToOutboundEvents( 1312e00ba9b74536ce9a0d1adf78f92e6478563e49bDennis Cheng std::make_unique<TimeStampedEvent>(std::move(event))); 132bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng} 133bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng 134bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Chengvoid HciTransport::PostDelayedEventResponse(std::unique_ptr<EventPacket> event, 135bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng base::TimeDelta delay) { 1367a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng // TODO(dennischeng): When it becomes available for MessageLoopForIO, use the 1377a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng // thread's task runner to post |PostEventResponse| as a delayed task, being 1387a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng // sure to CHECK the appropriate task runner attributes using 1397a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng // base::ThreadTaskRunnerHandle. 1407a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng 1417a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng // The system does not support high resolution timing and the clock could be 1427a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng // as coarse as ~15.6 ms so the event is sent without a delay to avoid 1437a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng // inconsistent event responses. 1447a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng if (!base::TimeTicks::IsHighResolution()) { 1457a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng LOG_INFO(LOG_TAG, 1467a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng "System does not support high resolution timing. Sending event " 1477a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng "without delay."); 1487a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng PostEventResponse(std::move(event)); 1497a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng } 150bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng 151bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng LOG_INFO(LOG_TAG, "Posting event response with delay of %lld ms.", 152bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng delay.InMilliseconds()); 153bf7db3143fda4dc8391c92ec25dc93b9725ec225Dennis Cheng 1547a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng AddEventToOutboundEvents( 1557a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng std::make_unique<TimeStampedEvent>(std::move(event), delay)); 1567a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng} 1577a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng 1587a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis ChengHciTransport::TimeStampedEvent::TimeStampedEvent( 1597a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng std::unique_ptr<EventPacket> event, base::TimeDelta delay) 1607a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng : event_(std::move(event)), time_stamp_(base::TimeTicks::Now() + delay) {} 1617a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng 1627a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis ChengHciTransport::TimeStampedEvent::TimeStampedEvent( 1637a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng std::unique_ptr<EventPacket> event) 1647a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng : event_(std::move(event)), time_stamp_(base::TimeTicks::UnixEpoch()) {} 1657a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng 1667a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Chengconst base::TimeTicks& HciTransport::TimeStampedEvent::GetTimeStamp() const { 1677a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng return time_stamp_; 1687a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng} 1697a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng 1707a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Chengconst EventPacket& HciTransport::TimeStampedEvent::GetEvent() { 1717a87e719982e874c1d23e106a4dbc8dd2ede97bdDennis Cheng return *(event_.get()); 172f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng} 173f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng 174f3b1820e1676261886a6537e1f6abac6a35ed6d4Dennis Cheng} // namespace test_vendor_lib 175