1 /*
2 * Copyright 2021 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 "btaa/hci_processor.h"
18
19 #include "os/log.h"
20
21 namespace bluetooth {
22 namespace activity_attribution {
23
match_handle_with_address(uint16_t connection_handle,hci::Address & address)24 void DeviceParser::match_handle_with_address(uint16_t connection_handle, hci::Address& address) {
25 if (connection_handle && !address.IsEmpty()) {
26 connection_lookup_table_[connection_handle] = address;
27 } else if (connection_handle) {
28 if (connection_lookup_table_.find(connection_handle) != connection_lookup_table_.end()) {
29 address = connection_lookup_table_[connection_handle];
30 }
31 }
32 }
33
process_le_event(std::vector<BtaaHciPacket> & btaa_hci_packets,int16_t byte_count,hci::EventView & event)34 void HciProcessor::process_le_event(
35 std::vector<BtaaHciPacket>& btaa_hci_packets, int16_t byte_count, hci::EventView& event) {
36 uint16_t connection_handle_value = 0;
37 hci::Address address_value;
38
39 auto le_packet_view = hci::LeMetaEventView::Create(event);
40 if (!le_packet_view.IsValid()) {
41 return;
42 }
43
44 auto subevent_code = le_packet_view.GetSubeventCode();
45 auto le_event_info = lookup_le_event(subevent_code);
46
47 if (le_event_info.activity != Activity::UNKNOWN) {
48 // lookup_le_event returns all simple classic event which does not require additional processing.
49 if (le_event_info.connection_handle_pos) {
50 auto connection_handle_it = event.begin() + le_event_info.connection_handle_pos;
51 connection_handle_value = connection_handle_it.extract<uint16_t>();
52 }
53 if (le_event_info.address_pos) {
54 auto address_value_it = event.begin() + le_event_info.address_pos;
55 address_value = address_value_it.extract<hci::Address>();
56 }
57 device_parser_.match_handle_with_address(connection_handle_value, address_value);
58 btaa_hci_packets.push_back(BtaaHciPacket(le_event_info.activity, address_value, byte_count));
59 }
60 }
61
process_special_event(std::vector<BtaaHciPacket> & btaa_hci_packets,hci::EventCode event_code,uint16_t byte_count,hci::EventView & event)62 void HciProcessor::process_special_event(
63 std::vector<BtaaHciPacket>& btaa_hci_packets,
64 hci::EventCode event_code,
65 uint16_t byte_count,
66 hci::EventView& event) {
67 uint16_t avg_byte_count;
68 hci::Address address_value;
69
70 switch (event_code) {
71 case hci::EventCode::INQUIRY_RESULT:
72 case hci::EventCode::INQUIRY_RESULT_WITH_RSSI: {
73 auto packet_view = hci::InquiryResultView::Create(event);
74 if (!packet_view.IsValid()) {
75 return;
76 }
77 auto inquiry_results = packet_view.GetInquiryResults();
78 avg_byte_count = byte_count / inquiry_results.size();
79 for (auto& inquiry_result : inquiry_results) {
80 btaa_hci_packets.push_back(BtaaHciPacket(Activity::SCAN, inquiry_result.bd_addr_, avg_byte_count));
81 }
82 } break;
83
84 case hci::EventCode::NUMBER_OF_COMPLETED_PACKETS: {
85 auto packet_view = hci::NumberOfCompletedPacketsView::Create(event);
86 if (!packet_view.IsValid()) {
87 return;
88 }
89 auto completed_packets = packet_view.GetCompletedPackets();
90 avg_byte_count = byte_count / completed_packets.size();
91 for (auto& completed_packet : completed_packets) {
92 device_parser_.match_handle_with_address(completed_packet.connection_handle_, address_value);
93 btaa_hci_packets.push_back(BtaaHciPacket(Activity::CONNECT, address_value, avg_byte_count));
94 }
95 } break;
96
97 case hci::EventCode::RETURN_LINK_KEYS: {
98 auto packet_view = hci::ReturnLinkKeysView::Create(event);
99 if (!packet_view.IsValid()) {
100 return;
101 }
102 auto keys_and_addresses = packet_view.GetKeys();
103 avg_byte_count = byte_count / keys_and_addresses.size();
104 for (auto& key_and_address : keys_and_addresses) {
105 btaa_hci_packets.push_back(BtaaHciPacket(Activity::CONNECT, key_and_address.address_, avg_byte_count));
106 }
107 } break;
108
109 default: {
110 btaa_hci_packets.push_back(BtaaHciPacket(Activity::UNKNOWN, address_value, byte_count));
111 } break;
112 }
113 }
114
process_command(std::vector<BtaaHciPacket> & btaa_hci_packets,packet::PacketView<packet::kLittleEndian> & packet_view,uint16_t byte_count)115 void HciProcessor::process_command(
116 std::vector<BtaaHciPacket>& btaa_hci_packets,
117 packet::PacketView<packet::kLittleEndian>& packet_view,
118 uint16_t byte_count) {
119 hci::CommandView command = hci::CommandView::Create(packet_view);
120 if (!command.IsValid()) {
121 return;
122 }
123
124 uint16_t connection_handle_value = 0;
125 hci::Address address_value;
126 auto opcode = command.GetOpCode();
127 auto cmd_info = lookup_cmd(opcode);
128
129 if (cmd_info.connection_handle_pos) {
130 auto connection_handle_it = command.begin() + cmd_info.connection_handle_pos;
131 connection_handle_value = connection_handle_it.extract<uint16_t>();
132 }
133 if (cmd_info.address_pos) {
134 auto address_value_it = command.begin() + cmd_info.address_pos;
135 address_value = address_value_it.extract<hci::Address>();
136 }
137 device_parser_.match_handle_with_address(connection_handle_value, address_value);
138 pending_command_.btaa_hci_packet = BtaaHciPacket(cmd_info.activity, address_value, byte_count);
139
140 pending_command_.opcode = opcode;
141 }
142
process_event(std::vector<BtaaHciPacket> & btaa_hci_packets,packet::PacketView<packet::kLittleEndian> & packet_view,uint16_t byte_count)143 void HciProcessor::process_event(
144 std::vector<BtaaHciPacket>& btaa_hci_packets,
145 packet::PacketView<packet::kLittleEndian>& packet_view,
146 uint16_t byte_count) {
147 hci::EventView event = hci::EventView::Create(packet_view);
148 if (!event.IsValid()) {
149 return;
150 }
151
152 uint16_t connection_handle_value = 0;
153 hci::Address address_value;
154 auto event_code = event.GetEventCode();
155 auto event_info = lookup_event(event_code);
156
157 if (event_info.activity != Activity::UNKNOWN) {
158 // lookup_event returns all simple classic event which does not require additional processing.
159 if (event_info.connection_handle_pos) {
160 auto connection_handle_it = event.begin() + event_info.connection_handle_pos;
161 connection_handle_value = connection_handle_it.extract<uint16_t>();
162 }
163 if (event_info.address_pos) {
164 auto address_value_it = event.begin() + event_info.address_pos;
165 address_value = address_value_it.extract<hci::Address>();
166 }
167 device_parser_.match_handle_with_address(connection_handle_value, address_value);
168 btaa_hci_packets.push_back(BtaaHciPacket(event_info.activity, address_value, byte_count));
169 } else {
170 // The event requires additional processing.
171 switch (event_code) {
172 case hci::EventCode::COMMAND_COMPLETE: {
173 auto packet_view = hci::CommandCompleteView::Create(event);
174 if (packet_view.IsValid() && packet_view.GetCommandOpCode() == pending_command_.opcode) {
175 pending_command_.btaa_hci_packet.byte_count += byte_count;
176 btaa_hci_packets.push_back(std::move(pending_command_.btaa_hci_packet));
177 } else {
178 btaa_hci_packets.push_back(BtaaHciPacket(Activity::UNKNOWN, address_value, byte_count));
179 }
180 } break;
181 case hci::EventCode::COMMAND_STATUS: {
182 auto packet_view = hci::CommandStatusView::Create(event);
183 if (packet_view.IsValid() && packet_view.GetCommandOpCode() == pending_command_.opcode) {
184 pending_command_.btaa_hci_packet.byte_count += byte_count;
185 btaa_hci_packets.push_back(std::move(pending_command_.btaa_hci_packet));
186 } else {
187 btaa_hci_packets.push_back(BtaaHciPacket(Activity::UNKNOWN, address_value, byte_count));
188 }
189 break;
190 }
191 case hci::EventCode::LE_META_EVENT:
192 process_le_event(btaa_hci_packets, byte_count, event);
193 break;
194 case hci::EventCode::VENDOR_SPECIFIC:
195 btaa_hci_packets.push_back(BtaaHciPacket(Activity::VENDOR, address_value, byte_count));
196 break;
197 default:
198 process_special_event(btaa_hci_packets, event_code, byte_count, event);
199 break;
200 }
201 }
202 }
203
process_acl(std::vector<BtaaHciPacket> & btaa_hci_packets,packet::PacketView<packet::kLittleEndian> & packet_view,uint16_t byte_count)204 void HciProcessor::process_acl(
205 std::vector<BtaaHciPacket>& btaa_hci_packets,
206 packet::PacketView<packet::kLittleEndian>& packet_view,
207 uint16_t byte_count) {
208 hci::AclView acl = hci::AclView::Create(packet_view);
209 auto connection_handle = acl.begin();
210 // Connection handle is extracted from the 12 least significant bit.
211 uint16_t connection_handle_value = connection_handle.extract<uint16_t>() & 0xfff;
212 hci::Address address_value;
213 device_parser_.match_handle_with_address(connection_handle_value, address_value);
214 btaa_hci_packets.push_back(BtaaHciPacket(Activity::ACL, address_value, byte_count));
215 }
216
process_sco(std::vector<BtaaHciPacket> & btaa_hci_packets,packet::PacketView<packet::kLittleEndian> & packet_view,uint16_t byte_count)217 void HciProcessor::process_sco(
218 std::vector<BtaaHciPacket>& btaa_hci_packets,
219 packet::PacketView<packet::kLittleEndian>& packet_view,
220 uint16_t byte_count) {
221 hci::ScoView sco = hci::ScoView::Create(packet_view);
222 auto connection_handle = sco.begin();
223 // Connection handle is extracted from the 12 least significant bit.
224 uint16_t connection_handle_value = connection_handle.extract<uint16_t>() & 0xfff;
225 hci::Address address_value;
226 device_parser_.match_handle_with_address(connection_handle_value, address_value);
227 btaa_hci_packets.push_back(BtaaHciPacket(Activity::HFP, address_value, byte_count));
228 }
229
process_iso(std::vector<BtaaHciPacket> & btaa_hci_packets,packet::PacketView<packet::kLittleEndian> & packet_view,uint16_t byte_count)230 void HciProcessor::process_iso(
231 std::vector<BtaaHciPacket>& btaa_hci_packets,
232 packet::PacketView<packet::kLittleEndian>& packet_view,
233 uint16_t byte_count) {
234 hci::IsoView iso = hci::IsoView::Create(packet_view);
235 auto connection_handle = iso.begin();
236 // Connection handle is extracted from the 12 least significant bit.
237 uint16_t connection_handle_value = connection_handle.extract<uint16_t>() & 0xfff;
238 hci::Address address_value;
239 device_parser_.match_handle_with_address(connection_handle_value, address_value);
240 btaa_hci_packets.push_back(BtaaHciPacket(Activity::ISO, address_value, byte_count));
241 }
242
OnHciPacket(hal::HciPacket packet,hal::SnoopLogger::PacketType type,uint16_t length)243 std::vector<BtaaHciPacket> HciProcessor::OnHciPacket(
244 hal::HciPacket packet, hal::SnoopLogger::PacketType type, uint16_t length) {
245 std::vector<BtaaHciPacket> btaa_hci_packets;
246 auto packet_view = packet::PacketView<packet::kLittleEndian>(std::make_shared<std::vector<uint8_t>>(packet));
247 switch (type) {
248 case hal::SnoopLogger::PacketType::CMD:
249 process_command(btaa_hci_packets, packet_view, length);
250 break;
251 case hal::SnoopLogger::PacketType::EVT:
252 process_event(btaa_hci_packets, packet_view, length);
253 break;
254 case hal::SnoopLogger::PacketType::ACL:
255 process_acl(btaa_hci_packets, packet_view, length);
256 break;
257 case hal::SnoopLogger::PacketType::SCO:
258 process_sco(btaa_hci_packets, packet_view, length);
259 break;
260 case hal::SnoopLogger::PacketType::ISO:
261 process_iso(btaa_hci_packets, packet_view, length);
262 break;
263 }
264 return btaa_hci_packets;
265 }
266
267 } // namespace activity_attribution
268 } // namespace bluetooth
269