WifiVendorHalTest.java revision 2f0db656f678c8cf1ab6643739c6d0059721e6e2
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 */
16
17package com.android.server.wifi;
18
19import android.app.test.MockAnswerUtil.AnswerWithArguments;
20import android.hardware.wifi.V1_0.IWifiApIface;
21import android.hardware.wifi.V1_0.IWifiChip;
22import android.hardware.wifi.V1_0.IWifiIface;
23import android.hardware.wifi.V1_0.IWifiRttController;
24import android.hardware.wifi.V1_0.IWifiStaIface;
25import android.hardware.wifi.V1_0.StaApfPacketFilterCapabilities;
26import android.hardware.wifi.V1_0.WifiDebugHostWakeReasonStats;
27import android.hardware.wifi.V1_0.WifiDebugPacketFateFrameType;
28import android.hardware.wifi.V1_0.WifiDebugRingBufferFlags;
29import android.hardware.wifi.V1_0.WifiDebugRingBufferStatus;
30import android.hardware.wifi.V1_0.WifiDebugRingBufferVerboseLevel;
31import android.hardware.wifi.V1_0.WifiDebugRxPacketFate;
32import android.hardware.wifi.V1_0.WifiDebugRxPacketFateReport;
33import android.hardware.wifi.V1_0.WifiDebugTxPacketFate;
34import android.hardware.wifi.V1_0.WifiDebugTxPacketFateReport;
35import android.hardware.wifi.V1_0.WifiStatus;
36import android.hardware.wifi.V1_0.WifiStatusCode;
37import android.net.apf.ApfCapabilities;
38import android.net.wifi.WifiManager;
39import android.net.wifi.WifiWakeReasonAndCounts;
40import android.os.HandlerThread;
41import android.os.Looper;
42import android.os.RemoteException;
43
44import com.android.server.connectivity.KeepalivePacketData;
45import com.android.server.wifi.util.NativeUtil;
46
47import static org.junit.Assert.*;
48import static org.mockito.Mockito.*;
49
50import org.junit.Before;
51import org.junit.Test;
52import org.mockito.ArgumentCaptor;
53import org.mockito.Mock;
54import org.mockito.MockitoAnnotations;
55
56import java.net.InetAddress;
57import java.util.ArrayList;
58import java.util.Arrays;
59import java.util.Random;
60
61/**
62 * Unit tests for {@link com.android.server.wifi.WifiVendorHal}.
63 */
64public class WifiVendorHalTest {
65
66    WifiVendorHal mWifiVendorHal;
67    private WifiStatus mWifiStatusSuccess;
68    private WifiStatus mWifiStatusFailure;
69    @Mock
70    private HalDeviceManager mHalDeviceManager;
71    @Mock
72    private HandlerThread mWifiStateMachineHandlerThread;
73    @Mock
74    private WifiVendorHal.HalDeviceManagerStatusListener mHalDeviceManagerStatusCallbacks;
75    @Mock
76    private IWifiApIface mIWifiApIface;
77    @Mock
78    private IWifiChip mIWifiChip;
79    @Mock
80    private IWifiStaIface mIWifiStaIface;
81    @Mock
82    private IWifiRttController mIWifiRttController;
83
84    /**
85     * Sets up for unit test
86     */
87    @Before
88    public void setUp() throws Exception {
89        MockitoAnnotations.initMocks(this);
90        mWifiStatusSuccess = new WifiStatus();
91        mWifiStatusSuccess.code = WifiStatusCode.SUCCESS;
92        mWifiStatusFailure = new WifiStatus();
93        mWifiStatusFailure.code = WifiStatusCode.ERROR_UNKNOWN;
94        mWifiStatusFailure.description = "I don't even know what a Mock Turtle is.";
95        when(mIWifiStaIface.enableLinkLayerStatsCollection(false)).thenReturn(mWifiStatusSuccess);
96
97
98        // Setup the HalDeviceManager mock's start/stop behaviour. This can be overridden in
99        // individual tests, if needed.
100        doAnswer(new AnswerWithArguments() {
101            public boolean answer() {
102                when(mHalDeviceManager.isReady()).thenReturn(true);
103                when(mHalDeviceManager.isStarted()).thenReturn(true);
104                mHalDeviceManagerStatusCallbacks.onStatusChanged();
105                return true;
106            }
107        }).when(mHalDeviceManager).start();
108
109        doAnswer(new AnswerWithArguments() {
110            public void answer() {
111                when(mHalDeviceManager.isReady()).thenReturn(true);
112                when(mHalDeviceManager.isStarted()).thenReturn(false);
113                mHalDeviceManagerStatusCallbacks.onStatusChanged();
114            }
115        }).when(mHalDeviceManager).stop();
116        when(mHalDeviceManager.createStaIface(eq(null), eq(null)))
117                .thenReturn(mIWifiStaIface);
118        when(mHalDeviceManager.createApIface(eq(null), eq(null)))
119                .thenReturn(mIWifiApIface);
120        when(mHalDeviceManager.getChip(any(IWifiIface.class)))
121                .thenReturn(mIWifiChip);
122        when(mHalDeviceManager.createRttController(any(IWifiIface.class)))
123                .thenReturn(mIWifiRttController);
124
125        // Create the vendor HAL object under test.
126        mWifiVendorHal = new WifiVendorHal(mHalDeviceManager, mWifiStateMachineHandlerThread);
127
128        // Initialize the vendor HAL to capture the registered callback.
129        mWifiVendorHal.initialize();
130        ArgumentCaptor<WifiVendorHal.HalDeviceManagerStatusListener> callbackCaptor =
131                ArgumentCaptor.forClass(WifiVendorHal.HalDeviceManagerStatusListener.class);
132        verify(mHalDeviceManager).registerStatusListener(
133                callbackCaptor.capture(), any(Looper.class));
134        mHalDeviceManagerStatusCallbacks = callbackCaptor.getValue();
135    }
136
137    /**
138     * Tests the successful starting of HAL in STA mode using
139     * {@link WifiVendorHal#startVendorHal(boolean)}.
140     */
141    @Test
142    public void testStartHalSuccessInStaMode() {
143        assertTrue(mWifiVendorHal.startVendorHal(true));
144        assertTrue(mWifiVendorHal.isHalStarted());
145
146        verify(mHalDeviceManager).start();
147        verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
148        verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
149        verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
150        verify(mHalDeviceManager).isReady();
151        verify(mHalDeviceManager).isStarted();
152
153        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
154    }
155
156    /**
157     * Tests the successful starting of HAL in AP mode using
158     * {@link WifiVendorHal#startVendorHal(boolean)}.
159     */
160    @Test
161    public void testStartHalSuccessInApMode() {
162        assertTrue(mWifiVendorHal.startVendorHal(false));
163        assertTrue(mWifiVendorHal.isHalStarted());
164
165        verify(mHalDeviceManager).start();
166        verify(mHalDeviceManager).createApIface(eq(null), eq(null));
167        verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
168        verify(mHalDeviceManager).isReady();
169        verify(mHalDeviceManager).isStarted();
170
171        verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
172        verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
173    }
174
175    /**
176     * Tests the failure to start HAL in STA mode using
177     * {@link WifiVendorHal#startVendorHal(boolean)}.
178     */
179    @Test
180    public void testStartHalFailureInStaMode() {
181        // No callbacks are invoked in this case since the start itself failed. So, override
182        // default AnswerWithArguments that we setup.
183        doAnswer(new AnswerWithArguments() {
184            public boolean answer() {
185                return false;
186            }
187        }).when(mHalDeviceManager).start();
188        assertFalse(mWifiVendorHal.startVendorHal(true));
189        assertFalse(mWifiVendorHal.isHalStarted());
190
191        verify(mHalDeviceManager).start();
192
193        verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
194        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
195        verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
196        verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
197    }
198
199    /**
200     * Tests the failure to start HAL in STA mode using
201     * {@link WifiVendorHal#startVendorHal(boolean)}.
202     */
203    @Test
204    public void testStartHalFailureInIfaceCreationInStaMode() {
205        when(mHalDeviceManager.createStaIface(eq(null), eq(null))).thenReturn(null);
206        assertFalse(mWifiVendorHal.startVendorHal(true));
207        assertFalse(mWifiVendorHal.isHalStarted());
208
209        verify(mHalDeviceManager).start();
210        verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
211        verify(mHalDeviceManager).stop();
212
213        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
214        verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
215        verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
216    }
217
218    /**
219     * Tests the failure to start HAL in STA mode using
220     * {@link WifiVendorHal#startVendorHal(boolean)}.
221     */
222    @Test
223    public void testStartHalFailureInRttControllerCreationInStaMode() {
224        when(mHalDeviceManager.createRttController(any(IWifiIface.class))).thenReturn(null);
225        assertFalse(mWifiVendorHal.startVendorHal(true));
226        assertFalse(mWifiVendorHal.isHalStarted());
227
228        verify(mHalDeviceManager).start();
229        verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
230        verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
231        verify(mHalDeviceManager).stop();
232
233        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
234        verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
235    }
236
237    /**
238     * Tests the failure to start HAL in STA mode using
239     * {@link WifiVendorHal#startVendorHal(boolean)}.
240     */
241    @Test
242    public void testStartHalFailureInChipGetInStaMode() {
243        when(mHalDeviceManager.getChip(any(IWifiIface.class))).thenReturn(null);
244        assertFalse(mWifiVendorHal.startVendorHal(true));
245        assertFalse(mWifiVendorHal.isHalStarted());
246
247        verify(mHalDeviceManager).start();
248        verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
249        verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
250        verify(mHalDeviceManager).getChip(any(IWifiIface.class));
251        verify(mHalDeviceManager).stop();
252
253        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
254    }
255
256    /**
257     * Tests the failure to start HAL in STA mode using
258     * {@link WifiVendorHal#startVendorHal(boolean)}.
259     */
260    @Test
261    public void testStartHalFailureInApMode() {
262        when(mHalDeviceManager.createApIface(eq(null), eq(null))).thenReturn(null);
263        assertFalse(mWifiVendorHal.startVendorHal(false));
264        assertFalse(mWifiVendorHal.isHalStarted());
265
266        verify(mHalDeviceManager).start();
267        verify(mHalDeviceManager).createApIface(eq(null), eq(null));
268        verify(mHalDeviceManager).stop();
269
270        verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
271        verify(mHalDeviceManager, never()).getChip(any(IWifiIface.class));
272        verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
273    }
274
275    /**
276     * Tests the stopping of HAL in STA mode using
277     * {@link WifiVendorHal#stopVendorHal()}.
278     */
279    @Test
280    public void testStopHalInStaMode() {
281        assertTrue(mWifiVendorHal.startVendorHal(true));
282        assertTrue(mWifiVendorHal.isHalStarted());
283
284        mWifiVendorHal.stopVendorHal();
285        assertFalse(mWifiVendorHal.isHalStarted());
286
287        verify(mHalDeviceManager).start();
288        verify(mHalDeviceManager).stop();
289        verify(mHalDeviceManager).createStaIface(eq(null), eq(null));
290        verify(mHalDeviceManager).getChip(eq(mIWifiStaIface));
291        verify(mHalDeviceManager).createRttController(eq(mIWifiStaIface));
292        verify(mHalDeviceManager, times(2)).isReady();
293        verify(mHalDeviceManager, times(2)).isStarted();
294
295        verify(mHalDeviceManager, never()).createApIface(eq(null), eq(null));
296    }
297
298    /**
299     * Tests the stopping of HAL in AP mode using
300     * {@link WifiVendorHal#stopVendorHal()}.
301     */
302    @Test
303    public void testStopHalInApMode() {
304        assertTrue(mWifiVendorHal.startVendorHal(false));
305        assertTrue(mWifiVendorHal.isHalStarted());
306
307        mWifiVendorHal.stopVendorHal();
308        assertFalse(mWifiVendorHal.isHalStarted());
309
310        verify(mHalDeviceManager).start();
311        verify(mHalDeviceManager).stop();
312        verify(mHalDeviceManager).createApIface(eq(null), eq(null));
313        verify(mHalDeviceManager).getChip(eq(mIWifiApIface));
314        verify(mHalDeviceManager, times(2)).isReady();
315        verify(mHalDeviceManager, times(2)).isStarted();
316
317        verify(mHalDeviceManager, never()).createStaIface(eq(null), eq(null));
318        verify(mHalDeviceManager, never()).createRttController(any(IWifiIface.class));
319    }
320
321    /**
322     * Test translation to WifiManager.WIFI_FEATURE_*
323     *
324     * Just do a spot-check with a few feature bits here; since the code is table-
325     * driven we don't have to work hard to exercise all of it.
326     */
327    @Test
328    public void testFeatureMaskTranslation() {
329        int caps = (
330                IWifiStaIface.StaIfaceCapabilityMask.BACKGROUND_SCAN
331                | IWifiStaIface.StaIfaceCapabilityMask.LINK_LAYER_STATS
332            );
333        int expected = (
334                WifiManager.WIFI_FEATURE_SCANNER
335                | WifiManager.WIFI_FEATURE_LINK_LAYER_STATS);
336        assertEquals(expected, mWifiVendorHal.wifiFeatureMaskFromStaCapabilities(caps));
337    }
338
339    /**
340     * Test enablement of link layer stats after startup
341     * <p>
342     * Request link layer stats before HAL start
343     * - should not make it to the HAL layer
344     * Start the HAL in STA mode
345     * Request link layer stats twice more
346     * - enable request should make it to the HAL layer
347     * - HAL layer should have been called to make the requests (i.e., two calls total)
348     */
349    @Test
350    public void testLinkLayerStatsEnableAfterStartup() throws Exception {
351        doNothing().when(mIWifiStaIface).getLinkLayerStats(any());
352
353        assertNull(mWifiVendorHal.getWifiLinkLayerStats());
354        assertTrue(mWifiVendorHal.startVendorHalSta());
355        assertTrue(mWifiVendorHal.isHalStarted());
356
357        verify(mHalDeviceManager).start();
358        mWifiVendorHal.getWifiLinkLayerStats();
359        mWifiVendorHal.getWifiLinkLayerStats();
360        verify(mIWifiStaIface).enableLinkLayerStatsCollection(false); // mLinkLayerStatsDebug
361        verify(mIWifiStaIface, times(2)).getLinkLayerStats(any());
362    }
363
364    /**
365     * Test that link layer stats are not enabled and harmless in AP mode
366     * <p>
367     * Start the HAL in AP mode
368     * - stats should not be enabled
369     * Request link layer stats
370     * - HAL layer should have been called to make the request
371     */
372    @Test
373    public void testLinkLayerStatsNotEnabledAndHarmlessInApMode() throws Exception {
374        doNothing().when(mIWifiStaIface).getLinkLayerStats(any());
375
376        assertTrue(mWifiVendorHal.startVendorHalAp());
377        assertTrue(mWifiVendorHal.isHalStarted());
378        assertNull(mWifiVendorHal.getWifiLinkLayerStats());
379
380        verify(mHalDeviceManager).start();
381
382        verify(mIWifiStaIface, never()).enableLinkLayerStatsCollection(false);
383        verify(mIWifiStaIface, never()).getLinkLayerStats(any());
384    }
385
386    // TODO(b/34900534) add test for correct MOVE CORRESPONDING of fields
387
388    /**
389     * Test that getFirmwareVersion() and getDriverVersion() work
390     *
391     * Calls before the STA is started are expected to return null.
392     */
393    @Test
394    public void testVersionGetters() throws Exception {
395        String firmwareVersion = "fuzzy";
396        String driverVersion = "dizzy";
397        IWifiChip.ChipDebugInfo chipDebugInfo = new IWifiChip.ChipDebugInfo();
398        chipDebugInfo.firmwareDescription = firmwareVersion;
399        chipDebugInfo.driverDescription = driverVersion;
400
401        doAnswer(new AnswerWithArguments() {
402            public void answer(IWifiChip.requestChipDebugInfoCallback cb) throws RemoteException {
403                cb.onValues(mWifiStatusSuccess, chipDebugInfo);
404            }
405        }).when(mIWifiChip).requestChipDebugInfo(any(IWifiChip.requestChipDebugInfoCallback.class));
406
407        assertNull(mWifiVendorHal.getFirmwareVersion());
408        assertNull(mWifiVendorHal.getDriverVersion());
409
410        assertTrue(mWifiVendorHal.startVendorHalSta());
411
412        assertEquals(firmwareVersion, mWifiVendorHal.getFirmwareVersion());
413        assertEquals(driverVersion, mWifiVendorHal.getDriverVersion());
414    }
415
416    /**
417     * Test that setScanningMacOui is hooked up to the HAL correctly
418     */
419    @Test
420    public void testSetScanningMacOui() throws Exception {
421        byte[] oui = NativeUtil.macAddressOuiToByteArray("DA:A1:19");
422        byte[] zzz = NativeUtil.macAddressOuiToByteArray("00:00:00");
423
424        when(mIWifiStaIface.setScanningMacOui(any())).thenReturn(mWifiStatusSuccess);
425
426        assertFalse(mWifiVendorHal.setScanningMacOui(oui)); // expect fail - STA not started
427        assertTrue(mWifiVendorHal.startVendorHalSta());
428        assertFalse(mWifiVendorHal.setScanningMacOui(null));  // expect fail - null
429        assertFalse(mWifiVendorHal.setScanningMacOui(new byte[]{(byte) 1})); // expect fail - len
430        assertTrue(mWifiVendorHal.setScanningMacOui(oui));
431        assertTrue(mWifiVendorHal.setScanningMacOui(zzz));
432
433        verify(mIWifiStaIface).setScanningMacOui(eq(oui));
434        verify(mIWifiStaIface).setScanningMacOui(eq(zzz));
435    }
436
437    @Test
438    public void testStartSendingOffloadedPacket() throws Exception {
439        byte[] srcMac = NativeUtil.macAddressToByteArray("4007b2088c81");
440        InetAddress src = InetAddress.parseNumericAddress("192.168.13.13");
441        InetAddress dst = InetAddress.parseNumericAddress("93.184.216.34");
442        int slot = 13;
443        int millis = 16000;
444
445        KeepalivePacketData kap = KeepalivePacketData.nattKeepalivePacket(src, 63000, dst, 4500);
446
447        when(mIWifiStaIface.startSendingKeepAlivePackets(
448                anyInt(), any(), anyShort(), any(), any(), anyInt()
449        )).thenReturn(mWifiStatusSuccess);
450
451        assertTrue(mWifiVendorHal.startVendorHalSta());
452        assertTrue(0 == mWifiVendorHal.startSendingOffloadedPacket(slot, srcMac, kap, millis));
453
454        verify(mIWifiStaIface).startSendingKeepAlivePackets(
455                eq(slot), any(), anyShort(), any(), any(), eq(millis));
456    }
457
458    @Test
459    public void testStopSendingOffloadedPacket() throws Exception {
460        int slot = 13;
461
462        when(mIWifiStaIface.stopSendingKeepAlivePackets(anyInt())).thenReturn(mWifiStatusSuccess);
463
464        assertTrue(mWifiVendorHal.startVendorHalSta());
465        assertTrue(0 == mWifiVendorHal.stopSendingOffloadedPacket(slot));
466
467        verify(mIWifiStaIface).stopSendingKeepAlivePackets(eq(slot));
468    }
469
470    /**
471     * Test that getApfCapabilities is hooked up to the HAL correctly
472     *
473     * A call before the vendor HAL is started should return a non-null result with version 0
474     *
475     * A call after the HAL is started should return the mocked values.
476     */
477    @Test
478    public void testApfCapabilities() throws Exception {
479        int myVersion = 33;
480        int myMaxSize = 1234;
481
482        StaApfPacketFilterCapabilities capabilities = new StaApfPacketFilterCapabilities();
483        capabilities.version = myVersion;
484        capabilities.maxLength = myMaxSize;
485
486        doAnswer(new AnswerWithArguments() {
487            public void answer(IWifiStaIface.getApfPacketFilterCapabilitiesCallback cb)
488                    throws RemoteException {
489                cb.onValues(mWifiStatusSuccess, capabilities);
490            }
491        }).when(mIWifiStaIface).getApfPacketFilterCapabilities(any(
492                IWifiStaIface.getApfPacketFilterCapabilitiesCallback.class));
493
494
495        assertEquals(0, mWifiVendorHal.getApfCapabilities().apfVersionSupported);
496
497        assertTrue(mWifiVendorHal.startVendorHalSta());
498
499        ApfCapabilities actual = mWifiVendorHal.getApfCapabilities();
500
501        assertEquals(myVersion, actual.apfVersionSupported);
502        assertEquals(myMaxSize, actual.maximumApfProgramSize);
503        assertEquals(android.system.OsConstants.ARPHRD_ETHER, actual.apfPacketFormat);
504        assertNotEquals(0, actual.apfPacketFormat);
505    }
506
507    /**
508     * Test that an APF program can be installed.
509     */
510    @Test
511    public void testInstallApf() throws Exception {
512        byte[] filter = new byte[] {19, 53, 10};
513
514        ArrayList<Byte> expected = new ArrayList<>(3);
515        for (byte b : filter) expected.add(b);
516
517        when(mIWifiStaIface.installApfPacketFilter(anyInt(), any(ArrayList.class)))
518                .thenReturn(mWifiStatusSuccess);
519
520        assertTrue(mWifiVendorHal.startVendorHalSta());
521        assertTrue(mWifiVendorHal.installPacketFilter(filter));
522
523        verify(mIWifiStaIface).installApfPacketFilter(eq(0), eq(expected));
524    }
525
526    /**
527     * Test that the country code is set in AP mode (when it should be).
528     */
529    @Test
530    public void testSetCountryCodeHal() throws Exception {
531        byte[] expected = new byte[]{(byte) 'C', (byte) 'A'};
532
533        when(mIWifiApIface.setCountryCode(any()))
534                .thenReturn(mWifiStatusSuccess);
535
536        assertTrue(mWifiVendorHal.startVendorHalAp());
537
538        assertFalse(mWifiVendorHal.setCountryCodeHal(null));
539        assertFalse(mWifiVendorHal.setCountryCodeHal(""));
540        assertFalse(mWifiVendorHal.setCountryCodeHal("A"));
541        assertTrue(mWifiVendorHal.setCountryCodeHal("CA")); // Only one expected to succeed
542        assertFalse(mWifiVendorHal.setCountryCodeHal("ZZZ"));
543
544        verify(mIWifiApIface).setCountryCode(eq(expected));
545    }
546
547    /**
548     * Test that startLoggingToDebugRingBuffer is plumbed to chip
549     *
550     * A call before the vendor hal is started should just return false.
551     * After starting in STA mode, the call should succeed, and pass ther right things down.
552     */
553    @Test
554    public void testStartLoggingRingBuffer() throws Exception {
555        when(mIWifiChip.startLoggingToDebugRingBuffer(
556                any(String.class), anyInt(), anyInt(), anyInt()
557        )).thenReturn(mWifiStatusSuccess);
558
559        assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One"));
560        assertTrue(mWifiVendorHal.startVendorHalSta());
561        assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One"));
562
563        verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
564    }
565
566    /**
567     * Same test as testStartLoggingRingBuffer, but in AP mode rather than STA.
568     */
569    @Test
570    public void testStartLoggingRingBufferOnAp() throws Exception {
571        when(mIWifiChip.startLoggingToDebugRingBuffer(
572                any(String.class), anyInt(), anyInt(), anyInt()
573        )).thenReturn(mWifiStatusSuccess);
574
575        assertFalse(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 0, 0, "One"));
576        assertTrue(mWifiVendorHal.startVendorHalAp());
577        assertTrue(mWifiVendorHal.startLoggingRingBuffer(1, 0x42, 11, 3000, "One"));
578
579        verify(mIWifiChip).startLoggingToDebugRingBuffer("One", 1, 11, 3000);
580    }
581
582    /**
583     * Test that getRingBufferStatus gets and translates its stuff correctly
584     */
585    @Test
586    public void testRingBufferStatus() throws Exception {
587        WifiDebugRingBufferStatus one = new WifiDebugRingBufferStatus();
588        one.ringName = "One";
589        one.flags = WifiDebugRingBufferFlags.HAS_BINARY_ENTRIES;
590        one.ringId = 5607371;
591        one.sizeInBytes = 54321;
592        one.freeSizeInBytes = 42;
593        one.verboseLevel = WifiDebugRingBufferVerboseLevel.VERBOSE;
594        String oneExpect = "name: One flag: 1 ringBufferId: 5607371 ringBufferByteSize: 54321"
595                + " verboseLevel: 2 writtenBytes: 0 readBytes: 0 writtenRecords: 0";
596
597        WifiDebugRingBufferStatus two = new WifiDebugRingBufferStatus();
598        two.ringName = "Two";
599        two.flags = WifiDebugRingBufferFlags.HAS_ASCII_ENTRIES
600                | WifiDebugRingBufferFlags.HAS_PER_PACKET_ENTRIES;
601        two.ringId = 4512470;
602        two.sizeInBytes = 300;
603        two.freeSizeInBytes = 42;
604        two.verboseLevel = WifiDebugRingBufferVerboseLevel.DEFAULT;
605
606        ArrayList<WifiDebugRingBufferStatus> halBufferStatus = new ArrayList<>(2);
607        halBufferStatus.add(one);
608        halBufferStatus.add(two);
609
610        WifiNative.RingBufferStatus[] actual;
611
612        doAnswer(new AnswerWithArguments() {
613            public void answer(IWifiChip.getDebugRingBuffersStatusCallback cb)
614                    throws RemoteException {
615                cb.onValues(mWifiStatusSuccess, halBufferStatus);
616            }
617        }).when(mIWifiChip).getDebugRingBuffersStatus(any(
618                IWifiChip.getDebugRingBuffersStatusCallback.class));
619
620        assertTrue(mWifiVendorHal.startVendorHalSta());
621        actual = mWifiVendorHal.getRingBufferStatus();
622
623        assertEquals(halBufferStatus.size(), actual.length);
624        assertEquals(oneExpect, actual[0].toString());
625        assertEquals(two.ringId, actual[1].ringBufferId);
626
627    }
628
629    /**
630     * Test that getRingBufferData calls forceDumpToDebugRingBuffer
631     *
632     * Try once before hal start, and twice after (one success, one failure).
633     */
634    @Test
635    public void testForceRingBufferDump() throws Exception {
636        when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Gunk"))).thenReturn(mWifiStatusSuccess);
637        when(mIWifiChip.forceDumpToDebugRingBuffer(eq("Glop"))).thenReturn(mWifiStatusFailure);
638
639        assertFalse(mWifiVendorHal.getRingBufferData("Gunk")); // hal not started
640
641        assertTrue(mWifiVendorHal.startVendorHalSta());
642
643        assertTrue(mWifiVendorHal.getRingBufferData("Gunk")); // mocked call succeeds
644        assertFalse(mWifiVendorHal.getRingBufferData("Glop")); // mocked call fails
645
646        verify(mIWifiChip).forceDumpToDebugRingBuffer("Gunk");
647        verify(mIWifiChip).forceDumpToDebugRingBuffer("Glop");
648    }
649
650    /**
651     * Tests the start of packet fate monitoring.
652     *
653     * Try once before hal start, and once after (one success, one failure).
654     */
655    @Test
656    public void testStartPktFateMonitoring() throws Exception {
657        when(mIWifiStaIface.startDebugPacketFateMonitoring()).thenReturn(mWifiStatusSuccess);
658
659        assertFalse(mWifiVendorHal.startPktFateMonitoring());
660        verify(mIWifiStaIface, never()).startDebugPacketFateMonitoring();
661
662        assertTrue(mWifiVendorHal.startVendorHalSta());
663        assertTrue(mWifiVendorHal.startPktFateMonitoring());
664        verify(mIWifiStaIface).startDebugPacketFateMonitoring();
665    }
666
667    /**
668     * Tests the retrieval of tx packet fates.
669     *
670     * Try once before hal start, and once after.
671     */
672    @Test
673    public void testGetTxPktFates() throws Exception {
674        byte[] frameContentBytes = new byte[30];
675        new Random().nextBytes(frameContentBytes);
676        WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport();
677        fateReport.fate = WifiDebugTxPacketFate.DRV_QUEUED;
678        fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
679        fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II;
680        fateReport.frameInfo.frameContent.addAll(
681                NativeUtil.byteArrayToArrayList(frameContentBytes));
682
683        doAnswer(new AnswerWithArguments() {
684            public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) {
685                cb.onValues(mWifiStatusSuccess,
686                        new ArrayList<WifiDebugTxPacketFateReport>(Arrays.asList(fateReport)));
687            }
688        }).when(mIWifiStaIface)
689                .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
690
691        WifiNative.TxFateReport[] retrievedFates = new WifiNative.TxFateReport[1];
692        assertFalse(mWifiVendorHal.getTxPktFates(retrievedFates));
693        verify(mIWifiStaIface, never())
694                .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
695
696        assertTrue(mWifiVendorHal.startVendorHalSta());
697
698        assertTrue(mWifiVendorHal.getTxPktFates(retrievedFates));
699        verify(mIWifiStaIface)
700                .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
701        assertEquals(WifiLoggerHal.TX_PKT_FATE_DRV_QUEUED, retrievedFates[0].mFate);
702        assertEquals(fateReport.frameInfo.driverTimestampUsec,
703                retrievedFates[0].mDriverTimestampUSec);
704        assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFates[0].mFrameType);
705        assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes);
706    }
707
708    /**
709     * Tests the retrieval of tx packet fates when the number of fates retrieved exceeds the
710     * input array.
711     *
712     * Try once before hal start, and once after.
713     */
714    @Test
715    public void testGetTxPktFatesExceedsInputArrayLength() throws Exception {
716        byte[] frameContentBytes = new byte[30];
717        new Random().nextBytes(frameContentBytes);
718        WifiDebugTxPacketFateReport fateReport = new WifiDebugTxPacketFateReport();
719        fateReport.fate = WifiDebugTxPacketFate.FW_DROP_OTHER;
720        fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
721        fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211;
722        fateReport.frameInfo.frameContent.addAll(
723                NativeUtil.byteArrayToArrayList(frameContentBytes));
724
725        doAnswer(new AnswerWithArguments() {
726            public void answer(IWifiStaIface.getDebugTxPacketFatesCallback cb) {
727                cb.onValues(mWifiStatusSuccess,
728                        new ArrayList<WifiDebugTxPacketFateReport>(Arrays.asList(
729                                fateReport, fateReport)));
730            }
731        }).when(mIWifiStaIface)
732                .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
733
734        WifiNative.TxFateReport[] retrievedFates = new WifiNative.TxFateReport[1];
735        assertFalse(mWifiVendorHal.getTxPktFates(retrievedFates));
736        verify(mIWifiStaIface, never())
737                .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
738
739        assertTrue(mWifiVendorHal.startVendorHalSta());
740
741        assertTrue(mWifiVendorHal.getTxPktFates(retrievedFates));
742        verify(mIWifiStaIface)
743                .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
744        assertEquals(WifiLoggerHal.TX_PKT_FATE_FW_DROP_OTHER, retrievedFates[0].mFate);
745        assertEquals(fateReport.frameInfo.driverTimestampUsec,
746                retrievedFates[0].mDriverTimestampUSec);
747        assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFates[0].mFrameType);
748        assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes);
749    }
750
751    /**
752     * Tests the retrieval of rx packet fates.
753     *
754     * Try once before hal start, and once after.
755     */
756    @Test
757    public void testGetRxPktFates() throws Exception {
758        byte[] frameContentBytes = new byte[30];
759        new Random().nextBytes(frameContentBytes);
760        WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport();
761        fateReport.fate = WifiDebugRxPacketFate.SUCCESS;
762        fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
763        fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.ETHERNET_II;
764        fateReport.frameInfo.frameContent.addAll(
765                NativeUtil.byteArrayToArrayList(frameContentBytes));
766
767        doAnswer(new AnswerWithArguments() {
768            public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) {
769                cb.onValues(mWifiStatusSuccess,
770                        new ArrayList<WifiDebugRxPacketFateReport>(Arrays.asList(fateReport)));
771            }
772        }).when(mIWifiStaIface)
773                .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
774
775        WifiNative.RxFateReport[] retrievedFates = new WifiNative.RxFateReport[1];
776        assertFalse(mWifiVendorHal.getRxPktFates(retrievedFates));
777        verify(mIWifiStaIface, never())
778                .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
779
780        assertTrue(mWifiVendorHal.startVendorHalSta());
781
782        assertTrue(mWifiVendorHal.getRxPktFates(retrievedFates));
783        verify(mIWifiStaIface)
784                .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
785        assertEquals(WifiLoggerHal.RX_PKT_FATE_SUCCESS, retrievedFates[0].mFate);
786        assertEquals(fateReport.frameInfo.driverTimestampUsec,
787                retrievedFates[0].mDriverTimestampUSec);
788        assertEquals(WifiLoggerHal.FRAME_TYPE_ETHERNET_II, retrievedFates[0].mFrameType);
789        assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes);
790    }
791
792    /**
793     * Tests the retrieval of rx packet fates when the number of fates retrieved exceeds the
794     * input array.
795     *
796     * Try once before hal start, and once after.
797     */
798    @Test
799    public void testGetRxPktFatesExceedsInputArrayLength() throws Exception {
800        byte[] frameContentBytes = new byte[30];
801        new Random().nextBytes(frameContentBytes);
802        WifiDebugRxPacketFateReport fateReport = new WifiDebugRxPacketFateReport();
803        fateReport.fate = WifiDebugRxPacketFate.FW_DROP_FILTER;
804        fateReport.frameInfo.driverTimestampUsec = new Random().nextLong();
805        fateReport.frameInfo.frameType = WifiDebugPacketFateFrameType.MGMT_80211;
806        fateReport.frameInfo.frameContent.addAll(
807                NativeUtil.byteArrayToArrayList(frameContentBytes));
808
809        doAnswer(new AnswerWithArguments() {
810            public void answer(IWifiStaIface.getDebugRxPacketFatesCallback cb) {
811                cb.onValues(mWifiStatusSuccess,
812                        new ArrayList<WifiDebugRxPacketFateReport>(Arrays.asList(
813                                fateReport, fateReport)));
814            }
815        }).when(mIWifiStaIface)
816                .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
817
818        WifiNative.RxFateReport[] retrievedFates = new WifiNative.RxFateReport[1];
819        assertFalse(mWifiVendorHal.getRxPktFates(retrievedFates));
820        verify(mIWifiStaIface, never())
821                .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
822
823        assertTrue(mWifiVendorHal.startVendorHalSta());
824
825        assertTrue(mWifiVendorHal.getRxPktFates(retrievedFates));
826        verify(mIWifiStaIface)
827                .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
828        assertEquals(WifiLoggerHal.RX_PKT_FATE_FW_DROP_FILTER, retrievedFates[0].mFate);
829        assertEquals(fateReport.frameInfo.driverTimestampUsec,
830                retrievedFates[0].mDriverTimestampUSec);
831        assertEquals(WifiLoggerHal.FRAME_TYPE_80211_MGMT, retrievedFates[0].mFrameType);
832        assertArrayEquals(frameContentBytes, retrievedFates[0].mFrameBytes);
833    }
834
835    /**
836     * Tests the failure to retrieve tx packet fates when the input array is empty.
837     */
838    @Test
839    public void testGetTxPktFatesEmptyInputArray() throws Exception {
840        assertTrue(mWifiVendorHal.startVendorHalSta());
841        assertFalse(mWifiVendorHal.getTxPktFates(new WifiNative.TxFateReport[0]));
842        verify(mIWifiStaIface, never())
843                .getDebugTxPacketFates(any(IWifiStaIface.getDebugTxPacketFatesCallback.class));
844    }
845
846    /**
847     * Tests the failure to retrieve rx packet fates when the input array is empty.
848     */
849    @Test
850    public void testGetRxPktFatesEmptyInputArray() throws Exception {
851        assertTrue(mWifiVendorHal.startVendorHalSta());
852        assertFalse(mWifiVendorHal.getRxPktFates(new WifiNative.RxFateReport[0]));
853        verify(mIWifiStaIface, never())
854                .getDebugRxPacketFates(any(IWifiStaIface.getDebugRxPacketFatesCallback.class));
855    }
856
857    /**
858     * Tests the nd offload enable/disable.
859     */
860    @Test
861    public void testEnableDisableNdOffload() throws Exception {
862        when(mIWifiStaIface.enableNdOffload(anyBoolean())).thenReturn(mWifiStatusSuccess);
863
864        assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(true));
865        verify(mIWifiStaIface, never()).enableNdOffload(anyBoolean());
866
867        assertTrue(mWifiVendorHal.startVendorHalSta());
868
869        assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(true));
870        verify(mIWifiStaIface).enableNdOffload(eq(true));
871        assertTrue(mWifiVendorHal.configureNeighborDiscoveryOffload(false));
872        verify(mIWifiStaIface).enableNdOffload(eq(false));
873    }
874
875    /**
876     * Tests the nd offload enable failure.
877     */
878    @Test
879    public void testEnableNdOffloadFailure() throws Exception {
880        when(mIWifiStaIface.enableNdOffload(eq(true))).thenReturn(mWifiStatusFailure);
881
882        assertTrue(mWifiVendorHal.startVendorHalSta());
883
884        assertFalse(mWifiVendorHal.configureNeighborDiscoveryOffload(true));
885        verify(mIWifiStaIface).enableNdOffload(eq(true));
886    }
887
888    /**
889     * Tests the retrieval of wlan wake reason stats.
890     */
891    @Test
892    public void testGetWlanWakeReasonCount() throws Exception {
893        WifiDebugHostWakeReasonStats stats = new WifiDebugHostWakeReasonStats();
894        Random rand = new Random();
895        stats.totalCmdEventWakeCnt = rand.nextInt();
896        stats.totalDriverFwLocalWakeCnt = rand.nextInt();
897        stats.totalRxPacketWakeCnt = rand.nextInt();
898        stats.rxPktWakeDetails.rxUnicastCnt = rand.nextInt();
899        stats.rxPktWakeDetails.rxMulticastCnt = rand.nextInt();
900        stats.rxIcmpPkWakeDetails.icmpPkt = rand.nextInt();
901        stats.rxIcmpPkWakeDetails.icmp6Pkt = rand.nextInt();
902        stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt = rand.nextInt();
903        stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt = rand.nextInt();
904
905        doAnswer(new AnswerWithArguments() {
906            public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) {
907                cb.onValues(mWifiStatusSuccess, stats);
908            }
909        }).when(mIWifiChip).getDebugHostWakeReasonStats(
910                any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
911
912        assertNull(mWifiVendorHal.getWlanWakeReasonCount());
913        verify(mIWifiChip, never())
914                .getDebugHostWakeReasonStats(
915                        any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
916
917        assertTrue(mWifiVendorHal.startVendorHalSta());
918
919        WifiWakeReasonAndCounts retrievedStats = mWifiVendorHal.getWlanWakeReasonCount();
920        verify(mIWifiChip).getDebugHostWakeReasonStats(
921                any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
922        assertNotNull(retrievedStats);
923        assertEquals(stats.totalCmdEventWakeCnt, retrievedStats.totalCmdEventWake);
924        assertEquals(stats.totalDriverFwLocalWakeCnt, retrievedStats.totalDriverFwLocalWake);
925        assertEquals(stats.totalRxPacketWakeCnt, retrievedStats.totalRxDataWake);
926        assertEquals(stats.rxPktWakeDetails.rxUnicastCnt, retrievedStats.rxUnicast);
927        assertEquals(stats.rxPktWakeDetails.rxMulticastCnt, retrievedStats.rxMulticast);
928        assertEquals(stats.rxIcmpPkWakeDetails.icmpPkt, retrievedStats.icmp);
929        assertEquals(stats.rxIcmpPkWakeDetails.icmp6Pkt, retrievedStats.icmp6);
930        assertEquals(stats.rxMulticastPkWakeDetails.ipv4RxMulticastAddrCnt,
931                retrievedStats.ipv4RxMulticast);
932        assertEquals(stats.rxMulticastPkWakeDetails.ipv6RxMulticastAddrCnt,
933                retrievedStats.ipv6Multicast);
934    }
935
936    /**
937     * Tests the failure in retrieval of wlan wake reason stats.
938     */
939    @Test
940    public void testGetWlanWakeReasonCountFailure() throws Exception {
941        doAnswer(new AnswerWithArguments() {
942            public void answer(IWifiChip.getDebugHostWakeReasonStatsCallback cb) {
943                cb.onValues(mWifiStatusFailure, new WifiDebugHostWakeReasonStats());
944            }
945        }).when(mIWifiChip).getDebugHostWakeReasonStats(
946                any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
947
948        // This should work in both AP & STA mode.
949        assertTrue(mWifiVendorHal.startVendorHalAp());
950
951        assertNull(mWifiVendorHal.getWlanWakeReasonCount());
952        verify(mIWifiChip).getDebugHostWakeReasonStats(
953                any(IWifiChip.getDebugHostWakeReasonStatsCallback.class));
954    }
955
956    /**
957     * Test that getFwMemoryDump is properly plumbed
958     */
959    @Test
960    public void testGetFwMemoryDump() throws Exception {
961        byte [] sample = NativeUtil.hexStringToByteArray("268c7a3fbfa4661c0bdd6a36");
962        ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample);
963
964        doAnswer(new AnswerWithArguments() {
965            public void answer(IWifiChip.requestFirmwareDebugDumpCallback cb)
966                    throws RemoteException {
967                cb.onValues(mWifiStatusSuccess, halBlob);
968            }
969        }).when(mIWifiChip).requestFirmwareDebugDump(any(
970                IWifiChip.requestFirmwareDebugDumpCallback.class));
971
972        assertTrue(mWifiVendorHal.startVendorHalSta());
973        assertArrayEquals(sample, mWifiVendorHal.getFwMemoryDump());
974    }
975
976    /**
977     * Test that getDriverStateDump is properly plumbed
978     *
979     * Just for variety, use AP mode here.
980     */
981    @Test
982    public void testGetDriverStateDump() throws Exception {
983        byte [] sample = NativeUtil.hexStringToByteArray("e83ff543cf80083e6459d20f");
984        ArrayList<Byte> halBlob = NativeUtil.byteArrayToArrayList(sample);
985
986        doAnswer(new AnswerWithArguments() {
987            public void answer(IWifiChip.requestDriverDebugDumpCallback cb)
988                    throws RemoteException {
989                cb.onValues(mWifiStatusSuccess, halBlob);
990            }
991        }).when(mIWifiChip).requestDriverDebugDump(any(
992                IWifiChip.requestDriverDebugDumpCallback.class));
993
994        assertTrue(mWifiVendorHal.startVendorHalAp());
995        assertArrayEquals(sample, mWifiVendorHal.getDriverStateDump());
996    }
997}
998