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