summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config/hiddenapi-greylist.txt19
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java4
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java11
-rw-r--r--services/net/java/android/net/apf/ApfFilter.java72
-rw-r--r--telecomm/java/android/telecom/Call.java11
-rw-r--r--telecomm/java/android/telecom/CallScreeningService.java25
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java4
-rw-r--r--telephony/java/android/telephony/DataFailCause.java259
-rw-r--r--tests/net/java/android/net/apf/ApfTest.java28
10 files changed, 357 insertions, 81 deletions
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 2aeb4310733e..30e9bfbb5a93 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -2938,7 +2938,6 @@ Lcom/android/internal/telephony/dataconnection/DataConnection;->mActivatingState
Lcom/android/internal/telephony/dataconnection/DataConnection;->mActiveState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcActiveState;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mConnectionParams:Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mDataRegState:I
-Lcom/android/internal/telephony/dataconnection/DataConnection;->mDcFailCause:Lcom/android/internal/telephony/dataconnection/DcFailCause;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingErrorCreatingConnection:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectionErrorCreatingConnection;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectingState;
@@ -2949,10 +2948,8 @@ Lcom/android/internal/telephony/dataconnection/DataConnection;->mLinkProperties:
Lcom/android/internal/telephony/dataconnection/DataConnection;->mNetworkInfo:Landroid/net/NetworkInfo;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mPhone:Lcom/android/internal/telephony/Phone;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mRilRat:I
-Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DcFailCause;)V
Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfConnected(Ljava/lang/String;)V
Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfDisconnectDcRetrying(Ljava/lang/String;)V
-Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyConnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;Lcom/android/internal/telephony/dataconnection/DcFailCause;Z)V
Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$DisconnectParams;Z)V
Lcom/android/internal/telephony/dataconnection/DataConnection;->onConnect(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;)V
Lcom/android/internal/telephony/dataconnection/DataConnection;->tearDownData(Ljava/lang/Object;)V
@@ -2961,22 +2958,6 @@ Lcom/android/internal/telephony/dataconnection/DcController;->lr(Ljava/lang/Stri
Lcom/android/internal/telephony/dataconnection/DcController;->mDcListActiveByCid:Ljava/util/HashMap;
Lcom/android/internal/telephony/dataconnection/DcController;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker;
Lcom/android/internal/telephony/dataconnection/DcController;->mDcTesterDeactivateAll:Lcom/android/internal/telephony/dataconnection/DcTesterDeactivateAll;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ACTIVATION_REJECT_GGSN:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ACTIVATION_REJECT_UNSPECIFIED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->APN_TYPE_CONFLICT:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->INSUFFICIENT_RESOURCES:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->MISSING_UNKNOWN_APN:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->NSAPI_IN_USE:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_IPV4_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_IPV6_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_SINGLE_BEARER_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->OPERATOR_BARRED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->PROTOCOL_ERRORS:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_NOT_SUBSCRIBED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_NOT_SUPPORTED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_OUT_OF_ORDER:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->UNKNOWN_PDP_ADDRESS_TYPE:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->USER_AUTHENTICATION:Lcom/android/internal/telephony/dataconnection/DcFailCause;
Lcom/android/internal/telephony/dataconnection/DcTracker$RecoveryAction;->isAggressiveRecovery(I)Z
Lcom/android/internal/telephony/dataconnection/DcTracker;->cancelReconnectAlarm(Lcom/android/internal/telephony/dataconnection/ApnContext;)V
Lcom/android/internal/telephony/dataconnection/DcTracker;->cleanUpAllConnections(Ljava/lang/String;)V
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
index 4c45a75d876a..cb2a088f738b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
@@ -25,9 +25,9 @@ import android.content.pm.UserInfo;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import android.sysprop.CarProperties;
import android.util.Log;
import com.android.internal.util.UserIcons;
@@ -43,7 +43,6 @@ import java.util.List;
@Deprecated
public final class UserManagerHelper {
private static final String TAG = "UserManagerHelper";
- private static final String HEADLESS_SYSTEM_USER = "android.car.systemuser.headless";
private final Context mContext;
private final UserManager mUserManager;
private final ActivityManager mActivityManager;
@@ -84,7 +83,7 @@ public final class UserManagerHelper {
* @return {@boolean true} if headless system user.
*/
public boolean isHeadlessSystemUser() {
- return SystemProperties.getBoolean(HEADLESS_SYSTEM_USER, false);
+ return CarProperties.headless_system_user().orElse(false);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 83021ca51a55..be46d2c7e4ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.car;
import android.app.ActivityManager;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
-import android.os.SystemProperties;
+import android.sysprop.CarProperties;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
@@ -56,7 +56,7 @@ public class CarStatusBar extends StatusBar implements
CarBatteryController.BatteryViewHandler {
private static final String TAG = "CarStatusBar";
public static final boolean ENABLE_HVAC_CONNECTION
- = !SystemProperties.getBoolean("android.car.hvac.demo", true);
+ = !CarProperties.hvac_demo().orElse(true);
private TaskStackListenerImpl mTaskStackListener;
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index d0e8b47e6db7..0f00c114e5bc 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -163,8 +163,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub
private static final int MAX_UID_RANGES_PER_COMMAND = 10;
- private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
/**
* Name representing {@link #setGlobalAlert(long)} limit when delivered to
* {@link INetworkManagementEventObserver#limitReached(String, String)}.
@@ -954,8 +952,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
public String[] listInterfaces() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- final List<String> result = mNetdService.interfaceGetList();
- return result.toArray(EMPTY_STRING_ARRAY);
+ return mNetdService.interfaceGetList();
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
@@ -1247,8 +1244,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
public String[] listTetheredInterfaces() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- final List<String> result = mNetdService.tetherInterfaceList();
- return result.toArray(EMPTY_STRING_ARRAY);
+ return mNetdService.tetherInterfaceList();
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
@@ -1271,8 +1267,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
public String[] getDnsForwarders() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- final List<String> result = mNetdService.tetherDnsList();
- return result.toArray(EMPTY_STRING_ARRAY);
+ return mNetdService.tetherDnsList();
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index b9cc372c5138..f0379059a5f7 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -139,7 +139,8 @@ public class ApfFilter {
DROPPED_IPV6_MULTICAST_PING,
DROPPED_IPV6_NON_ICMP_MULTICAST,
DROPPED_802_3_FRAME,
- DROPPED_ETHERTYPE_BLACKLISTED;
+ DROPPED_ETHERTYPE_BLACKLISTED,
+ DROPPED_ARP_REPLY_SPA_NO_HOST;
// Returns the negative byte offset from the end of the APF data segment for
// a given counter.
@@ -156,7 +157,7 @@ public class ApfFilter {
/**
* When APFv4 is supported, loads R1 with the offset of the specified counter.
*/
- private void maybeSetCounter(ApfGenerator gen, Counter c) {
+ private void maybeSetupCounter(ApfGenerator gen, Counter c) {
if (mApfCapabilities.hasDataAccess()) {
gen.addLoadImmediate(Register.R1, c.offset());
}
@@ -288,16 +289,18 @@ public class ApfFilter {
private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN;
- private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
- private static final short ARP_OPCODE_REQUEST = 1;
- private static final short ARP_OPCODE_REPLY = 2;
private static final byte[] ARP_IPV4_HEADER = {
0, 1, // Hardware type: Ethernet (1)
8, 0, // Protocol type: IP (0x0800)
6, // Hardware size: 6
4, // Protocol size: 4
};
- private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24;
+ private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
+ // Opcode: ARP request (0x0001), ARP reply (0x0002)
+ private static final short ARP_OPCODE_REQUEST = 1;
+ private static final short ARP_OPCODE_REPLY = 2;
+ private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
+ private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
// Do not log ApfProgramEvents whose actual lifetimes was less than this.
private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2;
// Limit on the Black List size to cap on program usage for this
@@ -816,7 +819,7 @@ public class ApfFilter {
gen.addJumpIfR0LessThan(filterLifetime, nextFilterLabel);
}
}
- maybeSetCounter(gen, Counter.DROPPED_RA);
+ maybeSetupCounter(gen, Counter.DROPPED_RA);
gen.addJump(mCountAndDropLabel);
gen.defineLabel(nextFilterLabel);
return filterLifetime;
@@ -883,6 +886,8 @@ public class ApfFilter {
// pass
// if not ARP IPv4 reply or request
// pass
+ // if ARP reply source ip is 0.0.0.0
+ // drop
// if unicast ARP reply
// pass
// if interface has no IPv4 address
@@ -897,18 +902,23 @@ public class ApfFilter {
// Pass if not ARP IPv4.
gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET);
- maybeSetCounter(gen, Counter.PASSED_ARP_NON_IPV4);
+ maybeSetupCounter(gen, Counter.PASSED_ARP_NON_IPV4);
gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_HEADER, mCountAndPassLabel);
// Pass if unknown ARP opcode.
gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET);
gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check
- maybeSetCounter(gen, Counter.PASSED_ARP_UNKNOWN);
+ maybeSetupCounter(gen, Counter.PASSED_ARP_UNKNOWN);
gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, mCountAndPassLabel);
+ // Drop if ARP reply source IP is 0.0.0.0
+ gen.addLoad32(Register.R0, ARP_SOURCE_IP_ADDRESS_OFFSET);
+ maybeSetupCounter(gen, Counter.DROPPED_ARP_REPLY_SPA_NO_HOST);
+ gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
+
// Pass if unicast reply.
gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
- maybeSetCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
+ maybeSetupCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
// Either a unicast request, a unicast reply, or a broadcast reply.
@@ -916,17 +926,17 @@ public class ApfFilter {
if (mIPv4Address == null) {
// When there is no IPv4 address, drop GARP replies (b/29404209).
gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
- maybeSetCounter(gen, Counter.DROPPED_GARP_REPLY);
+ maybeSetupCounter(gen, Counter.DROPPED_GARP_REPLY);
gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
} else {
// When there is an IPv4 address, drop unicast/broadcast requests
// and broadcast replies with a different target IPv4 address.
gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
- maybeSetCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
+ maybeSetupCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, mCountAndDropLabel);
}
- maybeSetCounter(gen, Counter.PASSED_ARP);
+ maybeSetupCounter(gen, Counter.PASSED_ARP);
gen.addJump(mCountAndPassLabel);
}
@@ -970,7 +980,7 @@ public class ApfFilter {
// NOTE: Relies on R1 containing IPv4 header offset.
gen.addAddR1();
gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, skipDhcpv4Filter);
- maybeSetCounter(gen, Counter.PASSED_DHCP);
+ maybeSetupCounter(gen, Counter.PASSED_DHCP);
gen.addJump(mCountAndPassLabel);
// Drop all multicasts/broadcasts.
@@ -979,30 +989,30 @@ public class ApfFilter {
// If IPv4 destination address is in multicast range, drop.
gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET);
gen.addAnd(0xf0);
- maybeSetCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
gen.addJumpIfR0Equals(0xe0, mCountAndDropLabel);
// If IPv4 broadcast packet, drop regardless of L2 (b/30231088).
- maybeSetCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET);
gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, mCountAndDropLabel);
if (mIPv4Address != null && mIPv4PrefixLength < 31) {
- maybeSetCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
int broadcastAddr = ipv4BroadcastAddress(mIPv4Address, mIPv4PrefixLength);
gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
}
// If L2 broadcast packet, drop.
// TODO: can we invert this condition to fall through to the common pass case below?
- maybeSetCounter(gen, Counter.PASSED_IPV4_UNICAST);
+ maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST);
gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
- maybeSetCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
gen.addJump(mCountAndDropLabel);
}
// Otherwise, pass
- maybeSetCounter(gen, Counter.PASSED_IPV4);
+ maybeSetupCounter(gen, Counter.PASSED_IPV4);
gen.addJump(mCountAndPassLabel);
}
@@ -1050,16 +1060,16 @@ public class ApfFilter {
// Drop all other packets sent to ff00::/8 (multicast prefix).
gen.defineLabel(dropAllIPv6MulticastsLabel);
- maybeSetCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET);
gen.addJumpIfR0Equals(0xff, mCountAndDropLabel);
// Not multicast. Pass.
- maybeSetCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
+ maybeSetupCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
gen.addJump(mCountAndPassLabel);
gen.defineLabel(skipIPv6MulticastFilterLabel);
} else {
// If not ICMPv6, pass.
- maybeSetCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
+ maybeSetupCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, mCountAndPassLabel);
}
@@ -1069,7 +1079,7 @@ public class ApfFilter {
String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA";
gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
// Drop all router solicitations (b/32833400)
- maybeSetCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, mCountAndDropLabel);
// If not neighbor announcements, skip filter.
gen.addJumpIfR0NotEquals(ICMPV6_NEIGHBOR_ADVERTISEMENT, skipUnsolicitedMulticastNALabel);
@@ -1078,7 +1088,7 @@ public class ApfFilter {
gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET);
gen.addJumpIfBytesNotEqual(Register.R0, IPV6_ALL_NODES_ADDRESS,
skipUnsolicitedMulticastNALabel);
- maybeSetCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
gen.addJump(mCountAndDropLabel);
gen.defineLabel(skipUnsolicitedMulticastNALabel);
}
@@ -1108,7 +1118,7 @@ public class ApfFilter {
if (mApfCapabilities.hasDataAccess()) {
// Increment TOTAL_PACKETS
- maybeSetCounter(gen, Counter.TOTAL_PACKETS);
+ maybeSetupCounter(gen, Counter.TOTAL_PACKETS);
gen.addLoadData(Register.R0, 0); // load counter
gen.addAdd(1);
gen.addStoreData(Register.R0, 0); // write-back counter
@@ -1134,12 +1144,12 @@ public class ApfFilter {
if (mDrop802_3Frames) {
// drop 802.3 frames (ethtype < 0x0600)
- maybeSetCounter(gen, Counter.DROPPED_802_3_FRAME);
+ maybeSetupCounter(gen, Counter.DROPPED_802_3_FRAME);
gen.addJumpIfR0LessThan(ETH_TYPE_MIN, mCountAndDropLabel);
}
// Handle ether-type black list
- maybeSetCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
+ maybeSetupCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
for (int p : mEthTypeBlackList) {
gen.addJumpIfR0Equals(p, mCountAndDropLabel);
}
@@ -1168,9 +1178,9 @@ public class ApfFilter {
// Drop non-IP non-ARP broadcasts, pass the rest
gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
- maybeSetCounter(gen, Counter.PASSED_NON_IP_UNICAST);
+ maybeSetupCounter(gen, Counter.PASSED_NON_IP_UNICAST);
gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
- maybeSetCounter(gen, Counter.DROPPED_ETH_BROADCAST);
+ maybeSetupCounter(gen, Counter.DROPPED_ETH_BROADCAST);
gen.addJump(mCountAndDropLabel);
// Add IPv6 filters:
@@ -1193,7 +1203,7 @@ public class ApfFilter {
// Execution will reach the bottom of the program if none of the filters match,
// which will pass the packet to the application processor.
- maybeSetCounter(gen, Counter.PASSED_IPV6_ICMP);
+ maybeSetupCounter(gen, Counter.PASSED_IPV6_ICMP);
// Append the count & pass trampoline, which increments the counter at the data address
// pointed to by R1, then jumps to the pass label. This saves a few bytes over inserting
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index bf0ffb94b252..36d0188048c3 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -29,7 +29,6 @@ import android.os.ParcelFileDescriptor;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
-import java.lang.String;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
@@ -919,10 +918,16 @@ public final class Call {
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("[pa: ");
+ sb.append("[id: ");
+ sb.append(mTelecomCallId);
+ sb.append(", pa: ");
sb.append(mAccountHandle);
sb.append(", hdl: ");
- sb.append(Log.pii(mHandle));
+ sb.append(Log.piiHandle(mHandle));
+ sb.append(", hdlPres: ");
+ sb.append(mHandlePresentation);
+ sb.append(", videoState: ");
+ sb.append(VideoProfile.videoStateToString(mVideoState));
sb.append(", caps: ");
sb.append(capabilitiesToString(mCallCapabilities));
sb.append(", props: ");
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 7db69407ad3d..662874316a7f 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -27,8 +27,8 @@ import android.os.Message;
import android.os.RemoteException;
import com.android.internal.os.SomeArgs;
-import com.android.internal.telecom.ICallScreeningService;
import com.android.internal.telecom.ICallScreeningAdapter;
+import com.android.internal.telecom.ICallScreeningService;
/**
* This service can be implemented by the default dialer (see
@@ -147,7 +147,7 @@ public abstract class CallScreeningService extends Service {
private boolean mShouldSkipCallLog;
private boolean mShouldSkipNotification;
- /*
+ /**
* Sets whether the incoming call should be blocked.
*/
public Builder setDisallowCall(boolean shouldDisallowCall) {
@@ -155,7 +155,7 @@ public abstract class CallScreeningService extends Service {
return this;
}
- /*
+ /**
* Sets whether the incoming call should be disconnected as if the user had manually
* rejected it. This property should only be set to true if the call is disallowed.
*/
@@ -164,16 +164,20 @@ public abstract class CallScreeningService extends Service {
return this;
}
- /*
+ /**
* Sets whether the incoming call should not be displayed in the call log. This property
* should only be set to true if the call is disallowed.
+ * <p>
+ * Note: Calls will still be logged with type
+ * {@link android.provider.CallLog.Calls#BLOCKED_TYPE}, regardless of how this property
+ * is set.
*/
public Builder setSkipCallLog(boolean shouldSkipCallLog) {
mShouldSkipCallLog = shouldSkipCallLog;
return this;
}
- /*
+ /**
* Sets whether a missed call notification should not be shown for the incoming call.
* This property should only be set to true if the call is disallowed.
*/
@@ -211,6 +215,17 @@ public abstract class CallScreeningService extends Service {
* Called when a new incoming call is added.
* {@link CallScreeningService#respondToCall(Call.Details, CallScreeningService.CallResponse)}
* should be called to allow or disallow the call.
+ * <p>
+ * Note: The {@link Call.Details} instance provided to a call screening service will only have
+ * the following properties set. The rest of the {@link Call.Details} properties will be set to
+ * their default value or {@code null}.
+ * <ul>
+ * <li>{@link Call.Details#getState()}</li>
+ * <li>{@link Call.Details#getConnectTimeMillis()}</li>
+ * <li>{@link Call.Details#getCreationTimeMillis()}</li>
+ * <li>{@link Call.Details#getHandle()}</li>
+ * <li>{@link Call.Details#getHandlePresentation()}</li>
+ * </ul>
*
* @param callDetails Information about a new incoming call, see {@link Call.Details}.
*/
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 14e0909bba97..fed58c167a85 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1392,9 +1392,9 @@ public class CarrierConfigManager {
* Example: "default"
*
* {@code ERROR_CODE_1} is an integer defined in
- * {@link com.android.internal.telephony.dataconnection.DcFailCause DcFailure}
+ * {@link DataFailCause DcFailure}
* Example:
- * {@link com.android.internal.telephony.dataconnection.DcFailCause#MISSING_UNKNOWN_APN}
+ * {@link DataFailCause#MISSING_UNKNOWN_APN}
*
* {@code CARRIER_ACTION_IDX_1} is an integer defined in
* {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils}
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
new file mode 100644
index 000000000000..c6f7d0e458db
--- /dev/null
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony;
+
+import android.content.Context;
+import android.os.PersistableBundle;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+
+/**
+ * Returned as the reason for a connection failure as defined
+ * by RIL_DataCallFailCause in ril.h and some local errors.
+ * @hide
+ */
+public enum DataFailCause {
+ NONE(0),
+
+ // This series of errors as specified by the standards
+ // specified in ril.h
+ OPERATOR_BARRED(0x08), /* no retry */
+ NAS_SIGNALLING(0x0E),
+ LLC_SNDCP(0x19),
+ INSUFFICIENT_RESOURCES(0x1A),
+ MISSING_UNKNOWN_APN(0x1B), /* no retry */
+ UNKNOWN_PDP_ADDRESS_TYPE(0x1C), /* no retry */
+ USER_AUTHENTICATION(0x1D), /* no retry */
+ ACTIVATION_REJECT_GGSN(0x1E), /* no retry */
+ ACTIVATION_REJECT_UNSPECIFIED(0x1F),
+ SERVICE_OPTION_NOT_SUPPORTED(0x20), /* no retry */
+ SERVICE_OPTION_NOT_SUBSCRIBED(0x21), /* no retry */
+ SERVICE_OPTION_OUT_OF_ORDER(0x22),
+ NSAPI_IN_USE(0x23), /* no retry */
+ REGULAR_DEACTIVATION(0x24), /* possibly restart radio, based on config */
+ QOS_NOT_ACCEPTED(0x25),
+ NETWORK_FAILURE(0x26),
+ UMTS_REACTIVATION_REQ(0x27),
+ FEATURE_NOT_SUPP(0x28),
+ TFT_SEMANTIC_ERROR(0x29),
+ TFT_SYTAX_ERROR(0x2A),
+ UNKNOWN_PDP_CONTEXT(0x2B),
+ FILTER_SEMANTIC_ERROR(0x2C),
+ FILTER_SYTAX_ERROR(0x2D),
+ PDP_WITHOUT_ACTIVE_TFT(0x2E),
+ ONLY_IPV4_ALLOWED(0x32), /* no retry */
+ ONLY_IPV6_ALLOWED(0x33), /* no retry */
+ ONLY_SINGLE_BEARER_ALLOWED(0x34),
+ ESM_INFO_NOT_RECEIVED(0x35),
+ PDN_CONN_DOES_NOT_EXIST(0x36),
+ MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED(0x37),
+ MAX_ACTIVE_PDP_CONTEXT_REACHED(0x41),
+ UNSUPPORTED_APN_IN_CURRENT_PLMN(0x42),
+ INVALID_TRANSACTION_ID(0x51),
+ MESSAGE_INCORRECT_SEMANTIC(0x5F),
+ INVALID_MANDATORY_INFO(0x60),
+ MESSAGE_TYPE_UNSUPPORTED(0x61),
+ MSG_TYPE_NONCOMPATIBLE_STATE(0x62),
+ UNKNOWN_INFO_ELEMENT(0x63),
+ CONDITIONAL_IE_ERROR(0x64),
+ MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE(0x65),
+ PROTOCOL_ERRORS(0x6F), /* no retry */
+ APN_TYPE_CONFLICT(0x70),
+ INVALID_PCSCF_ADDR(0x71),
+ INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN(0x72),
+ EMM_ACCESS_BARRED(0x73),
+ EMERGENCY_IFACE_ONLY(0x74),
+ IFACE_MISMATCH(0x75),
+ COMPANION_IFACE_IN_USE(0x76),
+ IP_ADDRESS_MISMATCH(0x77),
+ IFACE_AND_POL_FAMILY_MISMATCH(0x78),
+ EMM_ACCESS_BARRED_INFINITE_RETRY(0x79),
+ AUTH_FAILURE_ON_EMERGENCY_CALL(0x7A),
+
+ // OEM sepecific error codes. To be used by OEMs when they don't
+ // want to reveal error code which would be replaced by ERROR_UNSPECIFIED
+ OEM_DCFAILCAUSE_1(0x1001),
+ OEM_DCFAILCAUSE_2(0x1002),
+ OEM_DCFAILCAUSE_3(0x1003),
+ OEM_DCFAILCAUSE_4(0x1004),
+ OEM_DCFAILCAUSE_5(0x1005),
+ OEM_DCFAILCAUSE_6(0x1006),
+ OEM_DCFAILCAUSE_7(0x1007),
+ OEM_DCFAILCAUSE_8(0x1008),
+ OEM_DCFAILCAUSE_9(0x1009),
+ OEM_DCFAILCAUSE_10(0x100A),
+ OEM_DCFAILCAUSE_11(0x100B),
+ OEM_DCFAILCAUSE_12(0x100C),
+ OEM_DCFAILCAUSE_13(0x100D),
+ OEM_DCFAILCAUSE_14(0x100E),
+ OEM_DCFAILCAUSE_15(0x100F),
+
+ // Local errors generated by Vendor RIL
+ // specified in ril.h
+ REGISTRATION_FAIL(-1),
+ GPRS_REGISTRATION_FAIL(-2),
+ SIGNAL_LOST(-3), /* no retry */
+ PREF_RADIO_TECH_CHANGED(-4),
+ RADIO_POWER_OFF(-5), /* no retry */
+ TETHERED_CALL_ACTIVE(-6), /* no retry */
+ ERROR_UNSPECIFIED(0xFFFF),
+
+ // Errors generated by the Framework
+ // specified here
+ UNKNOWN(0x10000),
+ RADIO_NOT_AVAILABLE(0x10001), /* no retry */
+ UNACCEPTABLE_NETWORK_PARAMETER(0x10002), /* no retry */
+ CONNECTION_TO_DATACONNECTIONAC_BROKEN(0x10003),
+ LOST_CONNECTION(0x10004),
+ RESET_BY_FRAMEWORK(0x10005);
+
+ private final int mErrorCode;
+ private static final HashMap<Integer, DataFailCause> sErrorCodeToFailCauseMap;
+ static {
+ sErrorCodeToFailCauseMap = new HashMap<Integer, DataFailCause>();
+ for (DataFailCause fc : values()) {
+ sErrorCodeToFailCauseMap.put(fc.getErrorCode(), fc);
+ }
+ }
+
+ /**
+ * Map of subId -> set of data call setup permanent failure for the carrier.
+ */
+ private static final HashMap<Integer, HashSet<DataFailCause>> sPermanentFailureCache =
+ new HashMap<>();
+
+ DataFailCause(int errorCode) {
+ mErrorCode = errorCode;
+ }
+
+ public int getErrorCode() {
+ return mErrorCode;
+ }
+
+ /**
+ * Returns whether or not the fail cause is a failure that requires a modem restart
+ *
+ * @param context device context
+ * @param subId subscription index
+ * @return true if the fail cause code needs platform to trigger a modem restart.
+ */
+ public boolean isRadioRestartFailure(Context context, int subId) {
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager != null) {
+ PersistableBundle b = configManager.getConfigForSubId(subId);
+
+ if (b != null) {
+ if (this == REGULAR_DEACTIVATION
+ && b.getBoolean(CarrierConfigManager
+ .KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL)) {
+ // This is for backward compatibility support. We need to continue support this
+ // old configuration until it gets removed in the future.
+ return true;
+ }
+ // Check the current configurations.
+ int[] causeCodes = b.getIntArray(CarrierConfigManager
+ .KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY);
+ if (causeCodes != null) {
+ return Arrays.stream(causeCodes).anyMatch(i -> i == getErrorCode());
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public boolean isPermanentFailure(Context context, int subId) {
+
+ synchronized (sPermanentFailureCache) {
+
+ HashSet<DataFailCause> permanentFailureSet = sPermanentFailureCache.get(subId);
+
+ // In case of cache miss, we need to look up the settings from carrier config.
+ if (permanentFailureSet == null) {
+ // Retrieve the permanent failure from carrier config
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager != null) {
+ PersistableBundle b = configManager.getConfigForSubId(subId);
+ if (b != null) {
+ String[] permanentFailureStrings = b.getStringArray(CarrierConfigManager.
+ KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS);
+
+ if (permanentFailureStrings != null) {
+ permanentFailureSet = new HashSet<>();
+ for (String failure : permanentFailureStrings) {
+ permanentFailureSet.add(DataFailCause.valueOf(failure));
+ }
+ }
+ }
+ }
+
+ // If we are not able to find the configuration from carrier config, use the default
+ // ones.
+ if (permanentFailureSet == null) {
+ permanentFailureSet = new HashSet<DataFailCause>() {
+ {
+ add(OPERATOR_BARRED);
+ add(MISSING_UNKNOWN_APN);
+ add(UNKNOWN_PDP_ADDRESS_TYPE);
+ add(USER_AUTHENTICATION);
+ add(ACTIVATION_REJECT_GGSN);
+ add(SERVICE_OPTION_NOT_SUPPORTED);
+ add(SERVICE_OPTION_NOT_SUBSCRIBED);
+ add(NSAPI_IN_USE);
+ add(ONLY_IPV4_ALLOWED);
+ add(ONLY_IPV6_ALLOWED);
+ add(PROTOCOL_ERRORS);
+ add(RADIO_POWER_OFF);
+ add(TETHERED_CALL_ACTIVE);
+ add(RADIO_NOT_AVAILABLE);
+ add(UNACCEPTABLE_NETWORK_PARAMETER);
+ add(SIGNAL_LOST);
+ }
+ };
+ }
+
+ sPermanentFailureCache.put(subId, permanentFailureSet);
+ }
+
+ return permanentFailureSet.contains(this);
+ }
+ }
+
+ public boolean isEventLoggable() {
+ return (this == OPERATOR_BARRED) || (this == INSUFFICIENT_RESOURCES) ||
+ (this == UNKNOWN_PDP_ADDRESS_TYPE) || (this == USER_AUTHENTICATION) ||
+ (this == ACTIVATION_REJECT_GGSN) || (this == ACTIVATION_REJECT_UNSPECIFIED) ||
+ (this == SERVICE_OPTION_NOT_SUBSCRIBED) ||
+ (this == SERVICE_OPTION_NOT_SUPPORTED) ||
+ (this == SERVICE_OPTION_OUT_OF_ORDER) || (this == NSAPI_IN_USE) ||
+ (this == ONLY_IPV4_ALLOWED) || (this == ONLY_IPV6_ALLOWED) ||
+ (this == PROTOCOL_ERRORS) || (this == SIGNAL_LOST) ||
+ (this == RADIO_POWER_OFF) || (this == TETHERED_CALL_ACTIVE) ||
+ (this == UNACCEPTABLE_NETWORK_PARAMETER);
+ }
+
+ public static DataFailCause fromInt(int errorCode) {
+ DataFailCause fc = sErrorCodeToFailCauseMap.get(errorCode);
+ if (fc == null) {
+ fc = UNKNOWN;
+ }
+ return fc;
+ }
+}
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
index 436dd859beca..151b5594216a 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -1048,12 +1048,17 @@ public class ApfTest {
4, // Protocol size: 4
0, 2 // Opcode: reply (2)
};
- private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24;
+ private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
+ private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
private static final byte[] MOCK_IPV4_ADDR = {10, 0, 0, 1};
private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, 31, (byte) 255}; // prefix = 19
private static final byte[] MOCK_MULTICAST_IPV4_ADDR = {(byte) 224, 0, 0, 1};
private static final byte[] ANOTHER_IPV4_ADDR = {10, 0, 0, 2};
+ private static final byte[] IPV4_SOURCE_ADDR = {10, 0, 0, 3};
+ private static final byte[] ANOTHER_IPV4_SOURCE_ADDR = {(byte) 192, 0, 2, 1};
+ private static final byte[] BUG_PROBE_SOURCE_ADDR1 = {0, 0, 1, 2};
+ private static final byte[] BUG_PROBE_SOURCE_ADDR2 = {3, 4, 0, 0};
private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0};
// Helper to initialize a default apfFilter.
@@ -1399,10 +1404,16 @@ public class ApfTest {
assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR));
assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR));
+ // Verify ARP reply packets from different source ip
+ assertDrop(program, arpReply(IPV4_ANY_HOST_ADDR, IPV4_ANY_HOST_ADDR));
+ assertPass(program, arpReply(ANOTHER_IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
+ assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR1, IPV4_ANY_HOST_ADDR));
+ assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR2, IPV4_ANY_HOST_ADDR));
+
// Verify unicast ARP reply packet is always accepted.
- assertPass(program, arpReplyUnicast(MOCK_IPV4_ADDR));
- assertPass(program, arpReplyUnicast(ANOTHER_IPV4_ADDR));
- assertPass(program, arpReplyUnicast(IPV4_ANY_HOST_ADDR));
+ assertPass(program, arpReply(IPV4_SOURCE_ADDR, MOCK_IPV4_ADDR));
+ assertPass(program, arpReply(IPV4_SOURCE_ADDR, ANOTHER_IPV4_ADDR));
+ assertPass(program, arpReply(IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
// Verify GARP reply packets are always filtered
assertDrop(program, garpReply());
@@ -1431,19 +1442,20 @@ public class ApfTest {
apfFilter.shutdown();
}
- private static byte[] arpRequestBroadcast(byte[] tip) {
+ private static byte[] arpReply(byte[] sip, byte[] tip) {
ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
- put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
+ put(packet, ARP_SOURCE_IP_ADDRESS_OFFSET, sip);
put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
return packet.array();
}
- private static byte[] arpReplyUnicast(byte[] tip) {
+ private static byte[] arpRequestBroadcast(byte[] tip) {
ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
- put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
+ put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
+ put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REQUEST_HEADER);
put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
return packet.array();
}