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