1 /*
2  * Copyright (C) 2019 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 package com.android.server.wifi;
17 
18 
19 import android.annotation.NonNull;
20 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
21 import android.hardware.wifi.supplicant.V1_3.DppFailureCode;
22 import android.hardware.wifi.supplicant.V1_3.DppProgressCode;
23 import android.hardware.wifi.supplicant.V1_3.DppSuccessCode;
24 import android.net.wifi.SecurityParams;
25 import android.net.wifi.WifiConfiguration;
26 import android.util.Log;
27 
28 import java.util.ArrayList;
29 
30 abstract class SupplicantStaIfaceCallbackHidlV1_3Impl extends
31         android.hardware.wifi.supplicant.V1_3.ISupplicantStaIfaceCallback.Stub {
32     private static final String TAG = SupplicantStaIfaceCallbackHidlV1_3Impl.class.getSimpleName();
33     private final SupplicantStaIfaceHalHidlImpl mStaIfaceHal;
34     private final String mIfaceName;
35     private final WifiMonitor mWifiMonitor;
36     private final SupplicantStaIfaceHalHidlImpl.SupplicantStaIfaceHalCallbackV1_2 mCallbackV12;
37 
SupplicantStaIfaceCallbackHidlV1_3Impl(@onNull SupplicantStaIfaceHalHidlImpl staIfaceHal, @NonNull String ifaceName, @NonNull WifiMonitor wifiMonitor)38     SupplicantStaIfaceCallbackHidlV1_3Impl(@NonNull SupplicantStaIfaceHalHidlImpl staIfaceHal,
39             @NonNull String ifaceName,
40             @NonNull WifiMonitor wifiMonitor) {
41         mStaIfaceHal = staIfaceHal;
42         mIfaceName = ifaceName;
43         mWifiMonitor = wifiMonitor;
44         // Create an older callback for function delegation,
45         // and it would cascadingly create older one.
46         mCallbackV12 = mStaIfaceHal.new SupplicantStaIfaceHalCallbackV1_2(mIfaceName);
47     }
48 
getCallbackV10()49     public SupplicantStaIfaceHalHidlImpl.SupplicantStaIfaceHalCallback getCallbackV10() {
50         return mCallbackV12.getCallbackV10();
51     }
52 
53     @Override
onNetworkAdded(int id)54     public void onNetworkAdded(int id) {
55         mCallbackV12.onNetworkAdded(id);
56     }
57 
58     @Override
onNetworkRemoved(int id)59     public void onNetworkRemoved(int id) {
60         mCallbackV12.onNetworkRemoved(id);
61     }
62 
63     @Override
onStateChanged(int newState, byte[ ] bssid, int id, ArrayList<Byte> ssid)64     public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
65             ArrayList<Byte> ssid) {
66         mCallbackV12.onStateChanged(newState, bssid, id, ssid);
67     }
68 
69     @Override
onAnqpQueryDone(byte[ ] bssid, ISupplicantStaIfaceCallback.AnqpData data, ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data)70     public void onAnqpQueryDone(byte[/* 6 */] bssid,
71             ISupplicantStaIfaceCallback.AnqpData data,
72             ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
73         mCallbackV12.onAnqpQueryDone(bssid, data, hs20Data);
74     }
75 
76     @Override
onHs20IconQueryDone(byte[ ] bssid, String fileName, ArrayList<Byte> data)77     public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
78             ArrayList<Byte> data) {
79         mCallbackV12.onHs20IconQueryDone(bssid, fileName, data);
80     }
81 
82     @Override
onHs20SubscriptionRemediation(byte[ ] bssid, byte osuMethod, String url)83     public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid,
84             byte osuMethod, String url) {
85         mCallbackV12.onHs20SubscriptionRemediation(bssid, osuMethod, url);
86     }
87 
88     @Override
onHs20DeauthImminentNotice(byte[ ] bssid, int reasonCode, int reAuthDelayInSec, String url)89     public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
90             int reAuthDelayInSec, String url) {
91         mCallbackV12.onHs20DeauthImminentNotice(bssid, reasonCode, reAuthDelayInSec, url);
92     }
93 
94     @Override
onDisconnected(byte[ ] bssid, boolean locallyGenerated, int reasonCode)95     public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated,
96             int reasonCode) {
97         mCallbackV12.onDisconnected(bssid, locallyGenerated, reasonCode);
98     }
99 
100     @Override
onAssociationRejected(byte[ ] bssid, int statusCode, boolean timedOut)101     public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode,
102             boolean timedOut) {
103         mCallbackV12.onAssociationRejected(bssid, statusCode, timedOut);
104     }
105 
106     @Override
onAuthenticationTimeout(byte[ ] bssid)107     public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
108         mCallbackV12.onAuthenticationTimeout(bssid);
109     }
110 
111     @Override
onBssidChanged(byte reason, byte[ ] bssid)112     public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
113         mCallbackV12.onBssidChanged(reason, bssid);
114     }
115 
116     @Override
onEapFailure()117     public void onEapFailure() {
118         mCallbackV12.onEapFailure();
119     }
120 
121     @Override
onEapFailure_1_1(int code)122     public void onEapFailure_1_1(int code) {
123         mCallbackV12.onEapFailure_1_1(code);
124     }
125 
126     @Override
onEapFailure_1_3(int code)127     public void onEapFailure_1_3(int code) {
128         mCallbackV12.onEapFailure_1_1(code);
129     }
130 
131     @Override
onWpsEventSuccess()132     public void onWpsEventSuccess() {
133         mCallbackV12.onWpsEventSuccess();
134     }
135 
136     @Override
onWpsEventFail(byte[ ] bssid, short configError, short errorInd)137     public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
138         mCallbackV12.onWpsEventFail(bssid, configError, errorInd);
139     }
140 
141     @Override
onWpsEventPbcOverlap()142     public void onWpsEventPbcOverlap() {
143         mCallbackV12.onWpsEventPbcOverlap();
144     }
145 
146     @Override
onExtRadioWorkStart(int id)147     public void onExtRadioWorkStart(int id) {
148         mCallbackV12.onExtRadioWorkStart(id);
149     }
150 
151     @Override
onExtRadioWorkTimeout(int id)152     public void onExtRadioWorkTimeout(int id) {
153         mCallbackV12.onExtRadioWorkTimeout(id);
154     }
155 
156     @Override
onDppSuccessConfigReceived(ArrayList<Byte> ssid, String password, byte[] psk, int securityAkm)157     public void onDppSuccessConfigReceived(ArrayList<Byte> ssid, String password,
158             byte[] psk, int securityAkm) {
159         mCallbackV12.onDppSuccessConfigReceived(
160                 ssid, password, psk, securityAkm);
161     }
162 
163     @Override
onDppSuccessConfigSent()164     public void onDppSuccessConfigSent() {
165         mCallbackV12.onDppSuccessConfigSent();
166     }
167 
168     @Override
onDppProgress(int code)169     public void onDppProgress(int code) {
170         mCallbackV12.onDppProgressInternal(halToFrameworkDppProgressCode(code));
171     }
172 
173     @Override
onDppFailure(int code)174     public void onDppFailure(int code) {
175         // Convert HIDL to framework DppFailureCode, then continue with callback
176         onDppFailureInternal(halToFrameworkDppFailureCode(code));
177     }
178 
onDppFailureInternal(int frameworkCode)179     protected void onDppFailureInternal(int frameworkCode) {
180         mCallbackV12.onDppFailureInternal(frameworkCode);
181     }
182 
183     @Override
onPmkCacheAdded(long expirationTimeInSec, ArrayList<Byte> serializedEntry)184     public void onPmkCacheAdded(long expirationTimeInSec, ArrayList<Byte> serializedEntry) {
185         WifiConfiguration curConfig = mStaIfaceHal.getCurrentNetworkLocalConfig(mIfaceName);
186 
187         if (curConfig == null) return;
188 
189         SecurityParams params = curConfig.getNetworkSelectionStatus().getCandidateSecurityParams();
190         if (params == null || params.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)) return;
191 
192         mStaIfaceHal.addPmkCacheEntry(mIfaceName,
193                 curConfig.networkId, expirationTimeInSec, serializedEntry);
194         mStaIfaceHal.logCallback(
195                 "onPmkCacheAdded: update pmk cache for config id "
196                 + curConfig.networkId
197                 + " on "
198                 + mIfaceName);
199     }
200 
201     @Override
onDppProgress_1_3(int code)202     public void onDppProgress_1_3(int code) {
203         if (mStaIfaceHal.getDppCallback() != null) {
204             mStaIfaceHal.getDppCallback().onProgress(halToFrameworkDppProgressCode(code));
205         } else {
206             Log.e(TAG, "onDppProgress callback is null");
207         }
208     }
209 
210     @Override
onDppFailure_1_3(int code, String ssid, String channelList, ArrayList<Short> bandList)211     public void onDppFailure_1_3(int code, String ssid, String channelList,
212             ArrayList<Short> bandList) {
213         // Convert HIDL to framework DppFailureCode, then continue with callback
214         onDppFailureInternal_1_3(halToFrameworkDppFailureCode(code), ssid, channelList, bandList);
215     }
216 
onDppFailureInternal_1_3(int frameworkCode, String ssid, String channelList, ArrayList<Short> bandList)217     protected void onDppFailureInternal_1_3(int frameworkCode, String ssid, String channelList,
218             ArrayList<Short> bandList) {
219         if (mStaIfaceHal.getDppCallback() != null) {
220             int[] bandListArray = null;
221 
222             // Convert operating class list to a primitive array
223             if (bandList != null) {
224                 bandListArray = new int[bandList.size()];
225 
226                 for (int i = 0; i < bandList.size(); i++) {
227                     bandListArray[i] = bandList.get(i).intValue();
228                 }
229             }
230             mStaIfaceHal.getDppCallback().onFailure(
231                     frameworkCode, ssid, channelList, bandListArray);
232         } else {
233             Log.e(TAG, "onDppFailure callback is null");
234         }
235     }
236 
237     @Override
onDppSuccess(int code)238     public void onDppSuccess(int code) {
239         if (mStaIfaceHal.getDppCallback() != null) {
240             mStaIfaceHal.getDppCallback().onSuccess(halToFrameworkDppEventType(code));
241         } else {
242             Log.e(TAG, "onDppSuccess callback is null");
243         }
244     }
245 
246     @Override
onBssTmHandlingDone(BssTmData tmData)247     public void onBssTmHandlingDone(BssTmData tmData) {
248         MboOceController.BtmFrameData btmFrmData = new MboOceController.BtmFrameData();
249 
250         btmFrmData.mStatus = halToFrameworkBtmResponseStatus(tmData.status);
251         btmFrmData.mBssTmDataFlagsMask = halToFrameworkBssTmDataFlagsMask(tmData.flags);
252         btmFrmData.mBlockListDurationMs = tmData.assocRetryDelayMs;
253         if ((tmData.flags & BssTmDataFlagsMask.MBO_TRANSITION_REASON_CODE_INCLUDED) != 0) {
254             btmFrmData.mTransitionReason = halToFrameworkMboTransitionReason(
255                     tmData.mboTransitionReason);
256         }
257         if ((tmData.flags
258                 & BssTmDataFlagsMask.MBO_CELLULAR_DATA_CONNECTION_PREFERENCE_INCLUDED) != 0) {
259             btmFrmData.mCellPreference =
260                     halToFrameworkMboCellularDataConnectionPreference(tmData.mboCellPreference);
261         }
262         mStaIfaceHal.logCallback(
263                 "onBssTmHandlingDone: Handle BTM handling event");
264         mWifiMonitor.broadcastBssTmHandlingDoneEvent(mIfaceName, btmFrmData);
265     }
266 
halToFrameworkBtmResponseStatus(int status)267     private @MboOceConstants.BtmResponseStatus int halToFrameworkBtmResponseStatus(int status) {
268         switch (status) {
269             case BssTmStatusCode.ACCEPT:
270                 return MboOceConstants.BTM_RESPONSE_STATUS_ACCEPT;
271             case BssTmStatusCode.REJECT_UNSPECIFIED:
272                 return MboOceConstants.BTM_RESPONSE_STATUS_REJECT_UNSPECIFIED;
273             case BssTmStatusCode.REJECT_INSUFFICIENT_BEACON:
274                 return MboOceConstants.BTM_RESPONSE_STATUS_REJECT_INSUFFICIENT_BEACON;
275             case BssTmStatusCode.REJECT_INSUFFICIENT_CAPABITY:
276                 return MboOceConstants.BTM_RESPONSE_STATUS_REJECT_INSUFFICIENT_CAPABITY;
277             case BssTmStatusCode.REJECT_BSS_TERMINATION_UNDESIRED:
278                 return MboOceConstants.BTM_RESPONSE_STATUS_REJECT_BSS_TERMINATION_UNDESIRED;
279             case BssTmStatusCode.REJECT_BSS_TERMINATION_DELAY_REQUEST:
280                 return MboOceConstants.BTM_RESPONSE_STATUS_REJECT_BSS_TERMINATION_DELAY_REQUEST;
281             case BssTmStatusCode.REJECT_STA_CANDIDATE_LIST_PROVIDED:
282                 return MboOceConstants.BTM_RESPONSE_STATUS_REJECT_STA_CANDIDATE_LIST_PROVIDED;
283             case BssTmStatusCode.REJECT_NO_SUITABLE_CANDIDATES:
284                 return MboOceConstants.BTM_RESPONSE_STATUS_REJECT_NO_SUITABLE_CANDIDATES;
285             case BssTmStatusCode.REJECT_LEAVING_ESS:
286                 return MboOceConstants.BTM_RESPONSE_STATUS_REJECT_LEAVING_ESS;
287             default:
288                 return MboOceConstants.BTM_RESPONSE_STATUS_REJECT_RESERVED;
289         }
290     }
291 
halToFrameworkBssTmDataFlagsMask(int flags)292     private int halToFrameworkBssTmDataFlagsMask(int flags) {
293         int tmDataflags = 0;
294         if ((flags & BssTmDataFlagsMask.WNM_MODE_PREFERRED_CANDIDATE_LIST_INCLUDED) != 0) {
295             tmDataflags |= MboOceConstants.BTM_DATA_FLAG_PREFERRED_CANDIDATE_LIST_INCLUDED;
296         }
297         if ((flags & BssTmDataFlagsMask.WNM_MODE_ABRIDGED) != 0) {
298             tmDataflags |= MboOceConstants.BTM_DATA_FLAG_MODE_ABRIDGED;
299         }
300         if ((flags & BssTmDataFlagsMask.WNM_MODE_DISASSOCIATION_IMMINENT) != 0) {
301             tmDataflags |= MboOceConstants.BTM_DATA_FLAG_DISASSOCIATION_IMMINENT;
302         }
303         if ((flags & BssTmDataFlagsMask.WNM_MODE_BSS_TERMINATION_INCLUDED) != 0) {
304             tmDataflags |= MboOceConstants.BTM_DATA_FLAG_BSS_TERMINATION_INCLUDED;
305         }
306         if ((flags & BssTmDataFlagsMask.WNM_MODE_ESS_DISASSOCIATION_IMMINENT) != 0) {
307             tmDataflags |= MboOceConstants.BTM_DATA_FLAG_ESS_DISASSOCIATION_IMMINENT;
308         }
309         if ((flags & BssTmDataFlagsMask.MBO_TRANSITION_REASON_CODE_INCLUDED) != 0) {
310             tmDataflags |= MboOceConstants.BTM_DATA_FLAG_MBO_TRANSITION_REASON_CODE_INCLUDED;
311         }
312         if ((flags & BssTmDataFlagsMask.MBO_ASSOC_RETRY_DELAY_INCLUDED) != 0) {
313             tmDataflags |= MboOceConstants.BTM_DATA_FLAG_MBO_ASSOC_RETRY_DELAY_INCLUDED;
314         }
315         if ((flags & BssTmDataFlagsMask.MBO_CELLULAR_DATA_CONNECTION_PREFERENCE_INCLUDED) != 0) {
316             tmDataflags |=
317                     MboOceConstants.BTM_DATA_FLAG_MBO_CELL_DATA_CONNECTION_PREFERENCE_INCLUDED;
318         }
319         return tmDataflags;
320     }
321 
halToFrameworkMboTransitionReason( int reason)322     private @MboOceConstants.MboTransitionReason int halToFrameworkMboTransitionReason(
323             int reason) {
324         switch (reason) {
325             case MboTransitionReasonCode.UNSPECIFIED:
326                 return MboOceConstants.MBO_TRANSITION_REASON_UNSPECIFIED;
327             case MboTransitionReasonCode.EXCESSIVE_FRAME_LOSS:
328                 return MboOceConstants.MBO_TRANSITION_REASON_EXCESSIVE_FRAME_LOSS;
329             case MboTransitionReasonCode.EXCESSIVE_TRAFFIC_DELAY:
330                 return MboOceConstants.MBO_TRANSITION_REASON_EXCESSIVE_TRAFFIC_DELAY;
331             case MboTransitionReasonCode.INSUFFICIENT_BANDWIDTH:
332                 return MboOceConstants.MBO_TRANSITION_REASON_INSUFFICIENT_BANDWIDTH;
333             case MboTransitionReasonCode.LOAD_BALANCING:
334                 return MboOceConstants.MBO_TRANSITION_REASON_LOAD_BALANCING;
335             case MboTransitionReasonCode.LOW_RSSI:
336                 return MboOceConstants.MBO_TRANSITION_REASON_LOW_RSSI;
337             case MboTransitionReasonCode.RX_EXCESSIVE_RETRIES:
338                 return MboOceConstants.MBO_TRANSITION_REASON_RX_EXCESSIVE_RETRIES;
339             case MboTransitionReasonCode.HIGH_INTERFERENCE:
340                 return MboOceConstants.MBO_TRANSITION_REASON_HIGH_INTERFERENCE;
341             case MboTransitionReasonCode.GRAY_ZONE:
342                 return MboOceConstants.MBO_TRANSITION_REASON_GRAY_ZONE;
343             default:
344                 return MboOceConstants.MBO_TRANSITION_REASON_RESERVED;
345         }
346     }
347 
348     private @MboOceConstants.MboTransitionReason int
halToFrameworkMboCellularDataConnectionPreference(int cellPref)349             halToFrameworkMboCellularDataConnectionPreference(int cellPref) {
350         switch (cellPref) {
351             case MboCellularDataConnectionPrefValue.EXCLUDED:
352                 return MboOceConstants.MBO_CELLULAR_DATA_CONNECTION_EXCLUDED;
353             case MboCellularDataConnectionPrefValue.NOT_PREFERRED:
354                 return MboOceConstants.MBO_CELLULAR_DATA_CONNECTION_NOT_PREFERRED;
355             case MboCellularDataConnectionPrefValue.PREFERRED:
356                 return MboOceConstants.MBO_CELLULAR_DATA_CONNECTION_PREFERRED;
357             default:
358                 return MboOceConstants.MBO_CELLULAR_DATA_CONNECTION_RESERVED;
359         }
360     }
361 
halToFrameworkDppEventType(int dppSuccessCode)362     private int halToFrameworkDppEventType(int dppSuccessCode) {
363         switch(dppSuccessCode) {
364             case DppSuccessCode.CONFIGURATION_SENT:
365                 return SupplicantStaIfaceHal.DppEventType.CONFIGURATION_SENT;
366             case DppSuccessCode.CONFIGURATION_APPLIED:
367                 return SupplicantStaIfaceHal.DppEventType.CONFIGURATION_APPLIED;
368             default:
369                 Log.e(TAG, "Invalid DppEventType received");
370                 return -1;
371         }
372     }
373 
halToFrameworkDppFailureCode(int failureCode)374     private int halToFrameworkDppFailureCode(int failureCode) {
375         switch(failureCode) {
376             case DppFailureCode.INVALID_URI:
377                 return SupplicantStaIfaceHal.DppFailureCode.INVALID_URI;
378             case DppFailureCode.AUTHENTICATION:
379                 return SupplicantStaIfaceHal.DppFailureCode.AUTHENTICATION;
380             case DppFailureCode.NOT_COMPATIBLE:
381                 return SupplicantStaIfaceHal.DppFailureCode.NOT_COMPATIBLE;
382             case DppFailureCode.CONFIGURATION:
383                 return SupplicantStaIfaceHal.DppFailureCode.CONFIGURATION;
384             case DppFailureCode.BUSY:
385                 return SupplicantStaIfaceHal.DppFailureCode.BUSY;
386             case DppFailureCode.TIMEOUT:
387                 return SupplicantStaIfaceHal.DppFailureCode.TIMEOUT;
388             case DppFailureCode.FAILURE:
389                 return SupplicantStaIfaceHal.DppFailureCode.FAILURE;
390             case DppFailureCode.NOT_SUPPORTED:
391                 return SupplicantStaIfaceHal.DppFailureCode.NOT_SUPPORTED;
392             case DppFailureCode.CONFIGURATION_REJECTED:
393                 return SupplicantStaIfaceHal.DppFailureCode.CONFIGURATION_REJECTED;
394             case DppFailureCode.CANNOT_FIND_NETWORK:
395                 return SupplicantStaIfaceHal.DppFailureCode.CANNOT_FIND_NETWORK;
396             case DppFailureCode.ENROLLEE_AUTHENTICATION:
397                 return SupplicantStaIfaceHal.DppFailureCode.ENROLLEE_AUTHENTICATION;
398             default:
399                 Log.e(TAG, "Invalid DppFailureCode received");
400                 return -1;
401         }
402     }
403 
halToFrameworkDppProgressCode(int progressCode)404     private int halToFrameworkDppProgressCode(int progressCode) {
405         switch(progressCode) {
406             case DppProgressCode.AUTHENTICATION_SUCCESS:
407                 return SupplicantStaIfaceHal.DppProgressCode.AUTHENTICATION_SUCCESS;
408             case DppProgressCode.RESPONSE_PENDING:
409                 return SupplicantStaIfaceHal.DppProgressCode.RESPONSE_PENDING;
410             case DppProgressCode.CONFIGURATION_SENT_WAITING_RESPONSE:
411                 return SupplicantStaIfaceHal.DppProgressCode.CONFIGURATION_SENT_WAITING_RESPONSE;
412             case DppProgressCode.CONFIGURATION_ACCEPTED:
413                 return SupplicantStaIfaceHal.DppProgressCode.CONFIGURATION_ACCEPTED;
414             default:
415                 Log.e(TAG, "Invalid DppProgressCode received");
416                 return -1;
417         }
418     }
419 
420     @Override
onStateChanged_1_3(int newState, byte[ ] bssid, int id, ArrayList<Byte> ssid, boolean filsHlpSent)421     public void onStateChanged_1_3(int newState, byte[/* 6 */] bssid, int id,
422             ArrayList<Byte> ssid, boolean filsHlpSent) {
423         mCallbackV12.onStateChanged(newState, bssid, id, ssid, filsHlpSent);
424     }
425 }
426