1 /*
2  * Copyright 2018 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 #include "hci_socket_device.h"
18 
19 #include <fcntl.h>
20 #include <netinet/in.h>
21 #include <sys/socket.h>
22 
23 #include "model/setup/device_boutique.h"
24 #include "os/log.h"
25 
26 using std::vector;
27 
28 namespace test_vendor_lib {
29 
HciSocketDevice(int file_descriptor)30 HciSocketDevice::HciSocketDevice(int file_descriptor) : socket_file_descriptor_(file_descriptor) {
31   advertising_interval_ms_ = std::chrono::milliseconds(1000);
32 
33   page_scan_delay_ms_ = std::chrono::milliseconds(600);
34 
35   properties_.SetPageScanRepetitionMode(0);
36   properties_.SetClassOfDevice(0x600420);
37   properties_.SetExtendedInquiryData({
38       16,  // length
39       9,   // Type: Device Name
40       'g',
41       'D',
42       'e',
43       'v',
44       'i',
45       'c',
46       'e',
47       '-',
48       'h',
49       'c',
50       'i',
51       '_',
52       'n',
53       'e',
54       't',
55   });
56   properties_.SetName({
57       'g',
58       'D',
59       'e',
60       'v',
61       'i',
62       'c',
63       'e',
64       '-',
65       'H',
66       'C',
67       'I',
68       '_',
69       'N',
70       'e',
71       't',
72   });
73 
74   h4_ = H4Packetizer(
75       socket_file_descriptor_,
76       [this](const std::vector<uint8_t>& raw_command) {
77         std::shared_ptr<std::vector<uint8_t>> packet_copy = std::make_shared<std::vector<uint8_t>>(raw_command);
78         HandleCommand(packet_copy);
79       },
80       [](const std::vector<uint8_t>&) {
81         LOG_ALWAYS_FATAL("Unexpected Event in HciSocketDevice!");
82       },
83       [this](const std::vector<uint8_t>& raw_acl) {
84         std::shared_ptr<std::vector<uint8_t>> packet_copy = std::make_shared<std::vector<uint8_t>>(raw_acl);
85         HandleAcl(packet_copy);
86       },
87       [this](const std::vector<uint8_t>& raw_sco) {
88         std::shared_ptr<std::vector<uint8_t>> packet_copy = std::make_shared<std::vector<uint8_t>>(raw_sco);
89         HandleSco(packet_copy);
90       },
91       [this](const std::vector<uint8_t>& raw_iso) {
92         std::shared_ptr<std::vector<uint8_t>> packet_copy =
93             std::make_shared<std::vector<uint8_t>>(raw_iso);
94         HandleIso(packet_copy);
95       },
96       [this]() {
97         LOG_INFO("HCI socket device disconnected");
98         socket_file_descriptor_ = -1;
99         close_callback_();
100       });
101 
102   RegisterEventChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
103     SendHci(PacketType::EVENT, packet);
104   });
105   RegisterAclChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
106     SendHci(PacketType::ACL, packet);
107   });
108   RegisterScoChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
109     SendHci(PacketType::SCO, packet);
110   });
111   RegisterIsoChannel([this](std::shared_ptr<std::vector<uint8_t>> packet) {
112     SendHci(PacketType::ISO, packet);
113   });
114 }
115 
TimerTick()116 void HciSocketDevice::TimerTick() {
117   h4_.OnDataReady(socket_file_descriptor_);
118   DualModeController::TimerTick();
119 }
120 
SendHci(PacketType packet_type,const std::shared_ptr<std::vector<uint8_t>> packet)121 void HciSocketDevice::SendHci(
122     PacketType packet_type,
123     const std::shared_ptr<std::vector<uint8_t>> packet) {
124   if (socket_file_descriptor_ == -1) {
125     LOG_INFO("Closed socket. Dropping packet of type %d",
126              static_cast<int>(packet_type));
127     return;
128   }
129   uint8_t type = static_cast<uint8_t>(packet_type);
130   h4_.Send(type, packet->data(), packet->size());
131 }
132 
RegisterCloseCallback(std::function<void ()> close_callback)133 void HciSocketDevice::RegisterCloseCallback(std::function<void()> close_callback) {
134   if (socket_file_descriptor_ != -1) {
135     close_callback_ = close_callback;
136   }
137 }
138 
139 }  // namespace test_vendor_lib
140