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/cmd_evt_classification.h"
18 
19 namespace bluetooth {
20 namespace activity_attribution {
21 
lookup_cmd(hci::OpCode opcode)22 CmdEvtActivityClassification lookup_cmd(hci::OpCode opcode) {
23   CmdEvtActivityClassification classification = {};
24   switch (opcode) {
25     case hci::OpCode::INQUIRY:
26     case hci::OpCode::INQUIRY_CANCEL:
27     case hci::OpCode::PERIODIC_INQUIRY_MODE:
28     case hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE:
29       classification = {.activity = Activity::SCAN, .connection_handle_pos = 0, .address_pos = 0};
30       break;
31 
32     case hci::OpCode::CREATE_CONNECTION:
33     case hci::OpCode::CREATE_CONNECTION_CANCEL:
34     case hci::OpCode::ACCEPT_CONNECTION_REQUEST:
35     case hci::OpCode::LINK_KEY_REQUEST_REPLY:
36     case hci::OpCode::LINK_KEY_REQUEST_NEGATIVE_REPLY:
37     case hci::OpCode::PIN_CODE_REQUEST_REPLY:
38     case hci::OpCode::PIN_CODE_REQUEST_NEGATIVE_REPLY:
39     case hci::OpCode::REJECT_CONNECTION_REQUEST:
40     case hci::OpCode::REMOTE_NAME_REQUEST:
41     case hci::OpCode::REMOTE_NAME_REQUEST_CANCEL:
42     case hci::OpCode::ACCEPT_SYNCHRONOUS_CONNECTION:
43     case hci::OpCode::REJECT_SYNCHRONOUS_CONNECTION:
44     case hci::OpCode::IO_CAPABILITY_REQUEST_REPLY:
45     case hci::OpCode::USER_CONFIRMATION_REQUEST_REPLY:
46     case hci::OpCode::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY:
47     case hci::OpCode::USER_PASSKEY_REQUEST_REPLY:
48     case hci::OpCode::USER_PASSKEY_REQUEST_NEGATIVE_REPLY:
49     case hci::OpCode::REMOTE_OOB_DATA_REQUEST_REPLY:
50     case hci::OpCode::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY:
51     case hci::OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY:
52     case hci::OpCode::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION:
53     case hci::OpCode::REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY:
54     case hci::OpCode::SWITCH_ROLE:
55     case hci::OpCode::READ_STORED_LINK_KEY:
56       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 0, .address_pos = 3};
57       break;
58 
59     case hci::OpCode::CENTRAL_LINK_KEY:
60     case hci::OpCode::READ_DEFAULT_LINK_POLICY_SETTINGS:
61     case hci::OpCode::WRITE_DEFAULT_LINK_POLICY_SETTINGS:
62     case hci::OpCode::WRITE_SCAN_ENABLE:
63     case hci::OpCode::READ_PAGE_SCAN_ACTIVITY:
64     case hci::OpCode::WRITE_PAGE_SCAN_ACTIVITY:
65     case hci::OpCode::READ_PAGE_SCAN_TYPE:
66     case hci::OpCode::WRITE_PAGE_SCAN_TYPE:
67     case hci::OpCode::READ_SIMPLE_PAIRING_MODE:
68     case hci::OpCode::WRITE_SIMPLE_PAIRING_MODE:
69     case hci::OpCode::READ_SCAN_ENABLE:
70     case hci::OpCode::LE_CREATE_CONNECTION_CANCEL:
71     case hci::OpCode::LE_READ_CONNECT_LIST_SIZE:
72     case hci::OpCode::LE_CLEAR_CONNECT_LIST:
73     case hci::OpCode::SEND_KEYPRESS_NOTIFICATION:
74     case hci::OpCode::LE_CLEAR_RESOLVING_LIST:
75     case hci::OpCode::LE_READ_RESOLVING_LIST_SIZE:
76     case hci::OpCode::LE_SET_HOST_CHANNEL_CLASSIFICATION:
77       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 0, .address_pos = 0};
78       break;
79 
80     case hci::OpCode::DISCONNECT:
81     case hci::OpCode::CHANGE_CONNECTION_PACKET_TYPE:
82     case hci::OpCode::AUTHENTICATION_REQUESTED:
83     case hci::OpCode::SET_CONNECTION_ENCRYPTION:
84     case hci::OpCode::CHANGE_CONNECTION_LINK_KEY:
85     case hci::OpCode::READ_REMOTE_SUPPORTED_FEATURES:
86     case hci::OpCode::READ_REMOTE_EXTENDED_FEATURES:
87     case hci::OpCode::READ_REMOTE_VERSION_INFORMATION:
88     case hci::OpCode::READ_CLOCK_OFFSET:
89     case hci::OpCode::READ_LMP_HANDLE:
90     case hci::OpCode::SETUP_SYNCHRONOUS_CONNECTION:
91     case hci::OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION:
92     case hci::OpCode::HOLD_MODE:
93     case hci::OpCode::SNIFF_MODE:
94     case hci::OpCode::EXIT_SNIFF_MODE:
95     case hci::OpCode::QOS_SETUP:
96     case hci::OpCode::ROLE_DISCOVERY:
97     case hci::OpCode::READ_LINK_POLICY_SETTINGS:
98     case hci::OpCode::WRITE_LINK_POLICY_SETTINGS:
99     case hci::OpCode::FLOW_SPECIFICATION:
100     case hci::OpCode::SNIFF_SUBRATING:
101     case hci::OpCode::FLUSH:
102     case hci::OpCode::READ_AUTOMATIC_FLUSH_TIMEOUT:
103     case hci::OpCode::WRITE_AUTOMATIC_FLUSH_TIMEOUT:
104     case hci::OpCode::READ_LINK_SUPERVISION_TIMEOUT:
105     case hci::OpCode::WRITE_LINK_SUPERVISION_TIMEOUT:
106     case hci::OpCode::REFRESH_ENCRYPTION_KEY:
107     case hci::OpCode::READ_FAILED_CONTACT_COUNTER:
108     case hci::OpCode::RESET_FAILED_CONTACT_COUNTER:
109     case hci::OpCode::READ_LINK_QUALITY:
110     case hci::OpCode::READ_RSSI:
111     case hci::OpCode::READ_AFH_CHANNEL_MAP:
112     case hci::OpCode::READ_CLOCK:
113     case hci::OpCode::READ_ENCRYPTION_KEY_SIZE:
114     // READ_LOOPBACK_MODE = 0x1801,
115     // WRITE_LOOPBACK_MODE = 0x1802,
116     // ENABLE_DEVICE_UNDER_TEST_MODE = 0x1803,
117     // WRITE_SIMPLE_PAIRING_DEBUG_MODE = 0x1804,
118     // WRITE_SECURE_CONNECTIONS_TEST_MODE = 0x180a,
119     case hci::OpCode::ENHANCED_FLUSH:
120     case hci::OpCode::LE_CONNECTION_UPDATE:
121     case hci::OpCode::LE_START_ENCRYPTION:
122     case hci::OpCode::LE_LONG_TERM_KEY_REQUEST_REPLY:
123     case hci::OpCode::LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY:
124     case hci::OpCode::LE_READ_PHY:
125     case hci::OpCode::LE_SET_PHY:
126     case hci::OpCode::LE_READ_REMOTE_FEATURES:
127     case hci::OpCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY:
128     case hci::OpCode::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY:
129     case hci::OpCode::LE_SET_DATA_LENGTH:
130       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 3, .address_pos = 0};
131       break;
132 
133     case hci::OpCode::SET_EVENT_MASK:
134     case hci::OpCode::RESET:
135     case hci::OpCode::SET_EVENT_FILTER:
136     case hci::OpCode::READ_PIN_TYPE:
137     case hci::OpCode::WRITE_PIN_TYPE:
138     case hci::OpCode::WRITE_LOCAL_NAME:
139     case hci::OpCode::READ_LOCAL_NAME:
140     case hci::OpCode::READ_CONNECTION_ACCEPT_TIMEOUT:
141     case hci::OpCode::WRITE_CONNECTION_ACCEPT_TIMEOUT:
142     case hci::OpCode::READ_PAGE_TIMEOUT:
143     case hci::OpCode::WRITE_PAGE_TIMEOUT:
144     case hci::OpCode::READ_AUTHENTICATION_ENABLE:
145     case hci::OpCode::WRITE_AUTHENTICATION_ENABLE:
146     case hci::OpCode::READ_CLASS_OF_DEVICE:
147     case hci::OpCode::WRITE_CLASS_OF_DEVICE:
148     case hci::OpCode::READ_VOICE_SETTING:
149     case hci::OpCode::WRITE_VOICE_SETTING:
150     case hci::OpCode::READ_NUM_BROADCAST_RETRANSMITS:
151     case hci::OpCode::WRITE_NUM_BROADCAST_RETRANSMITS:
152     case hci::OpCode::READ_HOLD_MODE_ACTIVITY:
153     case hci::OpCode::WRITE_HOLD_MODE_ACTIVITY:
154     case hci::OpCode::READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE:
155     case hci::OpCode::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE:
156     case hci::OpCode::SET_CONTROLLER_TO_HOST_FLOW_CONTROL:
157     case hci::OpCode::HOST_BUFFER_SIZE:
158     case hci::OpCode::HOST_NUM_COMPLETED_PACKETS:
159     case hci::OpCode::READ_NUMBER_OF_SUPPORTED_IAC:
160     case hci::OpCode::READ_CURRENT_IAC_LAP:
161     case hci::OpCode::WRITE_CURRENT_IAC_LAP:
162     case hci::OpCode::SET_AFH_HOST_CHANNEL_CLASSIFICATION:
163     case hci::OpCode::READ_AFH_CHANNEL_ASSESSMENT_MODE:
164     case hci::OpCode::WRITE_AFH_CHANNEL_ASSESSMENT_MODE:
165     case hci::OpCode::READ_LE_HOST_SUPPORT:
166     case hci::OpCode::WRITE_LE_HOST_SUPPORT:
167     case hci::OpCode::READ_SECURE_CONNECTIONS_HOST_SUPPORT:
168     case hci::OpCode::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT:
169     case hci::OpCode::READ_LOCAL_OOB_EXTENDED_DATA:
170     case hci::OpCode::SET_ECOSYSTEM_BASE_INTERVAL:
171     case hci::OpCode::CONFIGURE_DATA_PATH:
172     case hci::OpCode::READ_LOCAL_VERSION_INFORMATION:
173     case hci::OpCode::READ_LOCAL_SUPPORTED_COMMANDS:
174     case hci::OpCode::READ_LOCAL_SUPPORTED_FEATURES:
175     case hci::OpCode::READ_LOCAL_EXTENDED_FEATURES:
176     case hci::OpCode::READ_BUFFER_SIZE:
177     case hci::OpCode::READ_BD_ADDR:
178     case hci::OpCode::READ_DATA_BLOCK_SIZE:
179     case hci::OpCode::READ_LOCAL_SUPPORTED_CODECS_V1:
180     case hci::OpCode::READ_LOCAL_SUPPORTED_CODECS_V2:
181     case hci::OpCode::READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES:
182     case hci::OpCode::READ_LOCAL_SUPPORTED_CONTROLLER_DELAY:
183     case hci::OpCode::READ_LOCAL_OOB_DATA:
184     case hci::OpCode::LE_GENERATE_DHKEY_COMMAND:
185     case hci::OpCode::LE_MODIFY_SLEEP_CLOCK_ACCURACY:
186     case hci::OpCode::LE_READ_BUFFER_SIZE_V2:
187     case hci::OpCode::LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH:
188     case hci::OpCode::LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH:
189     case hci::OpCode::LE_READ_LOCAL_P_256_PUBLIC_KEY_COMMAND:
190     case hci::OpCode::LE_GENERATE_DHKEY_COMMAND_V1:
191     case hci::OpCode::LE_SET_EVENT_MASK:
192     case hci::OpCode::LE_READ_BUFFER_SIZE_V1:
193     case hci::OpCode::LE_READ_LOCAL_SUPPORTED_FEATURES:
194     case hci::OpCode::LE_SET_RANDOM_ADDRESS:
195     case hci::OpCode::LE_READ_TRANSMIT_POWER:
196     case hci::OpCode::LE_READ_RF_PATH_COMPENSATION_POWER:
197     case hci::OpCode::LE_WRITE_RF_PATH_COMPENSATION_POWER:
198     case hci::OpCode::LE_SET_DEFAULT_PHY:
199     case hci::OpCode::LE_ENCRYPT:
200     case hci::OpCode::LE_RAND:
201     case hci::OpCode::LE_SET_ADDRESS_RESOLUTION_ENABLE:
202     case hci::OpCode::LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT:
203     case hci::OpCode::LE_READ_MAXIMUM_DATA_LENGTH:
204     case hci::OpCode::LE_READ_SUPPORTED_STATES:
205       classification = {.activity = Activity::CONTROL, .connection_handle_pos = 0, .address_pos = 0};
206       break;
207 
208     case hci::OpCode::DELETE_STORED_LINK_KEY:
209       classification = {.activity = Activity::CONTROL, .connection_handle_pos = 0, .address_pos = 3};
210       break;
211     case hci::OpCode::READ_TRANSMIT_POWER_LEVEL:
212       classification = {.activity = Activity::CONTROL, .connection_handle_pos = 3, .address_pos = 0};
213       break;
214 
215     case hci::OpCode::READ_INQUIRY_SCAN_ACTIVITY:
216     case hci::OpCode::WRITE_INQUIRY_SCAN_ACTIVITY:
217     case hci::OpCode::READ_INQUIRY_SCAN_TYPE:
218     case hci::OpCode::WRITE_INQUIRY_SCAN_TYPE:
219     case hci::OpCode::READ_INQUIRY_MODE:
220     case hci::OpCode::WRITE_INQUIRY_MODE:
221     case hci::OpCode::READ_EXTENDED_INQUIRY_RESPONSE:
222     case hci::OpCode::WRITE_EXTENDED_INQUIRY_RESPONSE:
223     case hci::OpCode::LE_SET_CIG_PARAMETERS:
224     case hci::OpCode::LE_CREATE_CIS:
225     case hci::OpCode::LE_REMOVE_CIG:
226     case hci::OpCode::LE_ACCEPT_CIS_REQUEST:
227     case hci::OpCode::LE_REJECT_CIS_REQUEST:
228     case hci::OpCode::LE_CREATE_BIG:
229     case hci::OpCode::LE_TERMINATE_BIG:
230     case hci::OpCode::LE_BIG_CREATE_SYNC:
231     case hci::OpCode::LE_BIG_TERMINATE_SYNC:
232     case hci::OpCode::LE_REQUEST_PEER_SCA:
233     case hci::OpCode::LE_SETUP_ISO_DATA_PATH:
234     case hci::OpCode::LE_REMOVE_ISO_DATA_PATH:
235     case hci::OpCode::LE_SET_HOST_FEATURE:
236     case hci::OpCode::LE_READ_ISO_LINK_QUALITY:
237     case hci::OpCode::LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL:
238     case hci::OpCode::LE_READ_REMOTE_TRANSMIT_POWER_LEVEL:
239     case hci::OpCode::LE_SET_PATH_LOSS_REPORTING_PARAMETERS:
240     case hci::OpCode::LE_SET_PATH_LOSS_REPORTING_ENABLE:
241     case hci::OpCode::LE_SET_TRANSMIT_POWER_REPORTING_ENABLE:
242     case hci::OpCode::LE_GET_VENDOR_CAPABILITIES:
243     case hci::OpCode::LE_MULTI_ADVT:
244     case hci::OpCode::LE_BATCH_SCAN:
245     case hci::OpCode::LE_ADV_FILTER:
246     case hci::OpCode::LE_ENERGY_INFO:
247     case hci::OpCode::LE_EXTENDED_SCAN_PARAMS:
248     case hci::OpCode::CONTROLLER_DEBUG_INFO:
249     case hci::OpCode::CONTROLLER_A2DP_OPCODE:
250     case hci::OpCode::CONTROLLER_BQR:
251     case hci::OpCode::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL:
252     case hci::OpCode::WRITE_INQUIRY_TRANSMIT_POWER_LEVEL:
253     case hci::OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS:
254     case hci::OpCode::LE_SET_EXTENDED_SCAN_ENABLE:
255     case hci::OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL:
256     case hci::OpCode::LE_SET_SCAN_PARAMETERS:
257     case hci::OpCode::LE_SET_SCAN_ENABLE:
258     case hci::OpCode::LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS:
259     case hci::OpCode::LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE:
260     case hci::OpCode::LE_CLEAR_PERIODIC_ADVERTISING_LIST:
261     case hci::OpCode::LE_READ_PERIODIC_ADVERTISING_LIST_SIZE:
262     case hci::OpCode::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC:
263       classification = {.activity = Activity::SCAN, .connection_handle_pos = 0, .address_pos = 0};
264       break;
265 
266     case hci::OpCode::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER:
267     case hci::OpCode::LE_SET_ADVERTISING_DATA:
268     case hci::OpCode::LE_SET_SCAN_RESPONSE_DATA:
269     case hci::OpCode::LE_SET_ADVERTISING_ENABLE:
270     case hci::OpCode::LE_SET_EXTENDED_ADVERTISING_DATA:
271     case hci::OpCode::LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE:
272     case hci::OpCode::LE_SET_EXTENDED_ADVERTISING_ENABLE:
273     case hci::OpCode::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH:
274     case hci::OpCode::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS:
275     case hci::OpCode::LE_REMOVE_ADVERTISING_SET:
276     case hci::OpCode::LE_CLEAR_ADVERTISING_SETS:
277     case hci::OpCode::LE_SET_PERIODIC_ADVERTISING_PARAM:
278     case hci::OpCode::LE_SET_PERIODIC_ADVERTISING_DATA:
279     case hci::OpCode::LE_SET_PERIODIC_ADVERTISING_ENABLE:
280     case hci::OpCode::LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS:
281       classification = {.activity = Activity::ADVERTISE, .connection_handle_pos = 0, .address_pos = 0};
282       break;
283 
284     case hci::OpCode::LE_SET_ADVERTISING_PARAMETERS:
285       classification = {.activity = Activity::SCAN, .connection_handle_pos = 0, .address_pos = 10};
286       break;
287     case hci::OpCode::LE_CREATE_CONNECTION:
288       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 0, .address_pos = 9};
289       break;
290     case hci::OpCode::LE_ADD_DEVICE_TO_CONNECT_LIST:
291     case hci::OpCode::LE_READ_CHANNEL_MAP:
292       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 4, .address_pos = 0};
293       break;
294 
295     case hci::OpCode::LE_REMOVE_DEVICE_FROM_CONNECT_LIST:
296     case hci::OpCode::LE_ADD_DEVICE_TO_RESOLVING_LIST:
297     case hci::OpCode::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST:
298     case hci::OpCode::LE_READ_PEER_RESOLVABLE_ADDRESS:
299     case hci::OpCode::LE_READ_LOCAL_RESOLVABLE_ADDRESS:
300     case hci::OpCode::LE_SET_PRIVACY_MODE:
301       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 0, .address_pos = 4};
302       break;
303 
304     case hci::OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS:
305       classification = {.activity = Activity::ADVERTISE, .connection_handle_pos = 0, .address_pos = 15};
306       break;
307     case hci::OpCode::LE_EXTENDED_CREATE_CONNECTION:
308       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 0, .address_pos = 6};
309       break;
310     case hci::OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC:
311       classification = {.activity = Activity::SCAN, .connection_handle_pos = 0, .address_pos = 6};
312       break;
313     case hci::OpCode::LE_ADD_DEVICE_TO_PERIODIC_ADVERTISING_LIST:
314     case hci::OpCode::LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISING_LIST:
315       classification = {.activity = Activity::SCAN, .connection_handle_pos = 0, .address_pos = 4};
316       break;
317     case hci::OpCode::LE_PERIODIC_ADVERTISING_SYNC_TRANSFER:
318     case hci::OpCode::LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER:
319     case hci::OpCode::LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS:
320       classification = {.activity = Activity::SCAN, .connection_handle_pos = 3, .address_pos = 0};
321       break;
322 
323     default:
324       classification = {.activity = Activity::UNKNOWN, .connection_handle_pos = 0, .address_pos = 0};
325       break;
326   }
327   return classification;
328 }
329 
lookup_event(hci::EventCode event_code)330 CmdEvtActivityClassification lookup_event(hci::EventCode event_code) {
331   CmdEvtActivityClassification classification = {};
332   switch (event_code) {
333     case hci::EventCode::INQUIRY_COMPLETE:
334       classification = {.activity = Activity::SCAN, .connection_handle_pos = 0, .address_pos = 0};
335       break;
336     case hci::EventCode::CONNECTION_COMPLETE:
337     case hci::EventCode::SYNCHRONOUS_CONNECTION_COMPLETE:
338       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 3, .address_pos = 5};
339       break;
340 
341     case hci::EventCode::CONNECTION_REQUEST:
342     case hci::EventCode::PIN_CODE_REQUEST:
343     case hci::EventCode::LINK_KEY_REQUEST:
344     case hci::EventCode::LINK_KEY_NOTIFICATION:
345     case hci::EventCode::USER_PASSKEY_NOTIFICATION:
346     case hci::EventCode::KEYPRESS_NOTIFICATION:
347     case hci::EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION:
348     case hci::EventCode::IO_CAPABILITY_REQUEST:
349     case hci::EventCode::IO_CAPABILITY_RESPONSE:
350     case hci::EventCode::USER_CONFIRMATION_REQUEST:
351     case hci::EventCode::USER_PASSKEY_REQUEST:
352     case hci::EventCode::REMOTE_OOB_DATA_REQUEST:
353       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 0, .address_pos = 2};
354       break;
355 
356     case hci::EventCode::DISCONNECTION_COMPLETE:
357     case hci::EventCode::AUTHENTICATION_COMPLETE:
358     case hci::EventCode::ENCRYPTION_CHANGE:
359     case hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE:
360     case hci::EventCode::LINK_SUPERVISION_TIMEOUT_CHANGED:
361     case hci::EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE:
362     case hci::EventCode::CENTRAL_LINK_KEY_COMPLETE:
363     case hci::EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE:
364     case hci::EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE:
365     case hci::EventCode::QOS_SETUP_COMPLETE:
366     case hci::EventCode::MODE_CHANGE:
367     case hci::EventCode::READ_CLOCK_OFFSET_COMPLETE:
368     case hci::EventCode::CONNECTION_PACKET_TYPE_CHANGED:
369     case hci::EventCode::FLOW_SPECIFICATION_COMPLETE:
370     case hci::EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE:
371     case hci::EventCode::SYNCHRONOUS_CONNECTION_CHANGED:
372     case hci::EventCode::SNIFF_SUBRATING:
373       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 3, .address_pos = 0};
374       break;
375 
376     case hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE:
377     case hci::EventCode::EXTENDED_INQUIRY_RESULT:
378       classification = {.activity = Activity::SCAN, .connection_handle_pos = 0, .address_pos = 3};
379       break;
380     case hci::EventCode::FLUSH_OCCURRED:
381     case hci::EventCode::MAX_SLOTS_CHANGE:
382     case hci::EventCode::QOS_VIOLATION:
383     case hci::EventCode::ENHANCED_FLUSH_COMPLETE:
384       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 2, .address_pos = 0};
385       break;
386     case hci::EventCode::ROLE_CHANGE:
387     case hci::EventCode::SIMPLE_PAIRING_COMPLETE:
388       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 0, .address_pos = 3};
389       break;
390     case hci::EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE:
391       classification = {.activity = Activity::SCAN, .connection_handle_pos = 0, .address_pos = 2};
392       break;
393 
394     default:
395       classification = {.activity = Activity::UNKNOWN, .connection_handle_pos = 0, .address_pos = 0};
396   }
397   return classification;
398 }
399 
lookup_le_event(hci::SubeventCode subevent_code)400 CmdEvtActivityClassification lookup_le_event(hci::SubeventCode subevent_code) {
401   CmdEvtActivityClassification classification = {};
402   switch (subevent_code) {
403     case hci::SubeventCode::CONNECTION_COMPLETE:
404     case hci::SubeventCode::ENHANCED_CONNECTION_COMPLETE:
405       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 4, .address_pos = 7};
406       break;
407 
408     case hci::SubeventCode::CONNECTION_UPDATE_COMPLETE:
409     case hci::SubeventCode::READ_REMOTE_FEATURES_COMPLETE:
410     case hci::SubeventCode::PHY_UPDATE_COMPLETE:
411     case hci::SubeventCode::CTE_REQUEST_FAILED:
412     case hci::SubeventCode::TRANSMIT_POWER_REPORTING:
413       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 4, .address_pos = 0};
414       break;
415 
416     case hci::SubeventCode::LONG_TERM_KEY_REQUEST:
417     case hci::SubeventCode::REMOTE_CONNECTION_PARAMETER_REQUEST:
418     case hci::SubeventCode::DATA_LENGTH_CHANGE:
419     case hci::SubeventCode::CHANNEL_SELECTION_ALGORITHM:
420     case hci::SubeventCode::CONNECTION_IQ_REPORT:
421     case hci::SubeventCode::PATH_LOSS_THRESHOLD:
422       classification = {.activity = Activity::CONNECT, .connection_handle_pos = 3, .address_pos = 0};
423       break;
424 
425     case hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE:
426     case hci::SubeventCode::GENERATE_DHKEY_COMPLETE:
427       classification = {.activity = Activity::CONTROL, .connection_handle_pos = 0, .address_pos = 0};
428       break;
429 
430     case hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED:
431     case hci::SubeventCode::PERIODIC_ADVERTISING_REPORT:
432     case hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST:
433     case hci::SubeventCode::ADVERTISING_SET_TERMINATED:
434       classification = {.activity = Activity::ADVERTISE, .connection_handle_pos = 0, .address_pos = 0};
435       break;
436 
437     case hci::SubeventCode::SCAN_TIMEOUT:
438     case hci::SubeventCode::BIG_INFO_ADVERTISING_REPORT:
439     case hci::SubeventCode::CONNECTIONLESS_IQ_REPORT:
440     case hci::SubeventCode::CREATE_BIG_COMPLETE:
441     case hci::SubeventCode::TERMINATE_BIG_COMPLETE:
442     case hci::SubeventCode::BIG_SYNC_ESTABLISHED:
443     case hci::SubeventCode::BIG_SYNC_LOST:
444     case hci::SubeventCode::REQUEST_PEER_SCA_COMPLETE:
445       classification = {.activity = Activity::SCAN, .connection_handle_pos = 0, .address_pos = 0};
446       break;
447 
448     case hci::SubeventCode::SCAN_REQUEST_RECEIVED:
449       classification = {.activity = Activity::ADVERTISE, .connection_handle_pos = 0, .address_pos = 5};
450       break;
451 
452     case hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED:
453     case hci::SubeventCode::CIS_ESTABLISHED:
454     case hci::SubeventCode::CIS_REQUEST:
455       classification = {.activity = Activity::SCAN, .connection_handle_pos = 4, .address_pos = 0};
456       break;
457 
458     default:
459       classification = {.activity = Activity::UNKNOWN, .connection_handle_pos = 0, .address_pos = 0};
460   }
461   return classification;
462 }
463 
464 }  // namespace activity_attribution
465 }  // namespace bluetooth
466