diff options
author | Bernie Innocenti <codewiz@google.com> | 2018-04-16 13:48:10 +0900 |
---|---|---|
committer | Bernie Innocenti <codewiz@google.com> | 2018-04-19 22:20:42 +0900 |
commit | e25d3edec10f7b9cd60c291808f760a490b7d31d (patch) | |
tree | a11d56446b6f6a644b2364fe99457d00bad3f598 | |
parent | d5faea1644d2360f5c776cb833f2123e1c082f35 (diff) |
WifiNative plumbing for reading back the APF program & data buffer
Bug: 73804303
Test: frameworks/opt/net/wifi/tests/wifitests/runtests.sh
Change-Id: Ib2a0f2ec04df28aabf422fa3149850f601f55db9
4 files changed, 101 insertions, 4 deletions
diff --git a/service/java/com/android/server/wifi/WifiNative.java b/service/java/com/android/server/wifi/WifiNative.java index c86f566a0..8a76c4d3b 100644 --- a/service/java/com/android/server/wifi/WifiNative.java +++ b/service/java/com/android/server/wifi/WifiNative.java @@ -2195,7 +2195,7 @@ public class WifiNative { /** * Installs an APF program on this iface, replacing any existing program. * - * @param ifaceName Name of the interface. + * @param ifaceName Name of the interface * @param filter is the android packet filter program * @return true for success */ @@ -2204,6 +2204,16 @@ public class WifiNative { } /** + * Reads the APF program and data buffer for this iface. + * + * @param ifaceName Name of the interface + * @return the buffer returned by the driver, or null in case of an error + */ + public byte[] readPacketFilter(@NonNull String ifaceName) { + return mWifiVendorHal.readPacketFilter(ifaceName); + } + + /** * Set country code for this AP iface. * @param ifaceName Name of the interface. * @param countryCode - two-letter country code (as ISO 3166) diff --git a/service/java/com/android/server/wifi/WifiStateMachine.java b/service/java/com/android/server/wifi/WifiStateMachine.java index 32427c92c..4cb7d3722 100644 --- a/service/java/com/android/server/wifi/WifiStateMachine.java +++ b/service/java/com/android/server/wifi/WifiStateMachine.java @@ -636,6 +636,9 @@ public class WifiStateMachine extends StateMachine { /* used to indicate that the foreground user was switched */ static final int CMD_USER_STOP = BASE + 207; + /* Read the APF program & data buffer */ + static final int CMD_READ_PACKET_FILTER = BASE + 208; + /* Indicates that diagnostics should time out a connection start event. */ private static final int CMD_DIAGS_CONNECT_TIMEOUT = BASE + 252; @@ -1065,6 +1068,11 @@ public class WifiStateMachine extends StateMachine { } @Override + public void startReadPacketFilter() { + sendMessage(CMD_READ_PACKET_FILTER); + } + + @Override public void setFallbackMulticastFilter(boolean enabled) { sendMessage(CMD_SET_FALLBACK_PACKET_FILTERING, enabled); } @@ -3578,6 +3586,10 @@ public class WifiStateMachine extends StateMachine { case CMD_INSTALL_PACKET_FILTER: mWifiNative.installPacketFilter(mInterfaceName, (byte[]) message.obj); break; + case CMD_READ_PACKET_FILTER: + byte[] data = mWifiNative.readPacketFilter(mInterfaceName); + mIpClient.readPacketFilterComplete(data); + break; case CMD_SET_FALLBACK_PACKET_FILTERING: if ((boolean) message.obj) { mWifiNative.startFilteringMulticastV4Packets(mInterfaceName); @@ -5636,8 +5648,8 @@ public class WifiStateMachine extends StateMachine { } /** - * State machine initiated requests can have replyTo set to null indicating - * there are no recepients, we ignore those reply actions. + * State machine initiated requests can have replyTo set to null, indicating + * there are no recipients, we ignore those reply actions. */ private void replyToMessage(Message msg, int what) { if (msg.replyTo == null) return; diff --git a/service/java/com/android/server/wifi/WifiVendorHal.java b/service/java/com/android/server/wifi/WifiVendorHal.java index 36060fa55..16a279833 100644 --- a/service/java/com/android/server/wifi/WifiVendorHal.java +++ b/service/java/com/android/server/wifi/WifiVendorHal.java @@ -74,6 +74,7 @@ import android.util.MutableInt; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.HexDump; import com.android.server.wifi.HalDeviceManager.InterfaceDestroyedListener; import com.android.server.wifi.util.BitMask; import com.android.server.wifi.util.NativeUtil; @@ -185,6 +186,26 @@ public class WifiVendorHal { } /** + * Logs the argument along with the method name. + * + * Always returns its argument. + */ + private byte[] byteArrayResult(byte[] result) { + if (mVerboseLog == sNoLog) return result; + // Currently only seen if verbose logging is on + + Thread cur = Thread.currentThread(); + StackTraceElement[] trace = cur.getStackTrace(); + + mVerboseLog.err("% returns %") + .c(niceMethodName(trace, 3)) + .c(HexDump.dumpHexString(result)) + .flush(); + + return result; + } + + /** * Logs at method entry * * @param format string with % placeholders @@ -1738,6 +1759,36 @@ public class WifiVendorHal { } /** + * Reads the APF program and data buffer on this iface. + * + * @param ifaceName Name of the interface + * @return the buffer returned by the driver, or null in case of an error + */ + public byte[] readPacketFilter(@NonNull String ifaceName) { + class AnswerBox { + public byte[] data = null; + } + AnswerBox answer = new AnswerBox(); + enter("").flush(); + // TODO: Must also take the wakelock here to prevent going to sleep with APF disabled. + synchronized (sLock) { + try { + android.hardware.wifi.V1_2.IWifiStaIface ifaceV12 = + getWifiStaIfaceForV1_2Mockable(ifaceName); + if (ifaceV12 == null) return byteArrayResult(null); + ifaceV12.readApfPacketFilterData((status, dataByteArray) -> { + if (!ok(status)) return; + answer.data = NativeUtil.byteArrayFromArrayList(dataByteArray); + }); + return byteArrayResult(answer.data); + } catch (RemoteException e) { + handleRemoteException(e); + return byteArrayResult(null); + } + } + } + + /** * Set country code for this AP iface. * * @param ifaceName Name of the interface. diff --git a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java index 70c612918..9d20235ad 100644 --- a/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java +++ b/tests/wifitests/src/com/android/server/wifi/WifiVendorHalTest.java @@ -1233,6 +1233,31 @@ public class WifiVendorHalTest { } /** + * Test that an APF program and data buffer can be read back. + */ + @Test + public void testReadApf() throws Exception { + // Expose the 1.2 IWifiStaIface. + mWifiVendorHal = new WifiVendorHalSpyV1_2(mHalDeviceManager, mLooper.getLooper()); + + byte[] program = new byte[] {65, 66, 67}; + ArrayList<Byte> expected = new ArrayList<>(3); + for (byte b : program) expected.add(b); + + doAnswer(new AnswerWithArguments() { + public void answer( + android.hardware.wifi.V1_2.IWifiStaIface.readApfPacketFilterDataCallback cb) + throws RemoteException { + cb.onValues(mWifiStatusSuccess, expected); + } + }).when(mIWifiStaIfaceV12).readApfPacketFilterData(any( + android.hardware.wifi.V1_2.IWifiStaIface.readApfPacketFilterDataCallback.class)); + + assertTrue(mWifiVendorHal.startVendorHalSta()); + assertArrayEquals(program, mWifiVendorHal.readPacketFilter(TEST_IFACE_NAME)); + } + + /** * Test that the country code is set in AP mode (when it should be). */ @Test @@ -1348,7 +1373,6 @@ public class WifiVendorHalTest { assertEquals(halBufferStatus.size(), actual.length); assertEquals(oneExpect, actual[0].toString()); assertEquals(two.ringId, actual[1].ringBufferId); - } /** |