WifiVendorHal.java revision 8c6d09c03532b3936fab2fed6f8b84c895333565
1/*
2 * Copyright (C) 2017 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 */
16package com.android.server.wifi;
17
18import android.annotation.Nullable;
19import android.hardware.wifi.V1_0.IWifiApIface;
20import android.hardware.wifi.V1_0.IWifiChip;
21import android.hardware.wifi.V1_0.IWifiIface;
22import android.hardware.wifi.V1_0.IWifiRttController;
23import android.hardware.wifi.V1_0.IWifiStaIface;
24import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats;
25import android.hardware.wifi.V1_0.WifiStatus;
26import android.net.apf.ApfCapabilities;
27import android.net.wifi.RttManager;
28import android.net.wifi.RttManager.ResponderConfig;
29import android.net.wifi.WifiLinkLayerStats;
30import android.net.wifi.WifiScanner;
31import android.net.wifi.WifiWakeReasonAndCounts;
32import android.os.HandlerThread;
33import android.os.RemoteException;
34import android.util.Log;
35
36import com.android.server.connectivity.KeepalivePacketData;
37
38/**
39 * Vendor HAL via HIDL
40 */
41public class WifiVendorHal {
42
43    private static final String TAG = "WifiVendorHal";
44
45    // Vendor HAL HIDL interface objects.
46    private IWifiChip mIWifiChip;
47    private IWifiStaIface mIWifiStaIface;
48    private IWifiApIface mIWifiApIface;
49    private IWifiRttController mIWifiRttController;
50    private final HalDeviceManager mHalDeviceManager;
51    private final HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
52    private final HandlerThread mWifiStateMachineHandlerThread;
53
54    public WifiVendorHal(HalDeviceManager halDeviceManager,
55                         HandlerThread wifiStateMachineHandlerThread) {
56        mHalDeviceManager = halDeviceManager;
57        mWifiStateMachineHandlerThread = wifiStateMachineHandlerThread;
58        mHalDeviceManagerStatusCallbacks = new HalDeviceManagerStatusListener();
59    }
60
61    private void handleRemoteException(RemoteException e) {
62        kilroy();
63        Log.e(TAG, "RemoteException in HIDL call " + e);
64    }
65
66    private void noteHidlError(WifiStatus status, String culprit) {
67        kilroy();
68        Log.e(TAG, "Error in " + culprit + " code: " + status.code
69                + " (" + status.description + ")");
70    }
71
72    /**
73     * Initialize the Hal device manager and register for status callbacks.
74     * @return
75     */
76    public boolean initialize() {
77        mHalDeviceManager.initialize();
78        mHalDeviceManager.registerStatusListener(
79                mHalDeviceManagerStatusCallbacks, mWifiStateMachineHandlerThread.getLooper());
80        return true;
81    }
82
83    /**
84     * Bring up the HIDL Vendor HAL and configure for STA mode or AP mode.
85     *
86     * @param isStaMode true to start HAL in STA mode, false to start in AP mode.
87     */
88    public boolean startVendorHal(boolean isStaMode) {
89        if (!mHalDeviceManager.start()) {
90            Log.e(TAG, "Failed to start the vendor HAL");
91            return false;
92        }
93        if (isStaMode) {
94            mIWifiStaIface = mHalDeviceManager.createStaIface(null, null);
95            if (mIWifiStaIface == null) {
96                Log.e(TAG, "Failed to create STA Iface");
97                return false;
98            }
99        } else {
100            mIWifiApIface = mHalDeviceManager.createApIface(null, null);
101            if (mIWifiApIface == null) {
102                Log.e(TAG, "Failed to create AP Iface");
103                return false;
104            }
105        }
106        IWifiIface iface = (IWifiIface) (mIWifiStaIface != null ? mIWifiStaIface : mIWifiApIface);
107        mIWifiChip = mHalDeviceManager.getChip(iface);
108        if (mIWifiStaIface == null) {
109            Log.e(TAG, "Failed to get the chip created for the Iface");
110            return false;
111        }
112        return true;
113    }
114
115    /**
116     * Stops the HAL
117     */
118    public void stopVendorHal() {
119        mHalDeviceManager.stop();
120    }
121
122    /**
123     * Tests whether the HAL is running or not
124     */
125    public boolean isHalStarted() {
126        return (mIWifiStaIface != null || mIWifiApIface != null);
127    }
128
129    /**
130     * Gets the scan capabilities
131     *
132     * @param capabilities object to be filled in
133     * @return true for success. false for failure
134     */
135    public boolean getScanCapabilities(WifiNative.ScanCapabilities capabilities) {
136        kilroy();
137        throw new UnsupportedOperationException();
138    }
139
140    /**
141     * to be implemented
142     */
143    public boolean startScan(WifiNative.ScanSettings settings,
144                             WifiNative.ScanEventHandler eventHandler) {
145        kilroy();
146        throw new UnsupportedOperationException();
147    }
148
149    /**
150     * to be implemented
151     */
152    public void stopScan() {
153        kilroy();
154        throw new UnsupportedOperationException();
155    }
156
157    /**
158     * to be implemented
159     */
160    public void pauseScan() {
161        kilroy();
162        throw new UnsupportedOperationException();
163    }
164
165    /**
166     * to be implemented
167     */
168    public void restartScan() {
169        kilroy();
170        throw new UnsupportedOperationException();
171    }
172
173    /**
174     * to be implemented
175     */
176    public WifiScanner.ScanData[] getScanResults(boolean flush) {
177        kilroy();
178        throw new UnsupportedOperationException();
179    }
180
181    /**
182     * Get the link layer statistics
183     *
184     * @param iface is the name of the wifi interface (checked for null, otherwise ignored)
185     * @return the statistics, or null if unable to do so
186     */
187    public WifiLinkLayerStats getWifiLinkLayerStats(String iface) {
188        kilroy();
189        throw new UnsupportedOperationException();
190    }
191
192    /**
193     * Enable link layer stats collection
194     *
195     * @param iface  is the name of the wifi interface (checked for null, otherwise ignored)
196     * @param enable must be 1
197     */
198    public void setWifiLinkLayerStats(String iface, int enable) {
199        kilroy();
200        throw new UnsupportedOperationException();
201    }
202
203    /**
204     * Get the supported features
205     *
206     * @return bitmask defined by WifiManager.WIFI_FEATURE_*
207     */
208    public int getSupportedFeatureSet() {
209        kilroy();
210        throw new UnsupportedOperationException();
211    }
212
213    /* RTT related commands/events */
214
215    /**
216     * Starts a new rtt request
217     *
218     * @param params
219     * @param handler
220     * @return success indication
221     */
222    public boolean requestRtt(RttManager.RttParams[] params, WifiNative.RttEventHandler handler) {
223        kilroy();
224        throw new UnsupportedOperationException();
225    }
226
227    /**
228     * Cancels an outstanding rtt request
229     *
230     * @param params
231     * @return true if there was an outstanding request and it was successfully cancelled
232     */
233    public boolean cancelRtt(RttManager.RttParams[] params) {
234        kilroy();
235        throw new UnsupportedOperationException();
236    }
237
238    /**
239     * Enables RTT responder role on the device.
240     *
241     * @return {@link ResponderConfig} if the responder role is successfully enabled,
242     * {@code null} otherwise.
243     */
244    @Nullable
245    public ResponderConfig enableRttResponder(int timeoutSeconds) {
246        kilroy();
247        throw new UnsupportedOperationException();
248    }
249
250    /**
251     * Disables RTT responder role.
252     *
253     * @return {@code true} if responder role is successfully disabled,
254     * {@code false} otherwise.
255     */
256    public boolean disableRttResponder() {
257        kilroy();
258        throw new UnsupportedOperationException();
259    }
260
261    /**
262     * not supported
263     */
264    public boolean setScanningMacOui(byte[] oui) {
265        kilroy();
266        throw new UnsupportedOperationException();
267    }
268
269    /**
270     * not supported
271     */
272    public int[] getChannelsForBand(int band) {
273        kilroy();
274        throw new UnsupportedOperationException();
275    }
276
277    /**
278     * not supported
279     */
280    public boolean isGetChannelsForBandSupported() {
281        kilroy();
282        throw new UnsupportedOperationException();
283    }
284
285    /**
286     * Set DFS - actually, this is always on.
287     *
288     * @param dfsOn
289     * @return success indication
290     */
291    public boolean setDfsFlag(boolean dfsOn) {
292        kilroy();
293        throw new UnsupportedOperationException();
294    }
295
296    /**
297     * RTT (Round Trip Time) measurement capabilities of the device.
298     */
299    public RttManager.RttCapabilities getRttCapabilities() {
300        kilroy();
301        throw new UnsupportedOperationException();
302    }
303
304    /**
305     * Get the APF (Android Packet Filter) capabilities of the device
306     */
307    public ApfCapabilities getApfCapabilities() {
308        kilroy();
309        throw new UnsupportedOperationException();
310    }
311
312    private static final ApfCapabilities sNoApfCapabilities = new ApfCapabilities(0, 0, 0);
313
314    /**
315     * Installs an APF program on this iface, replacing an existing
316     * program if present.
317     */
318    public boolean installPacketFilter(byte[] filter) {
319        kilroy();
320        throw new UnsupportedOperationException();
321    }
322
323
324    /**
325     * to be implemented
326     */
327    public boolean setCountryCodeHal(String countryCode) {
328        kilroy();
329        throw new UnsupportedOperationException();
330    }
331
332    /**
333     * not to be implemented
334     */
335    public boolean enableDisableTdls(boolean enable, String macAdd,
336                                     WifiNative.TdlsEventHandler tdlsCallBack) {
337        kilroy();
338        throw new UnsupportedOperationException();
339    }
340
341    /**
342     * not to be implemented
343     */
344    public WifiNative.TdlsStatus getTdlsStatus(String macAdd) {
345        kilroy();
346        throw new UnsupportedOperationException();
347    }
348
349    /**
350     * not to be implemented
351     */
352    public WifiNative.TdlsCapabilities getTdlsCapabilities() {
353        kilroy();
354        throw new UnsupportedOperationException();
355    }
356
357    /**
358     * to be implemented
359     */
360    public boolean setLoggingEventHandler(WifiNative.WifiLoggerEventHandler handler) {
361        kilroy();
362        throw new UnsupportedOperationException();
363    }
364
365    /**
366     * Control debug data collection
367     *
368     * @param verboseLevel       0 to 3, inclusive. 0 stops logging.
369     * @param flags              Ignored.
370     * @param maxIntervalInSec   Maximum interval between reports; ignore if 0.
371     * @param minDataSizeInBytes Minimum data size in buffer for report; ignore if 0.
372     * @param ringName           Name of the ring for which data collection is to start.
373     * @return true for success
374     */
375    public boolean startLoggingRingBuffer(int verboseLevel, int flags, int maxIntervalInSec,
376                                          int minDataSizeInBytes, String ringName) {
377        kilroy();
378        throw new UnsupportedOperationException();
379    }
380
381    /**
382     * Pointlessly fail
383     *
384     * @return -1
385     */
386    public int getSupportedLoggerFeatureSet() {
387        return -1;
388    }
389
390    /**
391     * to be implemented
392     */
393    public boolean resetLogHandler() {
394        kilroy();
395        throw new UnsupportedOperationException();
396    }
397
398    private String mDriverDescription;
399
400    /**
401     * Vendor-provided wifi driver version string
402     */
403    public String getDriverVersion() {
404        kilroy();
405        throw new UnsupportedOperationException();
406    }
407
408    private String mFirmwareDescription;
409
410    /**
411     * Vendor-provided wifi firmware version string
412     */
413    public String getFirmwareVersion() {
414        kilroy();
415        throw new UnsupportedOperationException();
416    }
417
418    /**
419     * API to get the status of all ring buffers supported by driver
420     */
421    public WifiNative.RingBufferStatus[] getRingBufferStatus() {
422        kilroy();
423        throw new UnsupportedOperationException();
424    }
425
426    /**
427     * indicates to driver that all
428     * the data has to be uploaded urgently
429     */
430    public boolean getRingBufferData(String ringName) {
431        kilroy();
432        throw new UnsupportedOperationException();
433    }
434
435    /**
436     * to be implemented via mIWifiChip.requestFirmwareDebugDump
437     */
438    public byte[] getFwMemoryDump() {
439        kilroy();
440        throw new UnsupportedOperationException();
441    }
442
443    /**
444     * Request vendor debug info from the driver
445     */
446    public byte[] getDriverStateDump() {
447        kilroy();
448        throw new UnsupportedOperationException();
449    }
450
451    /**
452     * Start packet fate monitoring
453     * <p>
454     * Once started, monitoring remains active until HAL is unloaded.
455     *
456     * @return true for success
457     */
458    public boolean startPktFateMonitoring() {
459        kilroy();
460        throw new UnsupportedOperationException();
461    }
462
463    /**
464     * Retrieve fates of outbound packets
465     * <p>
466     * Reports the outbound frames for the most recent association (space allowing).
467     *
468     * @param reportBufs
469     * @return true for success
470     */
471    public boolean getTxPktFates(WifiNative.TxFateReport[] reportBufs) {
472        kilroy();
473        throw new UnsupportedOperationException();
474    }
475
476    /**
477     * Retrieve fates of inbound packets
478     * <p>
479     * Reports the inbound frames for the most recent association (space allowing).
480     *
481     * @param reportBufs
482     * @return true for success
483     */
484    public boolean getRxPktFates(WifiNative.RxFateReport[] reportBufs) {
485        kilroy();
486        throw new UnsupportedOperationException();
487    }
488
489    /**
490     * Start sending the specified keep alive packets periodically.
491     *
492     * @return 0 for success, -1 for error
493     */
494    public int startSendingOffloadedPacket(
495            int slot, KeepalivePacketData keepAlivePacket, int periodInMs) {
496        kilroy();
497        throw new UnsupportedOperationException();
498    }
499
500    /**
501     * Stop sending the specified keep alive packets.
502     *
503     * @param slot id - same as startSendingOffloadedPacket call.
504     * @return 0 for success, -1 for error
505     */
506    public int stopSendingOffloadedPacket(int slot) {
507        kilroy();
508        throw new UnsupportedOperationException();
509    }
510
511    /**
512     * Start RSSI monitoring on the currently connected access point.
513     *
514     * @param maxRssi          Maximum RSSI threshold.
515     * @param minRssi          Minimum RSSI threshold.
516     * @param rssiEventHandler Called when RSSI goes above maxRssi or below minRssi
517     * @return 0 for success, -1 for failure
518     */
519    public int startRssiMonitoring(byte maxRssi, byte minRssi,
520                                   WifiNative.WifiRssiEventHandler rssiEventHandler) {
521        kilroy();
522        throw new UnsupportedOperationException();
523    }
524
525    /**
526     * Stop RSSI monitoring
527     *
528     * @return 0 for success, -1 for failure
529     */
530    public int stopRssiMonitoring() {
531        kilroy();
532        throw new UnsupportedOperationException();
533    }
534
535    private WifiDebugHostWakeReasonStats mWifiDebugHostWakeReasonStats;
536
537    /**
538     * Fetch the host wakeup reasons stats from wlan driver.
539     *
540     * @return the |WifiWakeReasonAndCounts| object retrieved from the wlan driver.
541     */
542    public WifiWakeReasonAndCounts getWlanWakeReasonCount() {
543        kilroy();
544        throw new UnsupportedOperationException();
545    }
546
547    /**
548     * Enable/Disable Neighbour discovery offload functionality in the firmware.
549     */
550    public boolean configureNeighborDiscoveryOffload(boolean enabled) {
551        kilroy();
552        throw new UnsupportedOperationException();
553    }
554
555    /**
556     * Helper function that parses unquoted MAC address string to a byte array
557     *
558     * @param macWithColons mac address string without double quotes
559     * @param mac an array of 6 bytes to receive the parsed mac address
560     */
561    private void parseUnquotedMacStrToByteArray(String macWithColons, byte[] mac) {
562        String[] macAddrStr = macWithColons.split(":");
563        for (int i = 0; i < 6; i++) {
564            Integer hexVal = Integer.parseInt(macAddrStr[i], 16);
565            mac[i] = hexVal.byteValue();
566        }
567    }
568
569    StackTraceElement[] mTrace;
570
571    private void kilroy() {
572        Thread cur = Thread.currentThread();
573        mTrace = cur.getStackTrace();
574        StackTraceElement s = mTrace[3];
575        String name = s.getMethodName();
576        if (name.contains("lambda$")) {
577            // Try to find a friendlier method name
578            String myFile = s.getFileName();
579            if (myFile != null) {
580                for (int i = 4; i < mTrace.length; i++) {
581                    if (myFile.equals(mTrace[i].getFileName())) {
582                        name = mTrace[i].getMethodName();
583                        break;
584                    }
585                }
586            }
587        }
588        Log.e(TAG, "th " + cur.getId() + " line " + s.getLineNumber() + " " + name);
589    }
590
591    /**
592     * Hal Device Manager callbacks.
593     */
594    public class HalDeviceManagerStatusListener implements HalDeviceManager.ManagerStatusListener {
595        @Override
596        public void onStatusChanged() {
597            Log.i(TAG, "Device Manager onStatusChanged. isReady(): " + mHalDeviceManager.isReady()
598                    + "isStarted(): " + mHalDeviceManager.isStarted());
599            // Reset all our cached handles.
600            if (!mHalDeviceManager.isReady() || !mHalDeviceManager.isStarted())  {
601                mIWifiChip = null;
602                mIWifiStaIface = null;
603                mIWifiApIface = null;
604                mIWifiRttController = null;
605                mDriverDescription = null;
606                mFirmwareDescription = null;
607            }
608        }
609    }
610}
611