1 /*
2  * Copyright (C) 2008 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 package com.android.server.wifi;
18 
19 import android.annotation.IntDef;
20 import android.net.MacAddress;
21 import android.net.wifi.SupplicantState;
22 import android.net.wifi.WifiEnterpriseConfig;
23 import android.net.wifi.WifiManager;
24 import android.net.wifi.WifiSsid;
25 import android.os.Handler;
26 import android.os.Message;
27 import android.util.ArraySet;
28 import android.util.Log;
29 import android.util.SparseArray;
30 
31 import com.android.internal.annotations.VisibleForTesting;
32 import com.android.internal.util.Protocol;
33 import com.android.server.wifi.MboOceController.BtmFrameData;
34 import com.android.server.wifi.SupplicantStaIfaceHal.QosPolicyRequest;
35 import com.android.server.wifi.SupplicantStaIfaceHal.SupplicantEventCode;
36 import com.android.server.wifi.WifiCarrierInfoManager.SimAuthRequestData;
37 import com.android.server.wifi.hotspot2.AnqpEvent;
38 import com.android.server.wifi.hotspot2.IconEvent;
39 import com.android.server.wifi.hotspot2.WnmData;
40 
41 import java.lang.annotation.Retention;
42 import java.lang.annotation.RetentionPolicy;
43 import java.util.ArrayList;
44 import java.util.BitSet;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Set;
49 
50 /**
51  * Listen for events from the wpa_supplicant & wificond and broadcast them on
52  * to the various {@link ClientModeImpl} modules interested in handling these events.
53  */
54 public class WifiMonitor {
55     private static final String TAG = "WifiMonitor";
56 
57     /* Supplicant events reported to a state machine */
58     private static final int BASE = Protocol.BASE_WIFI_MONITOR;
59 
60    /* Network connection completed */
61     public static final int NETWORK_CONNECTION_EVENT             = BASE + 3;
62     /* Network disconnection completed */
63     public static final int NETWORK_DISCONNECTION_EVENT          = BASE + 4;
64     /* Scan results are available */
65     public static final int SCAN_RESULTS_EVENT                   = BASE + 5;
66     /* Supplicate state changed */
67     public static final int SUPPLICANT_STATE_CHANGE_EVENT        = BASE + 6;
68     /* Password failure and EAP authentication failure */
69     public static final int AUTHENTICATION_FAILURE_EVENT         = BASE + 7;
70     /* WPS success detected */
71     public static final int WPS_SUCCESS_EVENT                    = BASE + 8;
72     /* WPS failure detected */
73     public static final int WPS_FAIL_EVENT                       = BASE + 9;
74      /* WPS overlap detected */
75     public static final int WPS_OVERLAP_EVENT                    = BASE + 10;
76      /* WPS timeout detected */
77     public static final int WPS_TIMEOUT_EVENT                    = BASE + 11;
78 
79     /* Request Identity */
80     public static final int SUP_REQUEST_IDENTITY                 = BASE + 15;
81 
82     /* Request SIM Auth */
83     public static final int SUP_REQUEST_SIM_AUTH                 = BASE + 16;
84 
85     public static final int SCAN_FAILED_EVENT                    = BASE + 17;
86     /* Pno scan results are available */
87     public static final int PNO_SCAN_RESULTS_EVENT               = BASE + 18;
88 
89 
90     /* Indicates assoc reject event */
91     public static final int ASSOCIATION_REJECTION_EVENT          = BASE + 43;
92     public static final int ANQP_DONE_EVENT                      = BASE + 44;
93     public static final int ASSOCIATED_BSSID_EVENT               = BASE + 45;
94     public static final int TARGET_BSSID_EVENT                   = BASE + 46;
95     public static final int NETWORK_NOT_FOUND_EVENT              = BASE + 47;
96 
97     /* Passpoint ANQP events */
98     public static final int GAS_QUERY_START_EVENT                = BASE + 51;
99     public static final int GAS_QUERY_DONE_EVENT                 = BASE + 52;
100     public static final int RX_HS20_ANQP_ICON_EVENT              = BASE + 53;
101 
102     /* Passpoint events */
103     public static final int HS20_REMEDIATION_EVENT               = BASE + 61;
104     public static final int HS20_DEAUTH_IMMINENT_EVENT           = BASE + 62;
105     public static final int HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT = BASE + 63;
106 
107     /* MBO/OCE events */
108     public static final int MBO_OCE_BSS_TM_HANDLING_DONE         = BASE + 71;
109 
110     /* Transition Disable Indication */
111     public static final int TRANSITION_DISABLE_INDICATION        = BASE + 72;
112 
113     /* Trust On First Use incoming certificate event */
114     public static final int TOFU_CERTIFICATE_EVENT               = BASE + 73;
115 
116     /* Auxiliary supplicant event */
117     public static final int AUXILIARY_SUPPLICANT_EVENT           = BASE + 74;
118 
119     /* Quality of Service (QoS) events */
120     public static final int QOS_POLICY_RESET_EVENT               = BASE + 75;
121     public static final int QOS_POLICY_REQUEST_EVENT             = BASE + 76;
122 
123     /* MLO links change event */
124     public static final int MLO_LINKS_INFO_CHANGED              = BASE + 77;
125 
126     /* the AT_PERMANENT_ID_REQ denied indication for EAP-SIM/AKA/AKA' */
127     public static final int PERMANENT_ID_REQ_DENIED_INDICATION = BASE + 78;
128 
129     /* BSS frequency changed event (when STA switches the channel due to CSA) */
130     public static final int BSS_FREQUENCY_CHANGED_EVENT = BASE + 79;
131 
132     /* WPS config errrors */
133     private static final int CONFIG_MULTIPLE_PBC_DETECTED = 12;
134     private static final int CONFIG_AUTH_FAILURE = 18;
135 
136     /* WPS error indications */
137     private static final int REASON_TKIP_ONLY_PROHIBITED = 1;
138     private static final int REASON_WEP_PROHIBITED = 2;
139 
140     /* Transition disable indication */
141     public static final int TDI_USE_WPA3_PERSONAL = 1 << 0;
142     public static final int TDI_USE_SAE_PK = 1 << 1;
143     public static final int TDI_USE_WPA3_ENTERPRISE = 1 << 2;
144     public static final int TDI_USE_ENHANCED_OPEN = 1 << 3;
145 
146     @IntDef(flag = true, prefix = { "TDI_" }, value = {
147             TDI_USE_WPA3_PERSONAL,
148             TDI_USE_SAE_PK,
149             TDI_USE_WPA3_ENTERPRISE,
150             TDI_USE_ENHANCED_OPEN,
151     })
152     @Retention(RetentionPolicy.SOURCE)
153     @interface TransitionDisableIndication{}
154 
155     /* MLO links change event reason codes */
156     public enum MloLinkInfoChangeReason {
157         UNKNOWN,
158         TID_TO_LINK_MAP,
159         MULTI_LINK_RECONFIG_AP_REMOVAL,
160     }
161 
162     /**
163      * Use this key to get the interface name of the message sent by WifiMonitor,
164      * or null if not available.
165      *
166      * <br />
167      * Sample code:
168      * <code>
169      * message.getData().getString(KEY_IFACE)
170      * </code>
171      */
172     public static final String KEY_IFACE = "com.android.server.wifi.WifiMonitor.KEY_IFACE";
173 
174     private boolean mVerboseLoggingEnabled = false;
175 
enableVerboseLogging(boolean verbose)176     void enableVerboseLogging(boolean verbose) {
177         mVerboseLoggingEnabled = verbose;
178     }
179 
180     private final Map<String, SparseArray<Set<Handler>>> mHandlerMap = new HashMap<>();
registerHandler(String iface, int what, Handler handler)181     public synchronized void registerHandler(String iface, int what, Handler handler) {
182         SparseArray<Set<Handler>> ifaceHandlers = mHandlerMap.get(iface);
183         if (ifaceHandlers == null) {
184             ifaceHandlers = new SparseArray<>();
185             mHandlerMap.put(iface, ifaceHandlers);
186         }
187         Set<Handler> ifaceWhatHandlers = ifaceHandlers.get(what);
188         if (ifaceWhatHandlers == null) {
189             ifaceWhatHandlers = new ArraySet<>();
190             ifaceHandlers.put(what, ifaceWhatHandlers);
191         }
192         ifaceWhatHandlers.add(handler);
193     }
194 
195     /**
196      * Deregister the given |handler|
197      * @param iface
198      * @param what
199      * @param handler
200      */
deregisterHandler(String iface, int what, Handler handler)201     public synchronized void deregisterHandler(String iface, int what, Handler handler) {
202         SparseArray<Set<Handler>> ifaceHandlers = mHandlerMap.get(iface);
203         if (ifaceHandlers == null) {
204             return;
205         }
206         Set<Handler> ifaceWhatHandlers = ifaceHandlers.get(what);
207         if (ifaceWhatHandlers == null) {
208             return;
209         }
210         ifaceWhatHandlers.remove(handler);
211     }
212 
213     private final Map<String, Boolean> mMonitoringMap = new HashMap<>();
isMonitoring(String iface)214     private boolean isMonitoring(String iface) {
215         Boolean val = mMonitoringMap.get(iface);
216         if (val == null) {
217             return false;
218         } else {
219             return val.booleanValue();
220         }
221     }
222 
223     /**
224      * Enable/Disable monitoring for the provided iface.
225      *
226      * @param iface Name of the iface.
227      * @param enabled true to enable, false to disable.
228      */
229     @VisibleForTesting
setMonitoring(String iface, boolean enabled)230     public void setMonitoring(String iface, boolean enabled) {
231         mMonitoringMap.put(iface, enabled);
232     }
233 
234     /**
235      * Start Monitoring for wpa_supplicant events.
236      *
237      * @param iface Name of iface.
238      */
startMonitoring(String iface)239     public synchronized void startMonitoring(String iface) {
240         if (mVerboseLoggingEnabled) Log.d(TAG, "startMonitoring(" + iface + ")");
241         setMonitoring(iface, true);
242     }
243 
244     /**
245      * Stop Monitoring for wpa_supplicant events.
246      *
247      * @param iface Name of iface.
248      */
stopMonitoring(String iface)249     public synchronized void stopMonitoring(String iface) {
250         if (mVerboseLoggingEnabled) Log.d(TAG, "stopMonitoring(" + iface + ")");
251         setMonitoring(iface, true);
252         setMonitoring(iface, false);
253     }
254 
255     /**
256      * Returns the names of any interfaces that are being monitored.
257      */
getMonitoredIfaceNames()258     public List<String> getMonitoredIfaceNames() {
259         List<String> monitoringIfaceList = new ArrayList<>();
260         for (String iface : mMonitoringMap.keySet()) {
261             if (mMonitoringMap.get(iface)) {
262                 monitoringIfaceList.add(iface);
263             }
264         }
265         return monitoringIfaceList;
266     }
267 
268     /**
269      * Similar functions to Handler#sendMessage that send the message to the registered handler
270      * for the given interface and message what.
271      * All of these should be called with the WifiMonitor class lock
272      */
sendMessage(String iface, int what)273     private void sendMessage(String iface, int what) {
274         sendMessage(iface, Message.obtain(null, what));
275     }
276 
sendMessage(String iface, int what, Object obj)277     private void sendMessage(String iface, int what, Object obj) {
278         sendMessage(iface, Message.obtain(null, what, obj));
279     }
280 
sendMessage(String iface, int what, int arg1)281     private void sendMessage(String iface, int what, int arg1) {
282         sendMessage(iface, Message.obtain(null, what, arg1, 0));
283     }
284 
sendMessage(String iface, int what, int arg1, int arg2)285     private void sendMessage(String iface, int what, int arg1, int arg2) {
286         sendMessage(iface, Message.obtain(null, what, arg1, arg2));
287     }
288 
sendMessage(String iface, int what, int arg1, int arg2, Object obj)289     private void sendMessage(String iface, int what, int arg1, int arg2, Object obj) {
290         sendMessage(iface, Message.obtain(null, what, arg1, arg2, obj));
291     }
292 
sendMessage(String iface, Message message)293     private void sendMessage(String iface, Message message) {
294         SparseArray<Set<Handler>> ifaceHandlers = mHandlerMap.get(iface);
295         if (iface != null && ifaceHandlers != null) {
296             if (isMonitoring(iface)) {
297                 Set<Handler> ifaceWhatHandlers = ifaceHandlers.get(message.what);
298                 if (ifaceWhatHandlers != null) {
299                     for (Handler handler : ifaceWhatHandlers) {
300                         if (handler != null) {
301                             sendMessage(iface, handler, Message.obtain(message));
302                         }
303                     }
304                 }
305             } else {
306                 if (mVerboseLoggingEnabled) {
307                     Log.d(TAG, "Dropping event because (" + iface + ") is stopped");
308                 }
309             }
310         } else {
311             if (mVerboseLoggingEnabled) {
312                 Log.d(TAG, "Sending to all monitors because there's no matching iface");
313             }
314             for (Map.Entry<String, SparseArray<Set<Handler>>> entry : mHandlerMap.entrySet()) {
315                 iface = entry.getKey();
316                 if (isMonitoring(iface)) {
317                     Set<Handler> ifaceWhatHandlers = entry.getValue().get(message.what);
318                     if (ifaceWhatHandlers == null) continue;
319                     for (Handler handler : ifaceWhatHandlers) {
320                         if (handler != null) {
321                             sendMessage(iface, handler, Message.obtain(message));
322                         }
323                     }
324                 }
325             }
326         }
327 
328         message.recycle();
329     }
330 
sendMessage(String iface, Handler handler, Message message)331     private void sendMessage(String iface, Handler handler, Message message) {
332         message.setTarget(handler);
333         // getData() will return the existing Bundle if it exists, or create a new one
334         // This prevents clearing the existing data.
335         message.getData().putString(KEY_IFACE, iface);
336         message.sendToTarget();
337     }
338 
339     /**
340      * Broadcast the WPS fail event to all the handlers registered for this event.
341      *
342      * @param iface Name of iface on which this occurred.
343      * @param cfgError Configuration error code.
344      * @param vendorErrorCode Vendor specific error indication code.
345      */
broadcastWpsFailEvent(String iface, int cfgError, int vendorErrorCode)346     public void broadcastWpsFailEvent(String iface, int cfgError, int vendorErrorCode) {
347         int reason = 0;
348         switch(vendorErrorCode) {
349             case REASON_TKIP_ONLY_PROHIBITED:
350                 sendMessage(iface, WPS_FAIL_EVENT, WifiManager.WPS_TKIP_ONLY_PROHIBITED);
351                 return;
352             case REASON_WEP_PROHIBITED:
353                 sendMessage(iface, WPS_FAIL_EVENT, WifiManager.WPS_WEP_PROHIBITED);
354                 return;
355             default:
356                 reason = vendorErrorCode;
357                 break;
358         }
359         switch(cfgError) {
360             case CONFIG_AUTH_FAILURE:
361                 sendMessage(iface, WPS_FAIL_EVENT, WifiManager.WPS_AUTH_FAILURE);
362                 return;
363             case CONFIG_MULTIPLE_PBC_DETECTED:
364                 sendMessage(iface, WPS_FAIL_EVENT, WifiManager.WPS_OVERLAP_ERROR);
365                 return;
366             default:
367                 if (reason == 0) {
368                     reason = cfgError;
369                 }
370                 break;
371         }
372         //For all other errors, return a generic internal error
373         sendMessage(iface, WPS_FAIL_EVENT, WifiManager.ActionListener.FAILURE_INTERNAL_ERROR,
374                 reason);
375     }
376 
377    /**
378     * Broadcast the WPS succes event to all the handlers registered for this event.
379     *
380     * @param iface Name of iface on which this occurred.
381     */
broadcastWpsSuccessEvent(String iface)382     public void broadcastWpsSuccessEvent(String iface) {
383         sendMessage(iface, WPS_SUCCESS_EVENT);
384     }
385 
386     /**
387      * Broadcast the WPS overlap event to all the handlers registered for this event.
388      *
389      * @param iface Name of iface on which this occurred.
390      */
broadcastWpsOverlapEvent(String iface)391     public void broadcastWpsOverlapEvent(String iface) {
392         sendMessage(iface, WPS_OVERLAP_EVENT);
393     }
394 
395     /**
396      * Broadcast the WPS timeout event to all the handlers registered for this event.
397      *
398      * @param iface Name of iface on which this occurred.
399      */
broadcastWpsTimeoutEvent(String iface)400     public void broadcastWpsTimeoutEvent(String iface) {
401         sendMessage(iface, WPS_TIMEOUT_EVENT);
402     }
403 
404     /**
405      * Broadcast the ANQP done event to all the handlers registered for this event.
406      *
407      * @param iface Name of iface on which this occurred.
408      * @param anqpEvent ANQP result retrieved.
409      */
broadcastAnqpDoneEvent(String iface, AnqpEvent anqpEvent)410     public void broadcastAnqpDoneEvent(String iface, AnqpEvent anqpEvent) {
411         sendMessage(iface, ANQP_DONE_EVENT, anqpEvent);
412     }
413 
414     /**
415      * Broadcast the Icon done event to all the handlers registered for this event.
416      *
417      * @param iface Name of iface on which this occurred.
418      * @param iconEvent Instance of IconEvent containing the icon data retrieved.
419      */
broadcastIconDoneEvent(String iface, IconEvent iconEvent)420     public void broadcastIconDoneEvent(String iface, IconEvent iconEvent) {
421         sendMessage(iface, RX_HS20_ANQP_ICON_EVENT, iconEvent);
422     }
423 
424     /**
425      * Broadcast the WNM event to all the handlers registered for this event.
426      *
427      * @param iface Name of iface on which this occurred.
428      * @param wnmData Instance of WnmData containing the event data.
429      */
broadcastWnmEvent(String iface, WnmData wnmData)430     public void broadcastWnmEvent(String iface, WnmData wnmData) {
431         if (mVerboseLoggingEnabled) Log.d(TAG, "WNM-Notification " + wnmData.getEventType());
432         switch (wnmData.getEventType()) {
433             case WnmData.HS20_REMEDIATION_EVENT:
434                 sendMessage(iface, HS20_REMEDIATION_EVENT, wnmData);
435                 break;
436 
437             case WnmData.HS20_DEAUTH_IMMINENT_EVENT:
438                 sendMessage(iface, HS20_DEAUTH_IMMINENT_EVENT, wnmData);
439                 break;
440 
441             case WnmData.HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT:
442                 sendMessage(iface, HS20_TERMS_AND_CONDITIONS_ACCEPTANCE_REQUIRED_EVENT, wnmData);
443                 break;
444 
445             default:
446                 Log.e(TAG, "Broadcast request for an unknown WNM-notification "
447                         + wnmData.getEventType());
448                 break;
449         }
450     }
451 
452     /**
453      * Broadcast the Network identity request event to all the handlers registered for this event.
454      *
455      * @param iface Name of iface on which this occurred.
456      * @param networkId ID of the network in wpa_supplicant.
457      * @param ssid SSID of the network.
458      */
broadcastNetworkIdentityRequestEvent(String iface, int networkId, String ssid)459     public void broadcastNetworkIdentityRequestEvent(String iface, int networkId, String ssid) {
460         sendMessage(iface, SUP_REQUEST_IDENTITY, 0, networkId, ssid);
461     }
462 
463     /**
464      * Broadcast the transition disable event to all the handlers registered for this event.
465      *
466      * @param iface Name of iface on which this occurred.
467      * @param networkId ID of the network in wpa_supplicant.
468      * @param indicationBits bits of the disable indication.
469      */
broadcastTransitionDisableEvent( String iface, int networkId, @TransitionDisableIndication int indicationBits)470     public void broadcastTransitionDisableEvent(
471             String iface, int networkId,
472             @TransitionDisableIndication int indicationBits) {
473         sendMessage(iface, TRANSITION_DISABLE_INDICATION, networkId, indicationBits);
474     }
475 
476     /**
477      * Broadcast the Network Gsm Sim auth request event to all the handlers registered for this
478      * event.
479      *
480      * @param iface Name of iface on which this occurred.
481      * @param networkId ID of the network in wpa_supplicant.
482      * @param ssid SSID of the network.
483      * @param data Accompanying event data.
484      */
broadcastNetworkGsmAuthRequestEvent(String iface, int networkId, String ssid, String[] data)485     public void broadcastNetworkGsmAuthRequestEvent(String iface, int networkId, String ssid,
486                                                     String[] data) {
487         sendMessage(iface, SUP_REQUEST_SIM_AUTH,
488                 new SimAuthRequestData(networkId, WifiEnterpriseConfig.Eap.SIM, ssid, data));
489     }
490 
491     /**
492      * Broadcast the Network Umts Sim auth request event to all the handlers registered for this
493      * event.
494      *
495      * @param iface Name of iface on which this occurred.
496      * @param networkId ID of the network in wpa_supplicant.
497      * @param ssid SSID of the network.
498      * @param data Accompanying event data.
499      */
broadcastNetworkUmtsAuthRequestEvent(String iface, int networkId, String ssid, String[] data)500     public void broadcastNetworkUmtsAuthRequestEvent(String iface, int networkId, String ssid,
501                                                      String[] data) {
502         sendMessage(iface, SUP_REQUEST_SIM_AUTH,
503                 new SimAuthRequestData(networkId, WifiEnterpriseConfig.Eap.AKA, ssid, data));
504     }
505 
506     /**
507      * Broadcast scan result event to all the handlers registered for this event.
508      * @param iface Name of iface on which this occurred.
509      */
broadcastScanResultEvent(String iface)510     public void broadcastScanResultEvent(String iface) {
511         sendMessage(iface, SCAN_RESULTS_EVENT);
512     }
513 
514     /**
515      * Broadcast pno scan result event to all the handlers registered for this event.
516      * @param iface Name of iface on which this occurred.
517      */
broadcastPnoScanResultEvent(String iface)518     public void broadcastPnoScanResultEvent(String iface) {
519         sendMessage(iface, PNO_SCAN_RESULTS_EVENT);
520     }
521 
522     /**
523      * Broadcast scan failed event to all the handlers registered for this event.
524      * @param iface Name of iface on which this occurred.
525      */
broadcastScanFailedEvent(String iface, int errorCode)526     public void broadcastScanFailedEvent(String iface, int errorCode) {
527         sendMessage(iface, SCAN_FAILED_EVENT, errorCode);
528     }
529 
530     /**
531      * Broadcast the authentication failure event to all the handlers registered for this event.
532      *
533      * @param iface Name of iface on which this occurred.
534      * @param reason Reason for authentication failure. This has to be one of the
535      *               {@link android.net.wifi.WifiManager#ERROR_AUTH_FAILURE_NONE},
536      *               {@link android.net.wifi.WifiManager#ERROR_AUTH_FAILURE_TIMEOUT},
537      *               {@link android.net.wifi.WifiManager#ERROR_AUTH_FAILURE_WRONG_PSWD},
538      *               {@link android.net.wifi.WifiManager#ERROR_AUTH_FAILURE_EAP_FAILURE}
539      * @param errorCode Error code associated with the authentication failure event.
540      *               A value of -1 is used when no error code is reported.
541      */
broadcastAuthenticationFailureEvent(String iface, int reason, int errorCode, String ssid, MacAddress bssid)542     public void broadcastAuthenticationFailureEvent(String iface, int reason, int errorCode,
543             String ssid, MacAddress bssid) {
544         sendMessage(iface, AUTHENTICATION_FAILURE_EVENT,
545                 new AuthenticationFailureEventInfo(ssid, bssid, reason, errorCode));
546     }
547 
548     /**
549      * Broadcast the association rejection event to all the handlers registered for this event.
550      *
551      * @param iface Name of iface on which this occurred.
552      * @param assocRejectInfo Instance of AssocRejectEventInfo containing the association
553      *                        rejection info.
554      */
broadcastAssociationRejectionEvent(String iface, AssocRejectEventInfo assocRejectInfo)555     public void broadcastAssociationRejectionEvent(String iface,
556             AssocRejectEventInfo assocRejectInfo) {
557         sendMessage(iface, ASSOCIATION_REJECTION_EVENT, assocRejectInfo);
558     }
559 
560     /**
561      * Broadcast the association success event to all the handlers registered for this event.
562      *
563      * @param iface Name of iface on which this occurred.
564      * @param bssid BSSID of the access point.
565      */
broadcastAssociatedBssidEvent(String iface, String bssid)566     public void broadcastAssociatedBssidEvent(String iface, String bssid) {
567         sendMessage(iface, ASSOCIATED_BSSID_EVENT, 0, 0, bssid);
568     }
569 
570     /**
571      * Broadcast the start of association event to all the handlers registered for this event.
572      *
573      * @param iface Name of iface on which this occurred.
574      * @param bssid BSSID of the access point.
575      */
broadcastTargetBssidEvent(String iface, String bssid)576     public void broadcastTargetBssidEvent(String iface, String bssid) {
577         sendMessage(iface, TARGET_BSSID_EVENT, 0, 0, bssid);
578     }
579 
580     /**
581      * Broadcast the network connection event to all the handlers registered for this event.
582      *
583      * @param iface Name of iface on which this occurred.
584      * @param networkId ID of the network in wpa_supplicant.
585      * @param filsHlpSent Whether the connection used FILS.
586      * @param bssid BSSID of the access point.
587      */
broadcastNetworkConnectionEvent(String iface, int networkId, boolean filsHlpSent, WifiSsid ssid, String bssid)588     public void broadcastNetworkConnectionEvent(String iface, int networkId, boolean filsHlpSent,
589             WifiSsid ssid, String bssid) {
590         broadcastNetworkConnectionEvent(iface, networkId, filsHlpSent, ssid, bssid, null);
591     }
592 
593     /**
594      * Broadcast the network connection event to all the handlers registered for this event.
595      *
596      * @param iface Name of iface on which this occurred.
597      * @param networkId ID of the network in wpa_supplicant.
598      * @param filsHlpSent Whether the connection used FILS.
599      * @param bssid BSSID of the access point.
600      * @param keyMgmtMask Current used key management mask.
601      */
broadcastNetworkConnectionEvent(String iface, int networkId, boolean filsHlpSent, WifiSsid ssid, String bssid, BitSet keyMgmtMask)602     public void broadcastNetworkConnectionEvent(String iface, int networkId, boolean filsHlpSent,
603             WifiSsid ssid, String bssid, BitSet keyMgmtMask) {
604         sendMessage(iface, NETWORK_CONNECTION_EVENT,
605                 new NetworkConnectionEventInfo(networkId, ssid, bssid, filsHlpSent, keyMgmtMask));
606     }
607 
608     /**
609      * Broadcast the network disconnection event to all the handlers registered for this event.
610      *
611      * @param iface Name of iface on which this occurred.
612      * @param locallyGenerated Whether the disconnect was locally triggered.
613      * @param reason Disconnect reason code.
614      * @param ssid SSID of the access point.
615      * @param bssid BSSID of the access point.
616      */
broadcastNetworkDisconnectionEvent(String iface, boolean locallyGenerated, int reason, String ssid, String bssid)617     public void broadcastNetworkDisconnectionEvent(String iface, boolean locallyGenerated,
618             int reason, String ssid, String bssid) {
619         sendMessage(iface, NETWORK_DISCONNECTION_EVENT,
620                 new DisconnectEventInfo(ssid, bssid, reason, locallyGenerated));
621     }
622 
623     /**
624      * Broadcast the supplicant state change event to all the handlers registered for this event.
625      *
626      * @param iface Name of iface on which this occurred.
627      * @param networkId ID of the network in wpa_supplicant.
628      * @param bssid BSSID of the access point.
629      * @param frequencyMhz Frequency of the connected channel in MHz
630      * @param newSupplicantState New supplicant state.
631      */
broadcastSupplicantStateChangeEvent(String iface, int networkId, WifiSsid wifiSsid, String bssid, int frequencyMhz, SupplicantState newSupplicantState)632     public void broadcastSupplicantStateChangeEvent(String iface, int networkId, WifiSsid wifiSsid,
633                                                     String bssid, int frequencyMhz,
634                                                     SupplicantState newSupplicantState) {
635         sendMessage(iface, SUPPLICANT_STATE_CHANGE_EVENT, 0, 0,
636                 new StateChangeResult(networkId, wifiSsid, bssid, frequencyMhz,
637                         newSupplicantState));
638     }
639 
640     /**
641      * Broadcast the bss transition management frame handling event
642      * to all the handlers registered for this event.
643      *
644      * @param iface Name of iface on which this occurred.
645      */
broadcastBssTmHandlingDoneEvent(String iface, BtmFrameData btmFrmData)646     public void broadcastBssTmHandlingDoneEvent(String iface, BtmFrameData btmFrmData) {
647         sendMessage(iface, MBO_OCE_BSS_TM_HANDLING_DONE, btmFrmData);
648     }
649 
650     /**
651      * Broadcast network not found event
652      * to all the handlers registered for this event.
653      *
654      * @param iface Name of iface on which this occurred.
655      */
broadcastNetworkNotFoundEvent(String iface, String ssid)656     public void broadcastNetworkNotFoundEvent(String iface, String ssid) {
657         sendMessage(iface, NETWORK_NOT_FOUND_EVENT, ssid);
658     }
659 
660     /**
661      * Broadcast the certification event which takes place during TOFU process.
662      *
663      * @param iface Name of iface on which this occurred.
664      * @param networkId ID of the network in wpa_supplicant.
665      * @param ssid SSID of the network.
666      * @param depth the depth of this cert in the chain, 0 is the leaf, i.e. the server cert.
667      * @param certificateEventInfo the certificate data.
668      */
broadcastCertificationEvent(String iface, int networkId, String ssid, int depth, CertificateEventInfo certificateEventInfo)669     public void broadcastCertificationEvent(String iface, int networkId, String ssid,
670             int depth, CertificateEventInfo certificateEventInfo) {
671         sendMessage(iface, TOFU_CERTIFICATE_EVENT, networkId, depth, certificateEventInfo);
672     }
673 
674     /**
675      * Broadcast the indication of AT_PERMANENT_ID_REQ denied for EAP-SIM/AKA/AKA'
676      * when the strict conservative peer mode is enabled.
677      *
678      * @param iface Name of iface on which this occurred.
679      * @param networkId ID of the network in wpa_supplicant.
680      * @param ssid SSID of the network.
681      */
broadcastPermanentIdReqDenied(String iface, int networkId, String ssid)682     public void broadcastPermanentIdReqDenied(String iface, int networkId,
683             String ssid) {
684         sendMessage(iface, PERMANENT_ID_REQ_DENIED_INDICATION, 0, networkId, ssid);
685     }
686 
687     /**
688      * Broadcast an auxiliary supplicant event to all handlers registered for this event.
689      *
690      * @param iface Name of iface on which this occurred.
691      * @param eventCode SupplicantEventCode for the event that occurred.
692      * @param bssid BSSID of the network.
693      * @param reasonString Optional string containing more information about why the
694      *                     event occurred.
695      */
broadcastAuxiliarySupplicantEvent(String iface, @SupplicantEventCode int eventCode, MacAddress bssid, String reasonString)696     public void broadcastAuxiliarySupplicantEvent(String iface, @SupplicantEventCode int eventCode,
697             MacAddress bssid, String reasonString) {
698         sendMessage(iface, AUXILIARY_SUPPLICANT_EVENT, 0, 0,
699                 new SupplicantEventInfo(eventCode, bssid, reasonString));
700     }
701 
702     /**
703      * Broadcast the QoS policy reset event to all the handlers
704      * registered for this event.
705      *
706      * @param iface Name of iface on which this occurred.
707      */
broadcastQosPolicyResetEvent(String iface)708     public void broadcastQosPolicyResetEvent(String iface) {
709         sendMessage(iface, QOS_POLICY_RESET_EVENT);
710     }
711 
712     /**
713      * Broadcast the QoS policy request event to all the handlers
714      * registered for this event.
715      *
716      * @param iface Name of iface on which this occurred.
717      * @param qosPolicyRequestId Dialog token to identify the request.
718      * @param qosPolicyData List of QoS policies requested by the AP.
719      */
broadcastQosPolicyRequestEvent(String iface, int qosPolicyRequestId, List<QosPolicyRequest> qosPolicyData)720     public void broadcastQosPolicyRequestEvent(String iface, int qosPolicyRequestId,
721             List<QosPolicyRequest> qosPolicyData) {
722         sendMessage(iface, QOS_POLICY_REQUEST_EVENT, qosPolicyRequestId, 0, qosPolicyData);
723     }
724 
725     /**
726      * Broadcast the MLO link changes with reason code to all handlers registered for this event.
727      *
728      * @param iface Name of the iface on which this occurred.
729      * @param reason Reason code for the MLO link info change.
730      */
broadcastMloLinksInfoChanged(String iface, WifiMonitor.MloLinkInfoChangeReason reason)731     public void broadcastMloLinksInfoChanged(String iface,
732             WifiMonitor.MloLinkInfoChangeReason reason) {
733         sendMessage(iface, MLO_LINKS_INFO_CHANGED, reason);
734     }
735 
736     /**
737      * Broadcast the BSS frequency changed event.
738      * This message is sent when STA switches the channel due to channel
739      * switch announcement from the connected access point.
740      *
741      * @param iface Name of the iface on which this occurred.
742      * @param frequencyMhz New frequency in MHz.
743      */
broadcastBssFrequencyChanged(String iface, int frequencyMhz)744     public void broadcastBssFrequencyChanged(String iface, int frequencyMhz) {
745         sendMessage(iface, BSS_FREQUENCY_CHANGED_EVENT, frequencyMhz);
746     }
747 }
748