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 import android.annotation.NonNull;
19 import android.content.Context;
20 import android.hardware.wifi.supplicant.V1_0.ISupplicantStaIfaceCallback;
21 import android.hardware.wifi.supplicant.V1_2.DppAkm;
22 import android.hardware.wifi.supplicant.V1_2.DppFailureCode;
23 import android.hardware.wifi.supplicant.V1_2.DppProgressCode;
24 import android.net.wifi.WifiConfiguration;
25 import android.net.wifi.WifiSsid;
26 import android.os.Process;
27 import android.util.Log;
28 
29 import com.android.server.wifi.util.NativeUtil;
30 
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 
34 abstract class SupplicantStaIfaceCallbackHidlV1_2Impl extends
35         android.hardware.wifi.supplicant.V1_2.ISupplicantStaIfaceCallback.Stub {
36     private static final String TAG = SupplicantStaIfaceCallbackHidlV1_2Impl.class.getSimpleName();
37     private final SupplicantStaIfaceHalHidlImpl mStaIfaceHal;
38     private final String mIfaceName;
39     private final Context mContext;
40     private final @NonNull SsidTranslator mSsidTranslator;
41     private final SupplicantStaIfaceHalHidlImpl.SupplicantStaIfaceHalCallbackV1_1 mCallbackV11;
42 
SupplicantStaIfaceCallbackHidlV1_2Impl(@onNull SupplicantStaIfaceHalHidlImpl staIfaceHal, @NonNull String ifaceName, @NonNull Context context, @NonNull SsidTranslator ssidTranslator)43     SupplicantStaIfaceCallbackHidlV1_2Impl(@NonNull SupplicantStaIfaceHalHidlImpl staIfaceHal,
44             @NonNull String ifaceName,
45             @NonNull Context context,
46             @NonNull SsidTranslator ssidTranslator) {
47         mStaIfaceHal = staIfaceHal;
48         mIfaceName = ifaceName;
49         mContext = context;
50         mSsidTranslator = ssidTranslator;
51         // Create an older callback for function delegation,
52         // and it would cascadingly create older one.
53         mCallbackV11 = mStaIfaceHal.new SupplicantStaIfaceHalCallbackV1_1(mIfaceName);
54     }
55 
getCallbackV10()56     public SupplicantStaIfaceHalHidlImpl.SupplicantStaIfaceHalCallback getCallbackV10() {
57         return mCallbackV11.getCallbackV10();
58     }
59 
60     @Override
onNetworkAdded(int id)61     public void onNetworkAdded(int id) {
62         mCallbackV11.onNetworkAdded(id);
63     }
64 
65     @Override
onNetworkRemoved(int id)66     public void onNetworkRemoved(int id) {
67         mCallbackV11.onNetworkRemoved(id);
68     }
69 
70     /**
71      * Added to plumb the new {@code filsHlpSent} param from the V1.3 callback version.
72      */
onStateChanged(int newState, byte[ ] bssid, int id, ArrayList<Byte> ssid, boolean filsHlpSent)73     public void onStateChanged(int newState, byte[/* 6 */] bssid, int id, ArrayList<Byte> ssid,
74             boolean filsHlpSent) {
75         mCallbackV11.onStateChanged(newState, bssid, id, ssid, filsHlpSent);
76     }
77 
78     @Override
onStateChanged(int newState, byte[ ] bssid, int id, ArrayList<Byte> ssid)79     public void onStateChanged(int newState, byte[/* 6 */] bssid, int id,
80             ArrayList<Byte> ssid) {
81         onStateChanged(newState, bssid, id, ssid, false);
82     }
83 
84     @Override
onAnqpQueryDone(byte[ ] bssid, ISupplicantStaIfaceCallback.AnqpData data, ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data)85     public void onAnqpQueryDone(byte[/* 6 */] bssid,
86             ISupplicantStaIfaceCallback.AnqpData data,
87             ISupplicantStaIfaceCallback.Hs20AnqpData hs20Data) {
88         mCallbackV11.onAnqpQueryDone(bssid, data, hs20Data);
89     }
90 
91     @Override
onHs20IconQueryDone(byte[ ] bssid, String fileName, ArrayList<Byte> data)92     public void onHs20IconQueryDone(byte[/* 6 */] bssid, String fileName,
93             ArrayList<Byte> data) {
94         mCallbackV11.onHs20IconQueryDone(bssid, fileName, data);
95     }
96 
97     @Override
onHs20SubscriptionRemediation(byte[ ] bssid, byte osuMethod, String url)98     public void onHs20SubscriptionRemediation(byte[/* 6 */] bssid,
99             byte osuMethod, String url) {
100         mCallbackV11.onHs20SubscriptionRemediation(bssid, osuMethod, url);
101     }
102 
103     @Override
onHs20DeauthImminentNotice(byte[ ] bssid, int reasonCode, int reAuthDelayInSec, String url)104     public void onHs20DeauthImminentNotice(byte[/* 6 */] bssid, int reasonCode,
105             int reAuthDelayInSec, String url) {
106         mCallbackV11.onHs20DeauthImminentNotice(bssid, reasonCode, reAuthDelayInSec, url);
107     }
108 
109     @Override
onDisconnected(byte[ ] bssid, boolean locallyGenerated, int reasonCode)110     public void onDisconnected(byte[/* 6 */] bssid, boolean locallyGenerated,
111             int reasonCode) {
112         mCallbackV11.onDisconnected(bssid, locallyGenerated, reasonCode);
113     }
114 
115     @Override
onAssociationRejected(byte[ ] bssid, int statusCode, boolean timedOut)116     public void onAssociationRejected(byte[/* 6 */] bssid, int statusCode,
117             boolean timedOut) {
118         mCallbackV11.onAssociationRejected(bssid, statusCode, timedOut);
119     }
120 
121     @Override
onAuthenticationTimeout(byte[ ] bssid)122     public void onAuthenticationTimeout(byte[/* 6 */] bssid) {
123         mCallbackV11.onAuthenticationTimeout(bssid);
124     }
125 
126     @Override
onBssidChanged(byte reason, byte[ ] bssid)127     public void onBssidChanged(byte reason, byte[/* 6 */] bssid) {
128         mCallbackV11.onBssidChanged(reason, bssid);
129     }
130 
131     @Override
onEapFailure()132     public void onEapFailure() {
133         mCallbackV11.onEapFailure();
134     }
135 
136     @Override
onEapFailure_1_1(int code)137     public void onEapFailure_1_1(int code) {
138         mCallbackV11.onEapFailure_1_1(code);
139     }
140 
141     @Override
onWpsEventSuccess()142     public void onWpsEventSuccess() {
143         mCallbackV11.onWpsEventSuccess();
144     }
145 
146     @Override
onWpsEventFail(byte[ ] bssid, short configError, short errorInd)147     public void onWpsEventFail(byte[/* 6 */] bssid, short configError, short errorInd) {
148         mCallbackV11.onWpsEventFail(bssid, configError, errorInd);
149     }
150 
151     @Override
onWpsEventPbcOverlap()152     public void onWpsEventPbcOverlap() {
153         mCallbackV11.onWpsEventPbcOverlap();
154     }
155 
156     @Override
onExtRadioWorkStart(int id)157     public void onExtRadioWorkStart(int id) {
158         mCallbackV11.onExtRadioWorkStart(id);
159     }
160 
161     @Override
onExtRadioWorkTimeout(int id)162     public void onExtRadioWorkTimeout(int id) {
163         mCallbackV11.onExtRadioWorkTimeout(id);
164     }
165 
166     @Override
onDppSuccessConfigReceived(ArrayList<Byte> ssid, String password, byte[] psk, int securityAkm)167     public void onDppSuccessConfigReceived(ArrayList<Byte> ssid, String password,
168             byte[] psk, int securityAkm) {
169         if (mStaIfaceHal.getDppCallback() == null) {
170             Log.e(TAG, "onDppSuccessConfigReceived callback is null");
171             return;
172         }
173 
174         WifiConfiguration newWifiConfiguration = new WifiConfiguration();
175 
176         // Set up SSID
177         WifiSsid wifiSsid = mSsidTranslator.getTranslatedSsid(
178                 WifiSsid.fromBytes(NativeUtil.byteArrayFromArrayList(ssid)));
179 
180         newWifiConfiguration.SSID = wifiSsid.toString();
181 
182         // Set up password or PSK
183         if (password != null) {
184             newWifiConfiguration.preSharedKey = "\"" + password + "\"";
185         } else if (psk != null) {
186             newWifiConfiguration.preSharedKey = Arrays.toString(psk);
187         }
188 
189         // Set up key management: SAE or PSK
190         if (securityAkm == DppAkm.SAE) {
191             newWifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE);
192         } else if (securityAkm == DppAkm.PSK_SAE || securityAkm == DppAkm.PSK) {
193             newWifiConfiguration.setSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK);
194         } else {
195             // No other AKMs are currently supported
196             onDppFailure(DppFailureCode.NOT_SUPPORTED);
197             return;
198         }
199 
200         // Set up default values
201         newWifiConfiguration.creatorName = mContext.getPackageManager()
202                 .getNameForUid(Process.WIFI_UID);
203         newWifiConfiguration.status = WifiConfiguration.Status.ENABLED;
204 
205         mStaIfaceHal.getDppCallback().onSuccessConfigReceived(newWifiConfiguration,
206                 false);
207     }
208 
209     @Override
onDppSuccessConfigSent()210     public void onDppSuccessConfigSent() {
211         if (mStaIfaceHal.getDppCallback() != null) {
212             mStaIfaceHal.getDppCallback().onSuccess(
213                     SupplicantStaIfaceHal.DppEventType.CONFIGURATION_SENT);
214         } else {
215             Log.e(TAG, "onSuccessConfigSent callback is null");
216         }
217     }
218 
219     @Override
onDppFailure(int code)220     public void onDppFailure(int code) {
221         // Convert HIDL to framework DppFailureCode, then continue with callback
222         onDppFailureInternal(halToFrameworkDppFailureCode(code));
223     }
224 
onDppFailureInternal(int frameworkCode)225     protected void onDppFailureInternal(int frameworkCode) {
226         if (mStaIfaceHal.getDppCallback() != null) {
227             mStaIfaceHal.getDppCallback().onFailure(frameworkCode, null, null, null);
228         } else {
229             Log.e(TAG, "onDppFailure callback is null");
230         }
231     }
232 
233     @Override
onDppProgress(int code)234     public void onDppProgress(int code) {
235         // Convert HIDL to framework DppProgressCode, then continue with callback
236         onDppProgressInternal(halToFrameworkDppProgressCode(code));
237     }
238 
onDppProgressInternal(int frameworkCode)239     protected void onDppProgressInternal(int frameworkCode) {
240         if (mStaIfaceHal.getDppCallback() != null) {
241             mStaIfaceHal.getDppCallback().onProgress(frameworkCode);
242         } else {
243             Log.e(TAG, "onDppProgress callback is null");
244         }
245     }
246 
halToFrameworkDppProgressCode(int progressCode)247     private int halToFrameworkDppProgressCode(int progressCode) {
248         switch(progressCode) {
249             case DppProgressCode.AUTHENTICATION_SUCCESS:
250                 return SupplicantStaIfaceHal.DppProgressCode.AUTHENTICATION_SUCCESS;
251             case DppProgressCode.RESPONSE_PENDING:
252                 return SupplicantStaIfaceHal.DppProgressCode.RESPONSE_PENDING;
253             default:
254                 Log.e(TAG, "Invalid DppProgressCode received");
255                 return -1;
256         }
257     }
258 
halToFrameworkDppFailureCode(int failureCode)259     private int halToFrameworkDppFailureCode(int failureCode) {
260         switch(failureCode) {
261             case DppFailureCode.INVALID_URI:
262                 return SupplicantStaIfaceHal.DppFailureCode.INVALID_URI;
263             case DppFailureCode.AUTHENTICATION:
264                 return SupplicantStaIfaceHal.DppFailureCode.AUTHENTICATION;
265             case DppFailureCode.NOT_COMPATIBLE:
266                 return SupplicantStaIfaceHal.DppFailureCode.NOT_COMPATIBLE;
267             case DppFailureCode.CONFIGURATION:
268                 return SupplicantStaIfaceHal.DppFailureCode.CONFIGURATION;
269             case DppFailureCode.BUSY:
270                 return SupplicantStaIfaceHal.DppFailureCode.BUSY;
271             case DppFailureCode.TIMEOUT:
272                 return SupplicantStaIfaceHal.DppFailureCode.TIMEOUT;
273             case DppFailureCode.FAILURE:
274                 return SupplicantStaIfaceHal.DppFailureCode.FAILURE;
275             case DppFailureCode.NOT_SUPPORTED:
276                 return SupplicantStaIfaceHal.DppFailureCode.NOT_SUPPORTED;
277             default:
278                 Log.e(TAG, "Invalid DppFailureCode received");
279                 return -1;
280         }
281     }
282 }
283