Merge changes from topic 'android-lowpan-next'

* changes:
  lowpan: AIDL refactor to no longer use property design pattern
  LowpanException: Refactor exception handling
  lowpan: Introduce new unit tests for data classes
  lowpan: Make various data classes Parcelable
  lowpan: Remove libandroid_net_lowpan from platform/frameworks/base
  LowpanEnergyScanResult: Remove `public` designation from setChannel/setMaxRssi
This commit is contained in:
Robert Quattlebaum
2017-07-18 17:30:41 +00:00
committed by Android (Google) Code Review
46 changed files with 2766 additions and 910 deletions

View File

@@ -1,33 +0,0 @@
#
# Copyright (C) 2017 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.
#
LOCAL_PATH := $(call my-dir)
ifneq (,$(findstring lowpan/java,$(FRAMEWORKS_BASE_SUBDIRS)))
include $(CLEAR_VARS)
LOCAL_MODULE := libandroid_net_lowpan
LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES += libbase
LOCAL_SHARED_LIBRARIES += libbinder
LOCAL_SHARED_LIBRARIES += libutils
LOCAL_AIDL_INCLUDES += frameworks/native/aidl/binder
LOCAL_AIDL_INCLUDES += frameworks/base/lowpan/java
LOCAL_AIDL_INCLUDES += frameworks/base/core/java
LOCAL_SRC_FILES += $(call all-Iaidl-files-under, java/android/net/lowpan)
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
endif

View File

@@ -16,103 +16,39 @@
package android.net.lowpan;
import android.net.IpPrefix;
import android.net.lowpan.ILowpanEnergyScanCallback;
import android.net.lowpan.ILowpanInterfaceListener;
import android.net.lowpan.ILowpanNetScanCallback;
import android.net.lowpan.ILowpanEnergyScanCallback;
import android.os.PersistableBundle;
import android.net.IpPrefix;
import android.net.lowpan.LowpanBeaconInfo;
import android.net.lowpan.LowpanChannelInfo;
import android.net.lowpan.LowpanCredential;
import android.net.lowpan.LowpanIdentity;
import android.net.lowpan.LowpanProvision;
/** {@hide} */
interface ILowpanInterface {
//////////////////////////////////////////////////////////////////////////
// Permission String Constants
/* These are here for the sake of C++ interface implementations. */
// These are here for the sake of C++ interface implementations.
const String PERM_ACCESS_LOWPAN_STATE = "android.permission.ACCESS_LOWPAN_STATE";
const String PERM_CHANGE_LOWPAN_STATE = "android.permission.CHANGE_LOWPAN_STATE";
const String PERM_READ_LOWPAN_CREDENTIAL = "android.permission.READ_LOWPAN_CREDENTIAL";
//////////////////////////////////////////////////////////////////////////
// Property Key Constants
/** Type: Boolean */
const String KEY_INTERFACE_ENABLED = "android.net.lowpan.property.INTERFACE_ENABLED";
/** Type: Boolean */
const String KEY_INTERFACE_UP = "android.net.lowpan.property.INTERFACE_UP";
/** Type: Boolean */
const String KEY_INTERFACE_COMMISSIONED = "android.net.lowpan.property.INTERFACE_COMMISSIONED";
/** Type: Boolean */
const String KEY_INTERFACE_CONNECTED = "android.net.lowpan.property.INTERFACE_CONNECTED";
/** Type: String */
const String KEY_INTERFACE_STATE = "android.net.lowpan.property.INTERFACE_STATE";
/** Type: String */
const String KEY_NETWORK_NAME = "android.net.lowpan.property.NETWORK_NAME";
/** Type: Integer */
const String KEY_NETWORK_TYPE = "android.net.lowpan.property.NETWORK_TYPE";
/** Type: Integer */
const String KEY_NETWORK_PANID = "android.net.lowpan.property.NETWORK_PANID";
/** Type: byte[] */
const String KEY_NETWORK_XPANID = "android.net.lowpan.property.NETWORK_XPANID";
/** Type: String */
const String KEY_NETWORK_ROLE = "android.net.lowpan.property.NETWORK_ROLE";
/** Type: byte[] */
const String KEY_NETWORK_MASTER_KEY = "android.net.lowpan.property.NETWORK_MASTER_KEY";
/** Type: Integer */
const String KEY_NETWORK_MASTER_KEY_INDEX
= "android.net.lowpan.property.NETWORK_MASTER_KEY_INDEX";
/** Type: int[] */
const String KEY_SUPPORTED_CHANNELS = "android.net.lowpan.property.SUPPORTED_CHANNELS";
/** Type: Integer */
const String KEY_CHANNEL = "android.net.lowpan.property.CHANNEL";
/** Type: int[] */
/**
* Channel mask key.
* Used for setting a channel mask when starting a scan.
* Type: int[]
* */
const String KEY_CHANNEL_MASK = "android.net.lowpan.property.CHANNEL_MASK";
/** Type: Integer */
/**
* Max Transmit Power Key.
* Used for setting the maximum transmit power when starting a network scan.
* Type: Integer
* */
const String KEY_MAX_TX_POWER = "android.net.lowpan.property.MAX_TX_POWER";
/** Type: Integer */
const String KEY_RSSI = "android.net.lowpan.property.RSSI";
/** Type: Integer */
const String KEY_LQI = "android.net.lowpan.property.LQI";
/** Type: byte[] */
const String KEY_BEACON_ADDRESS = "android.net.lowpan.property.BEACON_ORIGIN_ADDRESS";
/** Type: Boolean */
const String KEY_BEACON_CAN_ASSIST = "android.net.lowpan.property.BEACON_CAN_ASSIST";
/** Type: String */
const String DRIVER_VERSION = "android.net.lowpan.property.DRIVER_VERSION";
/** Type: String */
const String NCP_VERSION = "android.net.lowpan.property.NCP_VERSION";
/** Type: byte[]
* @hide */
const String KEY_EXTENDED_ADDRESS = "android.net.lowpan.property.EXTENDED_ADDRESS";
/** Type: byte[]
* @hide */
const String KEY_MAC_ADDRESS = "android.net.lowpan.property.MAC_ADDRESS";
//////////////////////////////////////////////////////////////////////////
// Interface States
const String STATE_OFFLINE = "offline";
@@ -121,58 +57,87 @@ interface ILowpanInterface {
const String STATE_ATTACHED = "attached";
const String STATE_FAULT = "fault";
//////////////////////////////////////////////////////////////////////////
// Device Roles
const String ROLE_END_DEVICE = "end-device";
const String ROLE_ROUTER = "router";
const String ROLE_SLEEPY_END_DEVICE = "sleepy-end-device";
const String ROLE_SLEEPY_ROUTER = "sleepy-router";
const String ROLE_UNKNOWN = "unknown";
const String ROLE_LEADER = "leader";
const String ROLE_COORDINATOR = "coordinator";
const String ROLE_DETACHED = "detached";
const String NETWORK_TYPE_UNKNOWN = "unknown";
/**
* Network type for Thread 1.x networks.
*
* @see android.net.lowpan.LowpanIdentity#getType
* @see #getLowpanIdentity
*/
const String NETWORK_TYPE_THREAD_V1 = "org.threadgroup.thread.v1";
//////////////////////////////////////////////////////////////////////////
// Service-Specific Error Code Constants
const int ERROR_UNSPECIFIED = 1;
const int ERROR_INVALID_ARGUMENT = 2;
const int ERROR_DISABLED = 3;
const int ERROR_WRONG_STATE = 4;
const int ERROR_INVALID_TYPE = 5;
const int ERROR_INVALID_VALUE = 6;
const int ERROR_TIMEOUT = 7;
const int ERROR_IO_FAILURE = 8;
const int ERROR_BUSY = 9;
const int ERROR_ALREADY = 10;
const int ERROR_CANCELED = 11;
const int ERROR_CREDENTIAL_NEEDED = 12;
const int ERROR_FEATURE_NOT_SUPPORTED = 14;
const int ERROR_PROPERTY_NOT_FOUND = 16;
const int ERROR_JOIN_FAILED_UNKNOWN = 18;
const int ERROR_JOIN_FAILED_AT_SCAN = 19;
const int ERROR_JOIN_FAILED_AT_AUTH = 20;
const int ERROR_FORM_FAILED_AT_SCAN = 21;
const int ERROR_NCP_PROBLEM = 27;
const int ERROR_PERMISSION_DENIED = 28;
const int ERROR_TIMEOUT = 5;
const int ERROR_IO_FAILURE = 6;
const int ERROR_NCP_PROBLEM = 7;
const int ERROR_BUSY = 8;
const int ERROR_ALREADY = 9;
const int ERROR_CANCELED = 10;
const int ERROR_FEATURE_NOT_SUPPORTED = 11;
const int ERROR_JOIN_FAILED_UNKNOWN = 12;
const int ERROR_JOIN_FAILED_AT_SCAN = 13;
const int ERROR_JOIN_FAILED_AT_AUTH = 14;
const int ERROR_FORM_FAILED_AT_SCAN = 15;
//////////////////////////////////////////////////////////////////////////
// Methods
@utf8InCpp String getName();
void join(in Map parameters);
void form(in Map parameters);
@utf8InCpp String getNcpVersion();
@utf8InCpp String getDriverVersion();
LowpanChannelInfo[] getSupportedChannels();
@utf8InCpp String[] getSupportedNetworkTypes();
byte[] getMacAddress();
boolean isEnabled();
void setEnabled(boolean enabled);
boolean isUp();
boolean isCommissioned();
boolean isConnected();
@utf8InCpp String getState();
@utf8InCpp String getRole();
@utf8InCpp String getPartitionId();
byte[] getExtendedAddress();
LowpanIdentity getLowpanIdentity();
LowpanCredential getLowpanCredential();
@utf8InCpp String[] getLinkAddresses();
IpPrefix[] getLinkNetworks();
void join(in LowpanProvision provision);
void form(in LowpanProvision provision);
void attach(in LowpanProvision provision);
void leave();
void reset();
void startCommissioningSession(in LowpanBeaconInfo beaconInfo);
void closeCommissioningSession();
oneway void sendToCommissioner(in byte[] packet);
void beginLowPower();
void pollForData();
oneway void pollForData();
oneway void onHostWake();
@utf8InCpp String[] getPropertyKeys();
Map getProperties(in @utf8InCpp String[] keys);
void setProperties(in Map properties);
void addListener(ILowpanInterfaceListener listener);
oneway void removeListener(ILowpanInterfaceListener listener);
@@ -182,14 +147,9 @@ interface ILowpanInterface {
void startEnergyScan(in Map properties, ILowpanEnergyScanCallback listener);
oneway void stopEnergyScan();
String[] copyLinkAddresses();
IpPrefix[] copyLinkNetworks();
void addOnMeshPrefix(in IpPrefix prefix, int flags);
oneway void removeOnMeshPrefix(in IpPrefix prefix);
void addExternalRoute(in IpPrefix prefix, int flags);
oneway void removeExternalRoute(in IpPrefix prefix);
@utf8InCpp String getPropertyAsString(@utf8InCpp String key);
}

View File

@@ -17,14 +17,29 @@
package android.net.lowpan;
import android.net.IpPrefix;
import android.net.lowpan.LowpanIdentity;
/** {@hide} */
interface ILowpanInterfaceListener {
oneway void onPropertiesChanged(in Map properties);
oneway void onEnabledChanged(boolean value);
oneway void onLinkNetworkAdded(in IpPrefix prefix);
oneway void onLinkNetworkRemoved(in IpPrefix prefix);
oneway void onConnectedChanged(boolean value);
oneway void onLinkAddressAdded(in String address);
oneway void onLinkAddressRemoved(in String address);
oneway void onUpChanged(boolean value);
oneway void onRoleChanged(@utf8InCpp String value);
oneway void onStateChanged(@utf8InCpp String value);
oneway void onLowpanIdentityChanged(in LowpanIdentity value);
oneway void onLinkNetworkAdded(in IpPrefix value);
oneway void onLinkNetworkRemoved(in IpPrefix value);
oneway void onLinkAddressAdded(@utf8InCpp String value);
oneway void onLinkAddressRemoved(@utf8InCpp String value);
oneway void onReceiveFromCommissioner(in byte[] packet);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 The Android Open Source Project
* Copyright (C) 2017 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.
@@ -16,8 +16,10 @@
package android.net.lowpan;
import android.net.lowpan.LowpanBeaconInfo;
/** {@hide} */
interface ILowpanNetScanCallback {
oneway void onNetScanBeacon(in Map parameters);
oneway void onNetScanBeacon(in LowpanBeaconInfo beacon);
oneway void onNetScanFinished();
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2017 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.net.lowpan;
/**
* Exception indicating this operation requires the interface to be enabled.
*
* @see LowpanInterface
* @hide
*/
// @SystemApi
public class InterfaceDisabledException extends LowpanException {
public InterfaceDisabledException() {}
public InterfaceDisabledException(String message) {
super(message);
}
public InterfaceDisabledException(String message, Throwable cause) {
super(message, cause);
}
protected InterfaceDisabledException(Exception cause) {
super(cause);
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2017 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.net.lowpan;
/**
* Exception indicating the join operation was unable to find the given network.
*
* @see LowpanInterface
* @hide
*/
// @SystemApi
public class JoinFailedAtAuthException extends JoinFailedException {
public JoinFailedAtAuthException() {}
public JoinFailedAtAuthException(String message) {
super(message);
}
public JoinFailedAtAuthException(String message, Throwable cause) {
super(message, cause);
}
public JoinFailedAtAuthException(Exception cause) {
super(cause);
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2017 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.net.lowpan;
/**
* Exception indicating the join operation was unable to find the given network.
*
* @see LowpanInterface
* @hide
*/
// @SystemApi
public class JoinFailedAtScanException extends JoinFailedException {
public JoinFailedAtScanException() {}
public JoinFailedAtScanException(String message) {
super(message);
}
public JoinFailedAtScanException(String message, Throwable cause) {
super(message, cause);
}
public JoinFailedAtScanException(Exception cause) {
super(cause);
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2017 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.net.lowpan;
/**
* Exception indicating the join operation has failed.
*
* @see LowpanInterface
* @hide
*/
// @SystemApi
public class JoinFailedException extends LowpanException {
public JoinFailedException() {}
public JoinFailedException(String message) {
super(message);
}
public JoinFailedException(String message, Throwable cause) {
super(message, cause);
}
protected JoinFailedException(Exception cause) {
super(cause);
}
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (C) 2017 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.net.lowpan;
parcelable LowpanBeaconInfo cpp_header "android/net/lowpan/LowpanBeaconInfo.h";

View File

@@ -16,9 +16,12 @@
package android.net.lowpan;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.HexDump;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.TreeSet;
/**
@@ -27,70 +30,93 @@ import java.util.TreeSet;
* @hide
*/
// @SystemApi
public class LowpanBeaconInfo extends LowpanIdentity {
public class LowpanBeaconInfo implements Parcelable {
public static final int UNKNOWN_RSSI = Integer.MAX_VALUE;
public static final int UNKNOWN_LQI = 0;
private int mRssi = UNKNOWN;
private int mLqi = UNKNOWN;
private LowpanIdentity mIdentity;
private int mRssi = UNKNOWN_RSSI;
private int mLqi = UNKNOWN_LQI;
private byte[] mBeaconAddress = null;
private final TreeSet<Integer> mFlags = new TreeSet<>();
public static final int FLAG_CAN_ASSIST = 1;
static class Builder extends LowpanIdentity.Builder {
private final LowpanBeaconInfo identity = new LowpanBeaconInfo();
/** @hide */
public static class Builder {
final LowpanIdentity.Builder mIdentityBuilder = new LowpanIdentity.Builder();
final LowpanBeaconInfo mBeaconInfo = new LowpanBeaconInfo();
public Builder setLowpanIdentity(LowpanIdentity x) {
mIdentityBuilder.setLowpanIdentity(x);
return this;
}
public Builder setName(String x) {
mIdentityBuilder.setName(x);
return this;
}
public Builder setXpanid(byte x[]) {
mIdentityBuilder.setXpanid(x);
return this;
}
public Builder setPanid(int x) {
mIdentityBuilder.setPanid(x);
return this;
}
public Builder setChannel(int x) {
mIdentityBuilder.setChannel(x);
return this;
}
public Builder setType(String x) {
mIdentityBuilder.setType(x);
return this;
}
public Builder setRssi(int x) {
identity.mRssi = x;
mBeaconInfo.mRssi = x;
return this;
}
public Builder setLqi(int x) {
identity.mLqi = x;
mBeaconInfo.mLqi = x;
return this;
}
public Builder setBeaconAddress(byte x[]) {
identity.mBeaconAddress = x.clone();
mBeaconInfo.mBeaconAddress = (x != null ? x.clone() : null);
return this;
}
public Builder setFlag(int x) {
identity.mFlags.add(x);
mBeaconInfo.mFlags.add(x);
return this;
}
public Builder setFlags(Collection<Integer> x) {
identity.mFlags.addAll(x);
return this;
}
/** @hide */
Builder updateFromMap(Map map) {
if (map.containsKey(LowpanProperties.KEY_RSSI.getName())) {
setRssi(LowpanProperties.KEY_RSSI.getFromMap(map));
}
if (map.containsKey(LowpanProperties.KEY_LQI.getName())) {
setLqi(LowpanProperties.KEY_LQI.getFromMap(map));
}
if (map.containsKey(LowpanProperties.KEY_BEACON_ADDRESS.getName())) {
setBeaconAddress(LowpanProperties.KEY_BEACON_ADDRESS.getFromMap(map));
}
identity.mFlags.clear();
if (map.containsKey(LowpanProperties.KEY_BEACON_CAN_ASSIST.getName())
&& LowpanProperties.KEY_BEACON_CAN_ASSIST.getFromMap(map).booleanValue()) {
setFlag(FLAG_CAN_ASSIST);
}
super.updateFromMap(map);
mBeaconInfo.mFlags.addAll(x);
return this;
}
public LowpanBeaconInfo build() {
return identity;
mBeaconInfo.mIdentity = mIdentityBuilder.build();
if (mBeaconInfo.mBeaconAddress == null) {
mBeaconInfo.mBeaconAddress = new byte[0];
}
return mBeaconInfo;
}
}
private LowpanBeaconInfo() {}
public LowpanIdentity getLowpanIdentity() {
return mIdentity;
}
public int getRssi() {
return mRssi;
}
@@ -111,27 +137,22 @@ public class LowpanBeaconInfo extends LowpanIdentity {
return mFlags.contains(flag);
}
@Override
void addToMap(Map<String, Object> parameters) {
super.addToMap(parameters);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(super.toString());
sb.append(mIdentity.toString());
if (mRssi != UNKNOWN) {
sb.append(", RSSI: ").append(mRssi);
if (mRssi != UNKNOWN_RSSI) {
sb.append(", RSSI:").append(mRssi).append("dBm");
}
if (mLqi != UNKNOWN) {
sb.append(", LQI: ").append(mLqi);
if (mLqi != UNKNOWN_LQI) {
sb.append(", LQI:").append(mLqi);
}
if (mBeaconAddress != null) {
sb.append(", BeaconAddress: ").append(HexDump.toHexString(mBeaconAddress));
if (mBeaconAddress.length > 0) {
sb.append(", BeaconAddress:").append(HexDump.toHexString(mBeaconAddress));
}
for (Integer flag : mFlags) {
@@ -147,4 +168,67 @@ public class LowpanBeaconInfo extends LowpanIdentity {
return sb.toString();
}
@Override
public int hashCode() {
return Objects.hash(mIdentity, mRssi, mLqi, Arrays.hashCode(mBeaconAddress), mFlags);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LowpanBeaconInfo)) {
return false;
}
LowpanBeaconInfo rhs = (LowpanBeaconInfo) obj;
return mIdentity.equals(rhs.mIdentity)
&& Arrays.equals(mBeaconAddress, rhs.mBeaconAddress)
&& mRssi == rhs.mRssi
&& mLqi == rhs.mLqi
&& mFlags.equals(rhs.mFlags);
}
/** Implement the Parcelable interface. */
@Override
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface. */
@Override
public void writeToParcel(Parcel dest, int flags) {
mIdentity.writeToParcel(dest, flags);
dest.writeInt(mRssi);
dest.writeInt(mLqi);
dest.writeByteArray(mBeaconAddress);
dest.writeInt(mFlags.size());
for (Integer val : mFlags) {
dest.writeInt(val);
}
}
/** Implement the Parcelable interface. */
public static final Creator<LowpanBeaconInfo> CREATOR =
new Creator<LowpanBeaconInfo>() {
public LowpanBeaconInfo createFromParcel(Parcel in) {
Builder builder = new Builder();
builder.setLowpanIdentity(LowpanIdentity.CREATOR.createFromParcel(in));
builder.setRssi(in.readInt());
builder.setLqi(in.readInt());
builder.setBeaconAddress(in.createByteArray());
for (int i = in.readInt(); i > 0; i--) {
builder.setFlag(in.readInt());
}
return builder.build();
}
public LowpanBeaconInfo[] newArray(int size) {
return new LowpanBeaconInfo[size];
}
};
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (C) 2017 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.net.lowpan;
parcelable LowpanChannelInfo cpp_header "android/net/lowpan/LowpanChannelInfo.h";

View File

@@ -16,22 +16,66 @@
package android.net.lowpan;
/** Provides detailed information about a given channel. */
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/**
* Provides detailed information about a given channel.
*
* @hide
*/
// @SystemApi
public class LowpanChannelInfo {
public class LowpanChannelInfo implements Parcelable {
public static final int UNKNOWN_POWER = Integer.MAX_VALUE;
public static final float UNKNOWN_FREQUENCY = 0.0f;
public static final float UNKNOWN_BANDWIDTH = 0.0f;
// Instance Variables
private String mName = null;
private int mIndex = 0;
private boolean mIsMaskedByRegulatoryDomain = false;
private float mSpectrumCenterFrequency = 0.0f;
private float mSpectrumBandwidth = 0.0f;
private String mName = null;
private float mSpectrumCenterFrequency = UNKNOWN_FREQUENCY;
private float mSpectrumBandwidth = UNKNOWN_BANDWIDTH;
private int mMaxTransmitPower = UNKNOWN_POWER;
private boolean mIsMaskedByRegulatoryDomain = false;
// Public Getters and Setters
/** @hide */
public static LowpanChannelInfo getChannelInfoForIeee802154Page0(int index) {
LowpanChannelInfo info = new LowpanChannelInfo();
if (index < 0) {
info = null;
} else if (index == 0) {
info.mSpectrumCenterFrequency = 868300000.0f;
info.mSpectrumBandwidth = 600000.0f;
} else if (index < 11) {
info.mSpectrumCenterFrequency = 906000000.0f - (2000000.0f * 1) + 2000000.0f * (index);
info.mSpectrumBandwidth = 0; // Unknown
} else if (index < 26) {
info.mSpectrumCenterFrequency =
2405000000.0f - (5000000.0f * 11) + 5000000.0f * (index);
info.mSpectrumBandwidth = 2000000.0f;
} else {
info = null;
}
info.mName = Integer.toString(index);
return info;
}
private LowpanChannelInfo() {}
private LowpanChannelInfo(int index, String name, float cf, float bw) {
mIndex = index;
mName = name;
mSpectrumCenterFrequency = cf;
mSpectrumBandwidth = bw;
}
public String getName() {
return mName;
@@ -63,22 +107,110 @@ public class LowpanChannelInfo {
sb.append("Channel ").append(mIndex);
if (mName != null) {
if (mName != null && !mName.equals(Integer.toString(mIndex))) {
sb.append(" (").append(mName).append(")");
}
if (mSpectrumCenterFrequency > 0.0f) {
sb.append(", SpectrumCenterFrequency: ").append(mSpectrumCenterFrequency).append("Hz");
if (mSpectrumCenterFrequency > 1000000000.0f) {
sb.append(", SpectrumCenterFrequency: ")
.append(mSpectrumCenterFrequency / 1000000000.0f)
.append("GHz");
} else if (mSpectrumCenterFrequency > 1000000.0f) {
sb.append(", SpectrumCenterFrequency: ")
.append(mSpectrumCenterFrequency / 1000000.0f)
.append("MHz");
} else {
sb.append(", SpectrumCenterFrequency: ")
.append(mSpectrumCenterFrequency / 1000.0f)
.append("kHz");
}
}
if (mSpectrumBandwidth > 0.0f) {
sb.append(", SpectrumBandwidth: ").append(mSpectrumBandwidth).append("Hz");
if (mSpectrumBandwidth > 1000000000.0f) {
sb.append(", SpectrumBandwidth: ")
.append(mSpectrumBandwidth / 1000000000.0f)
.append("GHz");
} else if (mSpectrumBandwidth > 1000000.0f) {
sb.append(", SpectrumBandwidth: ")
.append(mSpectrumBandwidth / 1000000.0f)
.append("MHz");
} else {
sb.append(", SpectrumBandwidth: ")
.append(mSpectrumBandwidth / 1000.0f)
.append("kHz");
}
}
if (mMaxTransmitPower != UNKNOWN_POWER) {
sb.append(", MaxTransmitPower: ").append(mMaxTransmitPower);
sb.append(", MaxTransmitPower: ").append(mMaxTransmitPower).append("dBm");
}
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LowpanChannelInfo)) {
return false;
}
LowpanChannelInfo rhs = (LowpanChannelInfo) obj;
return Objects.equals(mName, rhs.mName)
&& mIndex == rhs.mIndex
&& mIsMaskedByRegulatoryDomain == rhs.mIsMaskedByRegulatoryDomain
&& mSpectrumCenterFrequency == rhs.mSpectrumCenterFrequency
&& mSpectrumBandwidth == rhs.mSpectrumBandwidth
&& mMaxTransmitPower == rhs.mMaxTransmitPower;
}
@Override
public int hashCode() {
return Objects.hash(
mName,
mIndex,
mIsMaskedByRegulatoryDomain,
mSpectrumCenterFrequency,
mSpectrumBandwidth,
mMaxTransmitPower);
}
/** Implement the Parcelable interface. */
@Override
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface. */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mIndex);
dest.writeString(mName);
dest.writeFloat(mSpectrumCenterFrequency);
dest.writeFloat(mSpectrumBandwidth);
dest.writeInt(mMaxTransmitPower);
dest.writeBoolean(mIsMaskedByRegulatoryDomain);
}
/** Implement the Parcelable interface. */
public static final Creator<LowpanChannelInfo> CREATOR =
new Creator<LowpanChannelInfo>() {
public LowpanChannelInfo createFromParcel(Parcel in) {
LowpanChannelInfo info = new LowpanChannelInfo();
info.mIndex = in.readInt();
info.mName = in.readString();
info.mSpectrumCenterFrequency = in.readFloat();
info.mSpectrumBandwidth = in.readFloat();
info.mMaxTransmitPower = in.readInt();
info.mIsMaskedByRegulatoryDomain = in.readBoolean();
return info;
}
public LowpanChannelInfo[] newArray(int size) {
return new LowpanChannelInfo[size];
}
};
}

View File

@@ -18,9 +18,11 @@ package android.net.lowpan;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.Network;
import android.net.IpPrefix;
import android.os.DeadObjectException;
import android.os.Handler;
import java.net.InetSocketAddress;
import android.os.Looper;
import android.os.RemoteException;
/**
* Commissioning Session.
@@ -31,8 +33,15 @@ import java.net.InetSocketAddress;
* @hide
*/
// @SystemApi
public abstract class LowpanCommissioningSession {
public LowpanCommissioningSession() {}
public class LowpanCommissioningSession {
private final ILowpanInterface mBinder;
private final LowpanBeaconInfo mBeaconInfo;
private final ILowpanInterfaceListener mInternalCallback = new InternalCallback();
private final Looper mLooper;
private Handler mHandler;
private Callback mCallback = null;
private volatile boolean mIsClosed = false;
/**
* Callback base class for {@link LowpanCommissioningSession}
@@ -40,34 +49,175 @@ public abstract class LowpanCommissioningSession {
* @hide
*/
// @SystemApi
public static abstract class Callback {
public abstract static class Callback {
public void onReceiveFromCommissioner(@NonNull byte[] packet) {};
public void onClosed() {};
}
private class InternalCallback extends ILowpanInterfaceListener.Stub {
@Override
public void onStateChanged(String value) {
if (!mIsClosed) {
switch (value) {
case ILowpanInterface.STATE_OFFLINE:
case ILowpanInterface.STATE_FAULT:
synchronized (LowpanCommissioningSession.this) {
lockedCleanup();
}
}
}
}
@Override
public void onReceiveFromCommissioner(byte[] packet) {
mHandler.post(
() -> {
synchronized (LowpanCommissioningSession.this) {
if (!mIsClosed && (mCallback != null)) {
mCallback.onReceiveFromCommissioner(packet);
}
}
});
}
// We ignore all other callbacks.
@Override
public void onEnabledChanged(boolean value) {}
@Override
public void onConnectedChanged(boolean value) {}
@Override
public void onUpChanged(boolean value) {}
@Override
public void onRoleChanged(String value) {}
@Override
public void onLowpanIdentityChanged(LowpanIdentity value) {}
@Override
public void onLinkNetworkAdded(IpPrefix value) {}
@Override
public void onLinkNetworkRemoved(IpPrefix value) {}
@Override
public void onLinkAddressAdded(String value) {}
@Override
public void onLinkAddressRemoved(String value) {}
}
LowpanCommissioningSession(
ILowpanInterface binder, LowpanBeaconInfo beaconInfo, Looper looper) {
mBinder = binder;
mBeaconInfo = beaconInfo;
mLooper = looper;
if (mLooper != null) {
mHandler = new Handler(mLooper);
} else {
mHandler = new Handler();
}
try {
mBinder.addListener(mInternalCallback);
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
}
private void lockedCleanup() {
// Note: this method is only called from synchronized contexts.
if (!mIsClosed) {
try {
mBinder.removeListener(mInternalCallback);
} catch (DeadObjectException x) {
/* We don't care if we receive a DOE at this point.
* DOE is as good as success as far as we are concerned.
*/
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
if (mCallback != null) {
mHandler.post(() -> mCallback.onClosed());
}
}
mCallback = null;
mIsClosed = true;
}
/** TODO: doc */
@NonNull
public abstract LowpanBeaconInfo getBeaconInfo();
public LowpanBeaconInfo getBeaconInfo() {
return mBeaconInfo;
}
/** TODO: doc */
public abstract void sendToCommissioner(@NonNull byte[] packet);
public void sendToCommissioner(@NonNull byte[] packet) {
if (!mIsClosed) {
try {
mBinder.sendToCommissioner(packet);
} catch (DeadObjectException x) {
/* This method is a best-effort delivery.
* We don't care if we receive a DOE at this point.
*/
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
}
}
/** TODO: doc */
public abstract void setCallback(@Nullable Callback cb, @Nullable Handler handler);
public synchronized void setCallback(@Nullable Callback cb, @Nullable Handler handler) {
if (!mIsClosed) {
/* This class can be created with or without a default looper.
* Also, this method can be called with or without a specific
* handler. If a handler is specified, it is to always be used.
* Otherwise, if there was a Looper specified when this object
* was created, we create a new handle based on that looper.
* Otherwise we just create a default handler object. Since we
* don't really know how the previous handler was created, we
* end up always replacing it here. This isn't a huge problem
* because this method should be called infrequently.
*/
if (handler != null) {
mHandler = handler;
} else if (mLooper != null) {
mHandler = new Handler(mLooper);
} else {
mHandler = new Handler();
}
mCallback = cb;
}
}
/** TODO: doc */
public abstract void close();
public synchronized void close() {
if (!mIsClosed) {
try {
mBinder.closeCommissioningSession();
/**
* This method is largely for Nest Weave, as an alternative to {@link #sendToCommissioner()}
* and @{link Callback#onReceiveFromCommissioner()}.
*
* <p>When used with the Network instance obtained from getNetwork(), the caller can use the
* given InetSocketAddress to communicate with the commissioner using a UDP (or, under certain
* circumstances, TCP) socket.
*/
public abstract @Nullable InetSocketAddress getInetSocketAddress();
lockedCleanup();
public abstract @Nullable Network getNetwork();
} catch (DeadObjectException x) {
/* We don't care if we receive a DOE at this point.
* DOE is as good as success as far as we are concerned.
*/
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
}
}
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (C) 2017 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.net.lowpan;
parcelable LowpanCredential cpp_header "android/net/lowpan/LowpanCredential.h";

View File

@@ -16,7 +16,11 @@
package android.net.lowpan;
import java.util.Map;
import android.os.Parcel;
import android.os.Parcelable;
import com.android.internal.util.HexDump;
import java.util.Arrays;
import java.util.Objects;
/**
* Describes a credential for a LoWPAN network.
@@ -24,7 +28,7 @@ import java.util.Map;
* @hide
*/
// @SystemApi
public class LowpanCredential {
public class LowpanCredential implements Parcelable {
public static final int UNSPECIFIED_KEY_INDEX = 0;
@@ -49,18 +53,18 @@ public class LowpanCredential {
return new LowpanCredential(masterKey, keyIndex);
}
public void setMasterKey(byte[] masterKey) {
void setMasterKey(byte[] masterKey) {
if (masterKey != null) {
masterKey = masterKey.clone();
}
mMasterKey = masterKey;
}
public void setMasterKeyIndex(int keyIndex) {
void setMasterKeyIndex(int keyIndex) {
mMasterKeyIndex = keyIndex;
}
public void setMasterKey(byte[] masterKey, int keyIndex) {
void setMasterKey(byte[] masterKey, int keyIndex) {
setMasterKey(masterKey);
setMasterKeyIndex(keyIndex);
}
@@ -80,12 +84,89 @@ public class LowpanCredential {
return mMasterKey != null;
}
void addToMap(Map<String, Object> parameters) throws LowpanException {
public String toSensitiveString() {
StringBuffer sb = new StringBuffer();
sb.append("<LowpanCredential");
if (isMasterKey()) {
LowpanProperties.KEY_NETWORK_MASTER_KEY.putInMap(parameters, getMasterKey());
LowpanProperties.KEY_NETWORK_MASTER_KEY_INDEX.putInMap(parameters, getMasterKeyIndex());
sb.append(" MasterKey:").append(HexDump.toHexString(mMasterKey));
if (mMasterKeyIndex != UNSPECIFIED_KEY_INDEX) {
sb.append(", Index:").append(mMasterKeyIndex);
}
} else {
throw new LowpanException("Unsupported Network Credential");
sb.append(" empty");
}
sb.append(">");
return sb.toString();
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("<LowpanCredential");
if (isMasterKey()) {
// We don't print out the contents of the key here,
// we only do that in toSensitiveString.
sb.append(" MasterKey");
if (mMasterKeyIndex != UNSPECIFIED_KEY_INDEX) {
sb.append(", Index:").append(mMasterKeyIndex);
}
} else {
sb.append(" empty");
}
sb.append(">");
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LowpanCredential)) {
return false;
}
LowpanCredential rhs = (LowpanCredential) obj;
return Arrays.equals(mMasterKey, rhs.mMasterKey) && mMasterKeyIndex == rhs.mMasterKeyIndex;
}
@Override
public int hashCode() {
return Objects.hash(Arrays.hashCode(mMasterKey), mMasterKeyIndex);
}
/** Implement the Parcelable interface. */
@Override
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface. */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByteArray(mMasterKey);
dest.writeInt(mMasterKeyIndex);
}
/** Implement the Parcelable interface. */
public static final Creator<LowpanCredential> CREATOR =
new Creator<LowpanCredential>() {
public LowpanCredential createFromParcel(Parcel in) {
LowpanCredential credential = new LowpanCredential();
credential.mMasterKey = in.createByteArray();
credential.mMasterKeyIndex = in.readInt();
return credential;
}
public LowpanCredential[] newArray(int size) {
return new LowpanCredential[size];
}
};
}

View File

@@ -28,7 +28,7 @@ public class LowpanEnergyScanResult {
private int mChannel = UNKNOWN;
private int mMaxRssi = UNKNOWN;
public LowpanEnergyScanResult() {}
LowpanEnergyScanResult() {}
public int getChannel() {
return mChannel;
@@ -38,11 +38,11 @@ public class LowpanEnergyScanResult {
return mMaxRssi;
}
public void setChannel(int x) {
void setChannel(int x) {
mChannel = x;
}
public void setMaxRssi(int x) {
void setMaxRssi(int x) {
mMaxRssi = x;
}

View File

@@ -28,245 +28,65 @@ import android.util.AndroidException;
*/
// @SystemApi
public class LowpanException extends AndroidException {
// Make the eclipse warning about serializable exceptions go away
private static final long serialVersionUID = 0x31863cbe562b0e11l; // randomly generated
public static final int LOWPAN_ERROR = 1;
public static final int LOWPAN_CREDENTIAL_NEEDED = 2;
public static final int LOWPAN_DEAD = 3;
public static final int LOWPAN_DISABLED = 4;
public static final int LOWPAN_WRONG_STATE = 5;
public static final int LOWPAN_BUSY = 7;
public static final int LOWPAN_NCP_PROBLEM = 8;
public static final int LOWPAN_ALREADY = 9;
public static final int LOWPAN_CANCELED = 10;
public static final int LOWPAN_FEATURE_NOT_SUPPORTED = 12;
public static final int LOWPAN_PROPERTY_NOT_FOUND = 13;
public static final int LOWPAN_JOIN_FAILED_UNKNOWN = 14;
public static final int LOWPAN_JOIN_FAILED_AT_SCAN = 15;
public static final int LOWPAN_JOIN_FAILED_AT_AUTH = 16;
public static final int LOWPAN_FORM_FAILED_AT_SCAN = 17;
public static LowpanException rethrowAsLowpanException(ServiceSpecificException e)
throws LowpanException {
int reason;
switch (e.errorCode) {
case ILowpanInterface.ERROR_INVALID_ARGUMENT:
case ILowpanInterface.ERROR_INVALID_TYPE:
case ILowpanInterface.ERROR_INVALID_VALUE:
throw new IllegalArgumentException(e.getMessage(), e);
case ILowpanInterface.ERROR_PERMISSION_DENIED:
throw new SecurityException(e.getMessage(), e);
case ILowpanInterface.ERROR_DISABLED:
reason = LowpanException.LOWPAN_DISABLED;
break;
case ILowpanInterface.ERROR_WRONG_STATE:
reason = LowpanException.LOWPAN_WRONG_STATE;
break;
case ILowpanInterface.ERROR_BUSY:
reason = LowpanException.LOWPAN_BUSY;
break;
case ILowpanInterface.ERROR_ALREADY:
reason = LowpanException.LOWPAN_ALREADY;
break;
case ILowpanInterface.ERROR_CANCELED:
reason = LowpanException.LOWPAN_CANCELED;
break;
case ILowpanInterface.ERROR_CREDENTIAL_NEEDED:
reason = LowpanException.LOWPAN_CREDENTIAL_NEEDED;
break;
case ILowpanInterface.ERROR_FEATURE_NOT_SUPPORTED:
reason = LowpanException.LOWPAN_FEATURE_NOT_SUPPORTED;
break;
case ILowpanInterface.ERROR_PROPERTY_NOT_FOUND:
reason = LowpanException.LOWPAN_PROPERTY_NOT_FOUND;
break;
case ILowpanInterface.ERROR_JOIN_FAILED_UNKNOWN:
reason = LowpanException.LOWPAN_JOIN_FAILED_UNKNOWN;
break;
case ILowpanInterface.ERROR_JOIN_FAILED_AT_SCAN:
reason = LowpanException.LOWPAN_JOIN_FAILED_AT_SCAN;
break;
case ILowpanInterface.ERROR_JOIN_FAILED_AT_AUTH:
reason = LowpanException.LOWPAN_JOIN_FAILED_AT_AUTH;
break;
case ILowpanInterface.ERROR_FORM_FAILED_AT_SCAN:
reason = LowpanException.LOWPAN_FORM_FAILED_AT_SCAN;
break;
case ILowpanInterface.ERROR_TIMEOUT:
case ILowpanInterface.ERROR_NCP_PROBLEM:
reason = LowpanException.LOWPAN_NCP_PROBLEM;
break;
case ILowpanInterface.ERROR_UNSPECIFIED:
default:
reason = LOWPAN_ERROR;
break;
}
throw new LowpanException(reason, e.getMessage(), e);
}
private final int mReason;
public final int getReason() {
return mReason;
}
public LowpanException(int problem) {
super(getDefaultMessage(problem));
mReason = problem;
}
public LowpanException() {}
public LowpanException(String message) {
super(getCombinedMessage(LOWPAN_ERROR, message));
mReason = LOWPAN_ERROR;
super(message);
}
public LowpanException(int problem, String message, Throwable cause) {
super(getCombinedMessage(problem, message), cause);
mReason = problem;
public LowpanException(String message, Throwable cause) {
super(message, cause);
}
public LowpanException(int problem, Throwable cause) {
super(getDefaultMessage(problem), cause);
mReason = problem;
public LowpanException(Exception cause) {
super(cause);
}
/** @hide */
public static String getDefaultMessage(int problem) {
String problemString;
/* This method returns LowpanException so that the caller
* can add "throw" before the invocation of this method.
* This might seem superfluous, but it is actually to
* help provide a hint to the java compiler that this
* function will not return.
*/
static LowpanException rethrowFromServiceSpecificException(ServiceSpecificException e)
throws LowpanException {
switch (e.errorCode) {
case ILowpanInterface.ERROR_DISABLED:
throw new InterfaceDisabledException(e);
// TODO: Does this need localization?
case ILowpanInterface.ERROR_WRONG_STATE:
throw new WrongStateException(e);
switch (problem) {
case LOWPAN_DEAD:
problemString = "LoWPAN interface is no longer alive";
break;
case LOWPAN_DISABLED:
problemString = "LoWPAN interface is disabled";
break;
case LOWPAN_WRONG_STATE:
problemString = "LoWPAN interface in wrong state to perfom requested action";
break;
case LOWPAN_BUSY:
problemString =
"LoWPAN interface was unable to perform the requestion action because it was busy";
break;
case LOWPAN_NCP_PROBLEM:
problemString =
"The Network Co-Processor associated with this interface has experienced a problem";
break;
case LOWPAN_ALREADY:
problemString = "The LoWPAN interface is already in the given state";
break;
case LOWPAN_CANCELED:
problemString = "This operation was canceled";
break;
case LOWPAN_CREDENTIAL_NEEDED:
problemString = "Additional credentials are required to complete this operation";
break;
case LOWPAN_FEATURE_NOT_SUPPORTED:
problemString =
"A dependent feature required to perform the given action is not currently supported";
break;
case LOWPAN_PROPERTY_NOT_FOUND:
problemString = "The given property was not found";
break;
case LOWPAN_JOIN_FAILED_UNKNOWN:
problemString = "The join operation failed for an unspecified reason";
break;
case LOWPAN_JOIN_FAILED_AT_SCAN:
problemString =
"The join operation failed because it could not communicate with any peers";
break;
case LOWPAN_JOIN_FAILED_AT_AUTH:
problemString =
"The join operation failed because the credentials were not accepted by any peers";
break;
case LOWPAN_FORM_FAILED_AT_SCAN:
problemString = "Network form failed";
break;
case LOWPAN_ERROR:
case ILowpanInterface.ERROR_CANCELED:
throw new OperationCanceledException(e);
case ILowpanInterface.ERROR_JOIN_FAILED_UNKNOWN:
throw new JoinFailedException(e);
case ILowpanInterface.ERROR_JOIN_FAILED_AT_SCAN:
throw new JoinFailedAtScanException(e);
case ILowpanInterface.ERROR_JOIN_FAILED_AT_AUTH:
throw new JoinFailedAtAuthException(e);
case ILowpanInterface.ERROR_FORM_FAILED_AT_SCAN:
throw new NetworkAlreadyExistsException(e);
case ILowpanInterface.ERROR_FEATURE_NOT_SUPPORTED:
throw new LowpanException(
e.getMessage() != null ? e.getMessage() : "Feature not supported", e);
case ILowpanInterface.ERROR_NCP_PROBLEM:
throw new LowpanRuntimeException(
e.getMessage() != null ? e.getMessage() : "NCP problem", e);
case ILowpanInterface.ERROR_INVALID_ARGUMENT:
throw new LowpanRuntimeException(
e.getMessage() != null ? e.getMessage() : "Invalid argument", e);
case ILowpanInterface.ERROR_UNSPECIFIED:
default:
problemString = "The requested LoWPAN operation failed";
break;
throw new LowpanRuntimeException(e);
}
return problemString;
}
private static String getCombinedMessage(int problem, String message) {
String problemString = getProblemString(problem);
return String.format("%s (%d): %s", problemString, problem, message);
}
private static String getProblemString(int problem) {
String problemString;
switch (problem) {
case LOWPAN_ERROR:
problemString = "LOWPAN_ERROR";
break;
case LOWPAN_DEAD:
problemString = "LOWPAN_DEAD";
break;
case LOWPAN_DISABLED:
problemString = "LOWPAN_DISABLED";
break;
case LOWPAN_WRONG_STATE:
problemString = "LOWPAN_WRONG_STATE";
break;
case LOWPAN_BUSY:
problemString = "LOWPAN_BUSY";
break;
case LOWPAN_NCP_PROBLEM:
problemString = "LOWPAN_NCP_PROBLEM";
break;
case LOWPAN_ALREADY:
problemString = "LOWPAN_ALREADY";
break;
case LOWPAN_CANCELED:
problemString = "LOWPAN_CANCELED";
break;
case LOWPAN_CREDENTIAL_NEEDED:
problemString = "LOWPAN_CREDENTIAL_NEEDED";
break;
case LOWPAN_FEATURE_NOT_SUPPORTED:
problemString = "LOWPAN_FEATURE_NOT_SUPPORTED";
break;
case LOWPAN_PROPERTY_NOT_FOUND:
problemString = "LOWPAN_PROPERTY_NOT_FOUND";
break;
case LOWPAN_JOIN_FAILED_UNKNOWN:
problemString = "LOWPAN_JOIN_FAILED_UNKNOWN";
break;
case LOWPAN_JOIN_FAILED_AT_SCAN:
problemString = "LOWPAN_JOIN_FAILED_AT_SCAN";
break;
case LOWPAN_JOIN_FAILED_AT_AUTH:
problemString = "LOWPAN_JOIN_FAILED_AT_AUTH";
break;
case LOWPAN_FORM_FAILED_AT_SCAN:
problemString = "LOWPAN_FORM_FAILED_AT_SCAN";
break;
default:
problemString = "LOWPAN_ERROR_CODE_" + problem;
break;
}
return problemString;
}
}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (C) 2017 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.net.lowpan;
parcelable LowpanIdentity cpp_header "android/net/lowpan/LowpanIdentity.h";

View File

@@ -16,8 +16,16 @@
package android.net.lowpan;
import android.annotation.NonNull;
import android.icu.text.StringPrep;
import android.icu.text.StringPrepParseException;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import com.android.internal.util.HexDump;
import java.util.Map;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
/**
* Describes an instance of a LoWPAN network.
@@ -25,76 +33,100 @@ import java.util.Map;
* @hide
*/
// @SystemApi
public class LowpanIdentity {
public class LowpanIdentity implements Parcelable {
private static final String TAG = LowpanIdentity.class.getSimpleName();
// Constants
/** @hide */
public static final int TYPE_ZIGBEE = 1;
/** @hide */
public static final int TYPE_ZIGBEE_IP = 2;
/** @hide */
public static final int TYPE_THREAD = 3;
public static final int UNKNOWN = Integer.MAX_VALUE;
public static final int UNSPECIFIED_CHANNEL = -1;
public static final int UNSPECIFIED_PANID = 0xFFFFFFFF;
// Builder
/** @hide */
// @SystemApi
public static class Builder {
private final LowpanIdentity identity = new LowpanIdentity();
private static final StringPrep stringPrep =
StringPrep.getInstance(StringPrep.RFC3920_RESOURCEPREP);
final LowpanIdentity mIdentity = new LowpanIdentity();
private static String escape(@NonNull byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (byte b : bytes) {
if (b >= 32 && b <= 126) {
sb.append((char) b);
} else {
sb.append(String.format("\\0x%02x", b & 0xFF));
}
}
return sb.toString();
}
public Builder setLowpanIdentity(@NonNull LowpanIdentity x) {
Objects.requireNonNull(x);
setRawName(x.getRawName());
setXpanid(x.getXpanid());
setPanid(x.getPanid());
setChannel(x.getChannel());
setType(x.getType());
return this;
}
public Builder setName(@NonNull String name) {
Objects.requireNonNull(name);
try {
mIdentity.mName = stringPrep.prepare(name, StringPrep.DEFAULT);
mIdentity.mRawName = mIdentity.mName.getBytes(StandardCharsets.UTF_8);
mIdentity.mIsNameValid = true;
} catch (StringPrepParseException x) {
Log.w(TAG, x.toString());
setRawName(name.getBytes(StandardCharsets.UTF_8));
}
return this;
}
public Builder setRawName(@NonNull byte[] name) {
Objects.requireNonNull(name);
mIdentity.mRawName = name.clone();
mIdentity.mName = new String(name, StandardCharsets.UTF_8);
try {
String nameCheck = stringPrep.prepare(mIdentity.mName, StringPrep.DEFAULT);
mIdentity.mIsNameValid =
Arrays.equals(nameCheck.getBytes(StandardCharsets.UTF_8), name);
} catch (StringPrepParseException x) {
Log.w(TAG, x.toString());
mIdentity.mIsNameValid = false;
}
// Non-normal names must be rendered differently to avoid confusion.
if (!mIdentity.mIsNameValid) {
mIdentity.mName = "«" + escape(name) + "»";
}
public Builder setName(String x) {
identity.mName = x;
return this;
}
public Builder setXpanid(byte x[]) {
identity.mXpanid = (x != null ? x.clone() : null);
mIdentity.mXpanid = (x != null ? x.clone() : null);
return this;
}
public Builder setPanid(int x) {
identity.mPanid = x;
mIdentity.mPanid = x;
return this;
}
/** @hide */
public Builder setType(int x) {
identity.mType = x;
public Builder setType(@NonNull String x) {
mIdentity.mType = x;
return this;
}
public Builder setChannel(int x) {
identity.mChannel = x;
return this;
}
/** @hide */
Builder updateFromMap(Map map) {
if (map.containsKey(ILowpanInterface.KEY_NETWORK_NAME)) {
setName(LowpanProperties.KEY_NETWORK_NAME.getFromMap(map));
}
if (map.containsKey(ILowpanInterface.KEY_NETWORK_PANID)) {
setPanid(LowpanProperties.KEY_NETWORK_PANID.getFromMap(map));
}
if (map.containsKey(ILowpanInterface.KEY_NETWORK_XPANID)) {
setXpanid(LowpanProperties.KEY_NETWORK_XPANID.getFromMap(map));
}
if (map.containsKey(ILowpanInterface.KEY_CHANNEL)) {
setChannel(LowpanProperties.KEY_CHANNEL.getFromMap(map));
}
if (map.containsKey(ILowpanInterface.KEY_NETWORK_TYPE)) {
setType(LowpanProperties.KEY_NETWORK_TYPE.getFromMap(map));
}
mIdentity.mChannel = x;
return this;
}
public LowpanIdentity build() {
return identity;
return mIdentity;
}
}
@@ -102,28 +134,37 @@ public class LowpanIdentity {
// Instance Variables
private String mName = null;
private byte[] mXpanid = null;
private int mType = UNKNOWN;
private int mPanid = UNKNOWN;
private int mChannel = UNKNOWN;
private String mName = "";
private boolean mIsNameValid = true;
private byte[] mRawName = new byte[0];
private String mType = "";
private byte[] mXpanid = new byte[0];
private int mPanid = UNSPECIFIED_PANID;
private int mChannel = UNSPECIFIED_CHANNEL;
// Public Getters and Setters
// Public Getters
public String getName() {
return mName;
}
public boolean isNameValid() {
return mIsNameValid;
}
public byte[] getRawName() {
return mRawName.clone();
}
public byte[] getXpanid() {
return mXpanid != null ? mXpanid.clone() : null;
return mXpanid.clone();
}
public int getPanid() {
return mPanid;
}
/** @hide */
public int getType() {
public String getType() {
return mType;
}
@@ -131,43 +172,84 @@ public class LowpanIdentity {
return mChannel;
}
static void addToMap(Map<String, Object> parameters, LowpanIdentity networkInfo) {
if (networkInfo.getName() != null) {
LowpanProperties.KEY_NETWORK_NAME.putInMap(parameters, networkInfo.getName());
}
if (networkInfo.getPanid() != LowpanIdentity.UNKNOWN) {
LowpanProperties.KEY_NETWORK_PANID.putInMap(parameters, networkInfo.getPanid());
}
if (networkInfo.getChannel() != LowpanIdentity.UNKNOWN) {
LowpanProperties.KEY_CHANNEL.putInMap(parameters, networkInfo.getChannel());
}
if (networkInfo.getXpanid() != null) {
LowpanProperties.KEY_NETWORK_XPANID.putInMap(parameters, networkInfo.getXpanid());
}
}
void addToMap(Map<String, Object> parameters) {
addToMap(parameters, this);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("Name: ").append(mName == null ? "<none>" : mName);
sb.append("Name:").append(getName());
if (mXpanid != null) {
sb.append(", XPANID: ").append(HexDump.toHexString(mXpanid));
if (mType.length() > 0) {
sb.append(", Type:").append(mType);
}
if (mPanid != UNKNOWN) {
sb.append(", PANID: ").append(String.format("0x%04X", mPanid));
if (mXpanid.length > 0) {
sb.append(", XPANID:").append(HexDump.toHexString(mXpanid));
}
if (mChannel != UNKNOWN) {
sb.append(", Channel: ").append(mChannel);
if (mPanid != UNSPECIFIED_PANID) {
sb.append(", PANID:").append(String.format("0x%04X", mPanid));
}
if (mChannel != UNSPECIFIED_CHANNEL) {
sb.append(", Channel:").append(mChannel);
}
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LowpanIdentity)) {
return false;
}
LowpanIdentity rhs = (LowpanIdentity) obj;
return Arrays.equals(mRawName, rhs.mRawName)
&& Arrays.equals(mXpanid, rhs.mXpanid)
&& mType.equals(rhs.mType)
&& mPanid == rhs.mPanid
&& mChannel == rhs.mChannel;
}
@Override
public int hashCode() {
return Objects.hash(
Arrays.hashCode(mRawName), mType, Arrays.hashCode(mXpanid), mPanid, mChannel);
}
/** Implement the Parcelable interface. */
@Override
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface. */
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByteArray(mRawName);
dest.writeString(mType);
dest.writeByteArray(mXpanid);
dest.writeInt(mPanid);
dest.writeInt(mChannel);
}
/** Implement the Parcelable interface. */
public static final Creator<LowpanIdentity> CREATOR =
new Creator<LowpanIdentity>() {
public LowpanIdentity createFromParcel(Parcel in) {
Builder builder = new Builder();
builder.setRawName(in.createByteArray());
builder.setType(in.readString());
builder.setXpanid(in.createByteArray());
builder.setPanid(in.readInt());
builder.setChannel(in.readInt());
return builder.build();
}
public LowpanIdentity[] newArray(int size) {
return new LowpanIdentity[size];
}
};
}

View File

@@ -28,8 +28,6 @@ import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.util.Log;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Class for managing a specific Low-power Wireless Personal Area Network (LoWPAN) interface.
@@ -41,13 +39,13 @@ public class LowpanInterface {
private static final String TAG = LowpanInterface.class.getSimpleName();
/** Detached role. The interface is not currently attached to a network. */
public static final String ROLE_DETACHED = "detached";
public static final String ROLE_DETACHED = ILowpanInterface.ROLE_DETACHED;
/** End-device role. End devices do not route traffic for other nodes. */
public static final String ROLE_END_DEVICE = "end-device";
public static final String ROLE_END_DEVICE = ILowpanInterface.ROLE_END_DEVICE;
/** Router role. Routers help route traffic around the mesh network. */
public static final String ROLE_ROUTER = "router";
public static final String ROLE_ROUTER = ILowpanInterface.ROLE_ROUTER;
/**
* Sleepy End-Device role.
@@ -57,7 +55,7 @@ public class LowpanInterface {
* extraordinarilly low power consumption, but packet latency can be on the order of dozens of
* seconds(depending on how the node is configured).
*/
public static final String ROLE_SLEEPY_END_DEVICE = "sleepy-end-device";
public static final String ROLE_SLEEPY_END_DEVICE = ILowpanInterface.ROLE_SLEEPY_END_DEVICE;
/**
* Sleepy-router role.
@@ -65,13 +63,13 @@ public class LowpanInterface {
* <p>Routers with this role are nominally asleep, waking up periodically to check in with other
* routers and their children.
*/
public static final String ROLE_SLEEPY_ROUTER = "sleepy-router";
public static final String ROLE_SLEEPY_ROUTER = ILowpanInterface.ROLE_SLEEPY_ROUTER;
/** TODO: doc */
public static final String ROLE_LEADER = "leader";
public static final String ROLE_LEADER = ILowpanInterface.ROLE_LEADER;
/** TODO: doc */
public static final String ROLE_COORDINATOR = "coordinator";
public static final String ROLE_COORDINATOR = ILowpanInterface.ROLE_COORDINATOR;
/**
* Offline state.
@@ -86,7 +84,7 @@ public class LowpanInterface {
* @see #getState()
* @see #STATE_FAULT
*/
public static final String STATE_OFFLINE = "offline";
public static final String STATE_OFFLINE = ILowpanInterface.STATE_OFFLINE;
/**
* Commissioning state.
@@ -98,7 +96,7 @@ public class LowpanInterface {
* @see #getState()
* @hide
*/
public static final String STATE_COMMISSIONING = "commissioning";
public static final String STATE_COMMISSIONING = ILowpanInterface.STATE_COMMISSIONING;
/**
* Attaching state.
@@ -116,7 +114,7 @@ public class LowpanInterface {
* @see #STATE_ATTACHED
* @see #getState()
*/
public static final String STATE_ATTACHING = "attaching";
public static final String STATE_ATTACHING = ILowpanInterface.STATE_ATTACHING;
/**
* Attached state.
@@ -127,7 +125,7 @@ public class LowpanInterface {
* @see #STATE_ATTACHING
* @see #getState()
*/
public static final String STATE_ATTACHED = "attached";
public static final String STATE_ATTACHED = ILowpanInterface.STATE_ATTACHED;
/**
* Fault state.
@@ -141,7 +139,7 @@ public class LowpanInterface {
* @see #getState
* @see #STATE_OFFLINE
*/
public static final String STATE_FAULT = "fault";
public static final String STATE_FAULT = ILowpanInterface.STATE_FAULT;
/**
* Network type for Thread 1.x networks.
@@ -150,23 +148,9 @@ public class LowpanInterface {
* @see #getLowpanIdentity
* @hide
*/
public static final String NETWORK_TYPE_THREAD = "org.threadgroup.thread.v1";
public static final String NETWORK_TYPE_THREAD_V1 = ILowpanInterface.NETWORK_TYPE_THREAD_V1;
/**
* Network type for ZigBeeIP 1.x networks.
*
* @see android.net.lowpan.LowpanIdentity#getType
* @see #getLowpanIdentity
* @hide
*/
public static final String NETWORK_TYPE_ZIGBEE_IP = "org.zigbee.zigbeeip.v1";
private static final String NETWORK_PROPERTY_KEYS[] = {
LowpanProperties.KEY_NETWORK_NAME.getName(),
LowpanProperties.KEY_NETWORK_PANID.getName(),
LowpanProperties.KEY_NETWORK_XPANID.getName(),
LowpanProperties.KEY_CHANNEL.getName()
};
public static final String EMPTY_PARTITION_ID = "";
/**
* Callback base class for LowpanInterface
@@ -187,8 +171,13 @@ public class LowpanInterface {
public void onLowpanIdentityChanged(@NonNull LowpanIdentity value) {}
/** @hide */
public void onPropertiesChanged(@NonNull Map properties) {}
public void onLinkNetworkAdded(IpPrefix prefix) {}
public void onLinkNetworkRemoved(IpPrefix prefix) {}
public void onLinkAddressAdded(LinkAddress address) {}
public void onLinkAddressRemoved(LinkAddress address) {}
}
private final ILowpanInterface mBinder;
@@ -222,74 +211,6 @@ public class LowpanInterface {
return mBinder;
}
// Private Property Helpers
void setProperties(Map properties) throws LowpanException {
try {
mBinder.setProperties(properties);
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
}
}
@NonNull
Map<String, Object> getProperties(String keys[]) throws LowpanException {
try {
return mBinder.getProperties(keys);
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
}
}
/** @hide */
public <T> void setProperty(LowpanProperty<T> key, T value) throws LowpanException {
HashMap<String, T> prop = new HashMap<>();
prop.put(key.getName(), value);
setProperties(prop);
}
/** @hide */
@Nullable
public <T> T getProperty(LowpanProperty<T> key) throws LowpanException {
Map<String, Object> map = getProperties(new String[] {key.getName()});
if (map != null && !map.isEmpty()) {
// We know there is only one value.
return (T) map.values().iterator().next();
}
return null;
}
@Nullable
<T> String getPropertyAsString(LowpanProperty<T> key) throws LowpanException {
try {
return mBinder.getPropertyAsString(key.getName());
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
}
}
int getPropertyAsInt(LowpanProperty<Integer> key) throws LowpanException {
Integer value = getProperty(key);
return (value != null) ? value : 0;
}
boolean getPropertyAsBoolean(LowpanProperty<Boolean> key) throws LowpanException {
Boolean value = getProperty(key);
return (value != null) ? value : false;
}
// Public Actions
/**
@@ -306,15 +227,13 @@ public class LowpanInterface {
*/
public void form(@NonNull LowpanProvision provision) throws LowpanException {
try {
Map<String, Object> parameters = new HashMap();
provision.addToMap(parameters);
mBinder.form(parameters);
mBinder.form(provision);
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
@@ -328,15 +247,13 @@ public class LowpanInterface {
*/
public void join(@NonNull LowpanProvision provision) throws LowpanException {
try {
Map<String, Object> parameters = new HashMap();
provision.addToMap(parameters);
mBinder.join(parameters);
mBinder.join(provision);
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
@@ -348,13 +265,14 @@ public class LowpanInterface {
* <p>This method will block execution until the operation has completed.
*/
public void attach(@NonNull LowpanProvision provision) throws LowpanException {
if (ROLE_DETACHED.equals(getRole())) {
Map<String, Object> parameters = new HashMap();
provision.addToMap(parameters);
setProperties(parameters);
setUp(true);
} else {
throw new LowpanException(LowpanException.LOWPAN_ALREADY);
try {
mBinder.attach(provision);
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
@@ -372,7 +290,7 @@ public class LowpanInterface {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
@@ -382,9 +300,17 @@ public class LowpanInterface {
*/
public @NonNull LowpanCommissioningSession startCommissioningSession(
@NonNull LowpanBeaconInfo beaconInfo) throws LowpanException {
try {
mBinder.startCommissioningSession(beaconInfo);
/* TODO: Implement startCommissioningSession */
throw new LowpanException(LowpanException.LOWPAN_FEATURE_NOT_SUPPORTED);
return new LowpanCommissioningSession(mBinder, beaconInfo, mLooper);
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
/**
@@ -403,7 +329,7 @@ public class LowpanInterface {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
@@ -415,6 +341,9 @@ public class LowpanInterface {
try {
return mBinder.getName();
} catch (DeadObjectException x) {
return "";
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
@@ -428,9 +357,13 @@ public class LowpanInterface {
*/
public boolean isEnabled() {
try {
return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_ENABLED);
} catch (LowpanException x) {
return mBinder.isEnabled();
} catch (DeadObjectException x) {
return false;
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
}
@@ -444,7 +377,15 @@ public class LowpanInterface {
* @hide
*/
public void setEnabled(boolean enabled) throws LowpanException {
setProperty(LowpanProperties.KEY_INTERFACE_ENABLED, enabled);
try {
mBinder.setEnabled(enabled);
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
/**
@@ -454,22 +395,14 @@ public class LowpanInterface {
*/
public boolean isUp() {
try {
return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_UP);
} catch (LowpanException x) {
return false;
}
}
return mBinder.isUp();
/**
* Bring up or shut down the network interface.
*
* <p>This method brings up or shuts down the network interface, attaching or (gracefully)
* detaching from the currently configured LoWPAN network as appropriate.
*
* @hide
*/
public void setUp(boolean interfaceUp) throws LowpanException {
setProperty(LowpanProperties.KEY_INTERFACE_UP, interfaceUp);
} catch (DeadObjectException x) {
return false;
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
}
/**
@@ -480,9 +413,13 @@ public class LowpanInterface {
*/
public boolean isConnected() {
try {
return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_CONNECTED);
} catch (LowpanException x) {
return mBinder.isConnected();
} catch (DeadObjectException x) {
return false;
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
}
@@ -492,9 +429,13 @@ public class LowpanInterface {
*/
public boolean isCommissioned() {
try {
return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_COMMISSIONED);
} catch (LowpanException x) {
return mBinder.isCommissioned();
} catch (DeadObjectException x) {
return false;
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
}
@@ -514,90 +455,89 @@ public class LowpanInterface {
*/
public String getState() {
try {
return getProperty(LowpanProperties.KEY_INTERFACE_STATE);
} catch (LowpanException x) {
Log.e(TAG, x.toString());
return mBinder.getState();
} catch (DeadObjectException x) {
return STATE_FAULT;
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
}
/** Get network partition/fragment identifier. */
public String getPartitionId() {
try {
return mBinder.getPartitionId();
} catch (DeadObjectException x) {
return EMPTY_PARTITION_ID;
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
}
/** TODO: doc */
public LowpanIdentity getLowpanIdentity() {
LowpanIdentity.Builder builder = new LowpanIdentity.Builder();
try {
builder.updateFromMap(getProperties(NETWORK_PROPERTY_KEYS));
} catch (LowpanException x) {
// We ignore all LoWPAN-specitic exceptions here.
return mBinder.getLowpanIdentity();
} catch (DeadObjectException x) {
return new LowpanIdentity();
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
return builder.build();
}
/**
* TODO: doc
*
* @hide
*/
public void setLowpanIdentity(LowpanIdentity network) throws LowpanException {
Map<String, Object> map = new HashMap();
LowpanIdentity.addToMap(map, network);
setProperties(map);
}
/** TODO: doc */
@NonNull
public String getRole() {
String role = null;
try {
role = getProperty(LowpanProperties.KEY_NETWORK_ROLE);
} catch (LowpanException x) {
// We ignore all LoWPAN-specitic exceptions here.
Log.e(TAG, x.toString());
}
return mBinder.getRole();
if (role == null) {
role = ROLE_DETACHED;
}
} catch (DeadObjectException x) {
return ROLE_DETACHED;
return role;
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
}
/** TODO: doc */
@Nullable
public LowpanCredential getLowpanCredential() {
LowpanCredential credential = null;
try {
Integer keyIndex = getProperty(LowpanProperties.KEY_NETWORK_MASTER_KEY_INDEX);
return mBinder.getLowpanCredential();
if (keyIndex == null) {
credential =
LowpanCredential.createMasterKey(
getProperty(LowpanProperties.KEY_NETWORK_MASTER_KEY));
} else {
credential =
LowpanCredential.createMasterKey(
getProperty(LowpanProperties.KEY_NETWORK_MASTER_KEY),
keyIndex.intValue());
}
} catch (LowpanException x) {
// We ignore all LoWPAN-specitic exceptions here.
Log.e(TAG, x.toString());
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
}
return credential;
}
/**
* TODO: doc
*
* @hide
*/
public void setLowpanCredential(LowpanCredential networkCredential) throws LowpanException {
Map<String, Object> map = new HashMap();
networkCredential.addToMap(map);
setProperties(map);
public @NonNull String[] getSupportedNetworkTypes() throws LowpanException {
try {
return mBinder.getSupportedNetworkTypes();
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
public @NonNull LowpanChannelInfo[] getSupportedChannels() throws LowpanException {
try {
return mBinder.getSupportedChannels();
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
// Listener Support
@@ -627,57 +567,80 @@ public class LowpanInterface {
}
}
@Override public void onPropertiesChanged(Map properties) {
Runnable runnable =
() -> {
for (String key : (Set<String>) properties.keySet()) {
Object value = properties.get(key);
switch (key) {
case ILowpanInterface.KEY_INTERFACE_ENABLED:
cb.onEnabledChanged(
((Boolean) value).booleanValue());
break;
case ILowpanInterface.KEY_INTERFACE_UP:
cb.onUpChanged(((Boolean) value).booleanValue());
break;
case ILowpanInterface.KEY_INTERFACE_CONNECTED:
cb.onConnectedChanged(
((Boolean) value).booleanValue());
break;
case ILowpanInterface.KEY_INTERFACE_STATE:
cb.onStateChanged((String) value);
break;
case ILowpanInterface.KEY_NETWORK_NAME:
case ILowpanInterface.KEY_NETWORK_PANID:
case ILowpanInterface.KEY_NETWORK_XPANID:
case ILowpanInterface.KEY_CHANNEL:
cb.onLowpanIdentityChanged(getLowpanIdentity());
break;
case ILowpanInterface.KEY_NETWORK_ROLE:
cb.onRoleChanged(value.toString());
break;
}
}
cb.onPropertiesChanged(properties);
};
mHandler.post(runnable);
@Override
public void onEnabledChanged(boolean value) {
mHandler.post(() -> cb.onEnabledChanged(value));
}
@Override public void onLinkNetworkAdded(IpPrefix prefix) {
// Support for this event isn't yet implemented.
@Override
public void onConnectedChanged(boolean value) {
mHandler.post(() -> cb.onConnectedChanged(value));
}
@Override public void onLinkNetworkRemoved(IpPrefix prefix) {
// Support for this event isn't yet implemented.
@Override
public void onUpChanged(boolean value) {
mHandler.post(() -> cb.onUpChanged(value));
}
@Override public void onLinkAddressAdded(String address) {
// Support for this event isn't yet implemented.
@Override
public void onRoleChanged(String value) {
mHandler.post(() -> cb.onRoleChanged(value));
}
@Override public void onLinkAddressRemoved(String address) {
// Support for this event isn't yet implemented.
@Override
public void onStateChanged(String value) {
mHandler.post(() -> cb.onStateChanged(value));
}
@Override
public void onLowpanIdentityChanged(LowpanIdentity value) {
mHandler.post(() -> cb.onLowpanIdentityChanged(value));
}
@Override
public void onLinkNetworkAdded(IpPrefix value) {
mHandler.post(() -> cb.onLinkNetworkAdded(value));
}
@Override
public void onLinkNetworkRemoved(IpPrefix value) {
mHandler.post(() -> cb.onLinkNetworkRemoved(value));
}
@Override
public void onLinkAddressAdded(String value) {
LinkAddress la;
try {
la = new LinkAddress(value);
} catch (IllegalArgumentException x) {
Log.e(
TAG,
"onLinkAddressAdded: Bad LinkAddress \"" + value + "\", " + x);
return;
}
mHandler.post(() -> cb.onLinkAddressAdded(la));
}
@Override
public void onLinkAddressRemoved(String value) {
LinkAddress la;
try {
la = new LinkAddress(value);
} catch (IllegalArgumentException x) {
Log.e(
TAG,
"onLinkAddressRemoved: Bad LinkAddress \""
+ value
+ "\", "
+ x);
return;
}
mHandler.post(() -> cb.onLinkAddressRemoved(la));
}
@Override
public void onReceiveFromCommissioner(byte[] packet) {
// This is only used by the LowpanCommissioningSession.
}
};
try {
@@ -752,9 +715,9 @@ public class LowpanInterface {
*
* @hide
*/
public LinkAddress[] copyLinkAddresses() throws LowpanException {
public LinkAddress[] getLinkAddresses() throws LowpanException {
try {
String[] linkAddressStrings = mBinder.copyLinkAddresses();
String[] linkAddressStrings = mBinder.getLinkAddresses();
LinkAddress[] ret = new LinkAddress[linkAddressStrings.length];
int i = 0;
for (String str : linkAddressStrings) {
@@ -766,7 +729,7 @@ public class LowpanInterface {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
@@ -775,15 +738,15 @@ public class LowpanInterface {
*
* @hide
*/
public IpPrefix[] copyLinkNetworks() throws LowpanException {
public IpPrefix[] getLinkNetworks() throws LowpanException {
try {
return mBinder.copyLinkNetworks();
return mBinder.getLinkNetworks();
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
@@ -800,7 +763,7 @@ public class LowpanInterface {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
@@ -837,7 +800,7 @@ public class LowpanInterface {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}

View File

@@ -16,74 +16,14 @@
package android.net.lowpan;
import android.net.IpPrefix;
import android.net.LinkAddress;
/** {@hide} */
public final class LowpanProperties {
public static final LowpanProperty<Boolean> KEY_INTERFACE_ENABLED =
new LowpanStandardProperty(
"android.net.lowpan.property.INTERFACE_ENABLED", Boolean.class);
public static final LowpanProperty<Boolean> KEY_INTERFACE_COMMISSIONED =
new LowpanStandardProperty(
"android.net.lowpan.property.INTERFACE_COMMISSIONED", Boolean.class);
public static final LowpanProperty<Boolean> KEY_INTERFACE_CONNECTED =
new LowpanStandardProperty(
"android.net.lowpan.property.INTERFACE_CONNECTED", Boolean.class);
public static final LowpanProperty<Boolean> KEY_INTERFACE_UP =
new LowpanStandardProperty("android.net.lowpan.property.INTERFACE_UP", Boolean.class);
public static final LowpanProperty<String> KEY_INTERFACE_STATE =
new LowpanStandardProperty("android.net.lowpan.property.INTERFACE_STATE", String.class);
public static final LowpanProperty<String> KEY_NETWORK_NAME =
new LowpanStandardProperty("android.net.lowpan.property.NETWORK_NAME", Boolean.class);
public static final LowpanProperty<Integer> KEY_NETWORK_PANID =
new LowpanStandardProperty("android.net.lowpan.property.NETWORK_PANID", Integer.class);
public static final LowpanProperty<byte[]> KEY_NETWORK_XPANID =
new LowpanStandardProperty("android.net.lowpan.property.NETWORK_XPANID", byte[].class);
public static final LowpanProperty<byte[]> KEY_NETWORK_MASTER_KEY =
new LowpanStandardProperty(
"android.net.lowpan.property.NETWORK_MASTER_KEY", byte[].class);
public static final LowpanProperty<Integer> KEY_NETWORK_MASTER_KEY_INDEX =
new LowpanStandardProperty(
"android.net.lowpan.property.NETWORK_MASTER_KEY_INDEX", Integer.class);
public static final LowpanProperty<Integer> KEY_NETWORK_TYPE =
new LowpanStandardProperty("android.net.lowpan.property.NETWORK_TYPE", Integer.class);
public static final LowpanProperty<String> KEY_NETWORK_ROLE =
new LowpanStandardProperty("android.net.lowpan.property.NETWORK_ROLE", String.class);
public static final LowpanProperty<Integer> KEY_CHANNEL =
new LowpanStandardProperty("android.net.lowpan.property.CHANNEL", Integer.class);
public static final LowpanProperty<int[]> KEY_CHANNEL_MASK =
new LowpanStandardProperty("android.net.lowpan.property.CHANNEL_MASK", int[].class);
public static final LowpanProperty<Integer> KEY_MAX_TX_POWER =
new LowpanStandardProperty("android.net.lowpan.property.MAX_TX_POWER", Integer.class);
public static final LowpanProperty<Integer> KEY_RSSI =
new LowpanStandardProperty("android.net.lowpan.property.RSSI", Integer.class);
public static final LowpanProperty<Integer> KEY_LQI =
new LowpanStandardProperty("android.net.lowpan.property.LQI", Integer.class);
public static final LowpanProperty<byte[]> KEY_BEACON_ADDRESS =
new LowpanStandardProperty("android.net.lowpan.property.BEACON_ADDRESS", byte[].class);
public static final LowpanProperty<Boolean> KEY_BEACON_CAN_ASSIST =
new LowpanStandardProperty(
"android.net.lowpan.property.BEACON_CAN_ASSIST", Boolean.class);
public static final LowpanProperty<String> KEY_DRIVER_VERSION =
new LowpanStandardProperty("android.net.lowpan.property.DRIVER_VERSION", String.class);
public static final LowpanProperty<String> KEY_NCP_VERSION =
new LowpanStandardProperty("android.net.lowpan.property.NCP_VERSION", String.class);
/** @hide */
public static final LowpanProperty<byte[]> KEY_EXTENDED_ADDRESS =
new LowpanStandardProperty(
"android.net.lowpan.property.EXTENDED_ADDRESS", byte[].class);
/** @hide */
public static final LowpanProperty<byte[]> KEY_MAC_ADDRESS =
new LowpanStandardProperty("android.net.lowpan.property.MAC_ADDRESS", byte[].class);
/** @hide */
private LowpanProperties() {}

View File

@@ -0,0 +1,19 @@
/**
* Copyright (C) 2017 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.net.lowpan;
parcelable LowpanProvision cpp_header "android/net/lowpan/LowpanProvision.h";

View File

@@ -18,7 +18,9 @@ package android.net.lowpan;
import android.annotation.NonNull;
import android.annotation.Nullable;
import java.util.Map;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Objects;
/**
* Describes the information needed to describe a network
@@ -26,7 +28,7 @@ import java.util.Map;
* @hide
*/
// @SystemApi
public class LowpanProvision {
public class LowpanProvision implements Parcelable {
// Builder
@@ -69,20 +71,6 @@ public class LowpanProvision {
return mCredential;
}
// LoWPAN-Internal Methods
static void addToMap(Map<String, Object> parameters, LowpanProvision provision)
throws LowpanException {
provision.mIdentity.addToMap(parameters);
if (provision.mCredential != null) {
provision.mCredential.addToMap(parameters);
}
}
void addToMap(Map<String, Object> parameters) throws LowpanException {
addToMap(parameters, this);
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -90,11 +78,72 @@ public class LowpanProvision {
sb.append("LowpanProvision { identity => ").append(mIdentity.toString());
if (mCredential != null) {
sb.append(", credential: ").append(mCredential.toString());
sb.append(", credential => ").append(mCredential.toString());
}
sb.append("}");
return sb.toString();
}
@Override
public int hashCode() {
return Objects.hash(mIdentity, mCredential);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof LowpanProvision)) {
return false;
}
LowpanProvision rhs = (LowpanProvision) obj;
if (!mIdentity.equals(rhs.mIdentity)) {
return false;
}
if (!Objects.equals(mCredential, rhs.mCredential)) {
return false;
}
return true;
}
/** Implement the Parcelable interface. */
@Override
public int describeContents() {
return 0;
}
/** Implement the Parcelable interface. */
@Override
public void writeToParcel(Parcel dest, int flags) {
mIdentity.writeToParcel(dest, flags);
if (mCredential == null) {
dest.writeBoolean(false);
} else {
dest.writeBoolean(true);
mCredential.writeToParcel(dest, flags);
}
}
/** Implement the Parcelable interface. */
public static final Creator<LowpanProvision> CREATOR =
new Creator<LowpanProvision>() {
public LowpanProvision createFromParcel(Parcel in) {
Builder builder = new Builder();
builder.setLowpanIdentity(LowpanIdentity.CREATOR.createFromParcel(in));
if (in.readBoolean()) {
builder.setLowpanCredential(LowpanCredential.CREATOR.createFromParcel(in));
}
return builder.build();
}
public LowpanProvision[] newArray(int size) {
return new LowpanProvision[size];
}
};
};

View File

@@ -0,0 +1,42 @@
/*
* Copyright (C) 2017 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.net.lowpan;
import android.util.AndroidRuntimeException;
/**
* Generic runtime exception for LoWPAN operations.
*
* @hide
*/
// @SystemApi
public class LowpanRuntimeException extends AndroidRuntimeException {
public LowpanRuntimeException() {}
public LowpanRuntimeException(String message) {
super(message);
}
public LowpanRuntimeException(String message, Throwable cause) {
super(message, cause);
}
public LowpanRuntimeException(Exception cause) {
super(cause);
}
}

View File

@@ -21,7 +21,6 @@ import android.annotation.Nullable;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.util.Log;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -37,7 +36,7 @@ import java.util.Map;
*/
// @SystemApi
public class LowpanScanner {
private static final String TAG = LowpanInterface.class.getSimpleName();
private static final String TAG = LowpanScanner.class.getSimpleName();
// Public Classes
@@ -174,7 +173,7 @@ public class LowpanScanner {
ILowpanNetScanCallback binderListener =
new ILowpanNetScanCallback.Stub() {
public void onNetScanBeacon(Map parameters) {
public void onNetScanBeacon(LowpanBeaconInfo beaconInfo) {
Callback callback;
Handler handler;
@@ -187,12 +186,7 @@ public class LowpanScanner {
return;
}
Runnable runnable =
() ->
callback.onNetScanBeacon(
new LowpanBeaconInfo.Builder()
.updateFromMap(parameters)
.build());
Runnable runnable = () -> callback.onNetScanBeacon(beaconInfo);
if (handler != null) {
handler.post(runnable);
@@ -231,7 +225,7 @@ public class LowpanScanner {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
@@ -246,9 +240,6 @@ public class LowpanScanner {
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
Log.e(TAG, x.toString());
}
}
@@ -315,7 +306,7 @@ public class LowpanScanner {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
throw LowpanException.rethrowAsLowpanException(x);
throw LowpanException.rethrowFromServiceSpecificException(x);
}
}
@@ -330,9 +321,6 @@ public class LowpanScanner {
} catch (RemoteException x) {
throw x.rethrowAsRuntimeException();
} catch (ServiceSpecificException x) {
Log.e(TAG, x.toString());
}
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2017 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.net.lowpan;
/**
* Exception indicating the form operation found a network nearby with the same identity.
*
* @see LowpanInterface
* @hide
*/
// @SystemApi
public class NetworkAlreadyExistsException extends LowpanException {
public NetworkAlreadyExistsException() {}
public NetworkAlreadyExistsException(String message) {
super(message, null);
}
public NetworkAlreadyExistsException(String message, Throwable cause) {
super(message, cause);
}
public NetworkAlreadyExistsException(Exception cause) {
super(cause);
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2017 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.net.lowpan;
/**
* Exception indicating this operation was canceled by the driver before it could finish.
*
* @see LowpanInterface
* @hide
*/
// @SystemApi
public class OperationCanceledException extends LowpanException {
public OperationCanceledException() {}
public OperationCanceledException(String message) {
super(message);
}
public OperationCanceledException(String message, Throwable cause) {
super(message, cause);
}
protected OperationCanceledException(Exception cause) {
super(cause);
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2017 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.net.lowpan;
/**
* Exception indicating the interface is the wrong state for an operation.
*
* @see LowpanInterface
* @hide
*/
// @SystemApi
public class WrongStateException extends LowpanException {
public WrongStateException() {}
public WrongStateException(String message) {
super(message);
}
public WrongStateException(String message, Throwable cause) {
super(message, cause);
}
protected WrongStateException(Exception cause) {
super(cause);
}
}

View File

@@ -54,8 +54,35 @@ LOCAL_STATIC_JAVA_LIBRARIES := \
mockito-target-minus-junit4 \
frameworks-base-testutils \
LOCAL_JAVA_LIBRARIES := \
android.test.runner \
LOCAL_JNI_SHARED_LIBRARIES += libframeworkslowpantestsjni
LOCAL_JNI_SHARED_LIBRARIES += libandroid_net_lowpan
LOCAL_JNI_SHARED_LIBRARIES += \
libbacktrace \
libbase \
libbinder \
libc++ \
libcutils \
liblog \
liblzma \
libnativehelper \
libnetdaidl \
libui \
libunwind \
libutils \
libvndksupport \
libcrypto \
libhidl-gen-utils \
libhidlbase \
libhidltransport \
libpackagelistparser \
libpcre2 \
libselinux \
libtinyxml2 \
libvintf \
libhwbinder \
android.hidl.token@1.0
LOCAL_JAVA_LIBRARIES := android.test.runner
LOCAL_PACKAGE_NAME := FrameworksLowpanApiTests
LOCAL_COMPATIBILITY_SUITE := device-tests
@@ -63,3 +90,25 @@ LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_CERTIFICATE := platform
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
include $(BUILD_PACKAGE)
#########################################################################
# Build JNI Shared Library
#########################################################################
LOCAL_PATH:= $(LOCAL_PATH)/jni
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_CFLAGS := -Wall -Wextra -Werror
LOCAL_SRC_FILES := $(call all-cpp-files-under)
LOCAL_SHARED_LIBRARIES += libandroid_net_lowpan
LOCAL_SHARED_LIBRARIES += libbinder
LOCAL_SHARED_LIBRARIES += liblog
LOCAL_MODULE := libframeworkslowpantestsjni
include $(BUILD_SHARED_LIBRARY)

View File

@@ -0,0 +1,134 @@
/*
* Copyright (C) 2017 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.net.lowpan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LowpanBeaconInfoTest {
static {
System.loadLibrary("frameworkslowpantestsjni");
}
private static native byte[] readAndWriteNative(byte[] inParcel);
public void testNativeParcelUnparcel(LowpanBeaconInfo original) {
byte[] inParcel = marshall(original);
byte[] outParcel = readAndWriteNative(inParcel);
LowpanBeaconInfo roundTrip = unmarshall(outParcel);
assertEquals(original, roundTrip);
assertArrayEquals(inParcel, outParcel);
}
@Test
public void testNativeParcelUnparcel() {
testNativeParcelUnparcel(
new LowpanBeaconInfo.Builder()
.setName("TestNet1")
.setPanid(0x1234)
.setXpanid(
new byte[] {
(byte) 0x00,
(byte) 0x11,
(byte) 0x22,
(byte) 0x33,
(byte) 0x44,
(byte) 0x55,
(byte) 0x66,
(byte) 0x77
})
.setType(LowpanInterface.NETWORK_TYPE_THREAD_V1)
.setChannel(15)
.setBeaconAddress(
new byte[] {
(byte) 0x88,
(byte) 0x99,
(byte) 0xaa,
(byte) 0xbb,
(byte) 0xcc,
(byte) 0xdd,
(byte) 0xee,
(byte) 0xff
})
.build());
testNativeParcelUnparcel(
new LowpanBeaconInfo.Builder()
.setName("TestNet2")
.setPanid(0x5678)
.setXpanid(
new byte[] {
(byte) 0x88,
(byte) 0x99,
(byte) 0xaa,
(byte) 0xbb,
(byte) 0xcc,
(byte) 0xdd,
(byte) 0xee,
(byte) 0xff
})
.setType("bork-bork-bork")
.setChannel(16)
.setBeaconAddress(
new byte[] {
(byte) 0x00,
(byte) 0x11,
(byte) 0x22,
(byte) 0x33,
(byte) 0x44,
(byte) 0x55,
(byte) 0x66,
(byte) 0x77
})
.setFlag(LowpanBeaconInfo.FLAG_CAN_ASSIST)
.build());
}
/**
* Write a {@link LowpanBeaconInfo} into an empty parcel and return the underlying data.
*
* @see unmarshall(byte[])
*/
private static byte[] marshall(LowpanBeaconInfo addr) {
Parcel p = Parcel.obtain();
addr.writeToParcel(p, /* flags */ 0);
p.setDataPosition(0);
return p.marshall();
}
/**
* Read raw bytes into a parcel, and read a {@link LowpanBeaconInfo} back out of them.
*
* @see marshall(LowpanBeaconInfo)
*/
private static LowpanBeaconInfo unmarshall(byte[] data) {
Parcel p = Parcel.obtain();
p.unmarshall(data, 0, data.length);
p.setDataPosition(0);
return LowpanBeaconInfo.CREATOR.createFromParcel(p);
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2017 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.net.lowpan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LowpanChannelInfoTest {
static {
System.loadLibrary("frameworkslowpantestsjni");
}
private static native byte[] readAndWriteNative(byte[] inParcel);
public void testNativeParcelUnparcel(LowpanChannelInfo original) {
byte[] inParcel = marshall(original);
byte[] outParcel = readAndWriteNative(inParcel);
LowpanChannelInfo roundTrip = unmarshall(outParcel);
assertEquals(original, roundTrip);
assertArrayEquals(inParcel, outParcel);
}
@Test
public void testNativeParcelUnparcel() {
int i;
for (i = 1; i < 26; i++) {
testNativeParcelUnparcel(LowpanChannelInfo.getChannelInfoForIeee802154Page0(i));
}
}
/**
* Write a {@link LowpanChannelInfo} into an empty parcel and return the underlying data.
*
* @see unmarshall(byte[])
*/
private static byte[] marshall(LowpanChannelInfo addr) {
Parcel p = Parcel.obtain();
addr.writeToParcel(p, /* flags */ 0);
p.setDataPosition(0);
return p.marshall();
}
/**
* Read raw bytes into a parcel, and read a {@link LowpanChannelInfo} back out of them.
*
* @see marshall(LowpanChannelInfo)
*/
private static LowpanChannelInfo unmarshall(byte[] data) {
Parcel p = Parcel.obtain();
p.unmarshall(data, 0, data.length);
p.setDataPosition(0);
return LowpanChannelInfo.CREATOR.createFromParcel(p);
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2017 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.net.lowpan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LowpanCredentialTest {
static {
System.loadLibrary("frameworkslowpantestsjni");
}
private static native byte[] readAndWriteNative(byte[] inParcel);
public void testNativeParcelUnparcel(LowpanCredential original) {
byte[] inParcel = marshall(original);
byte[] outParcel = readAndWriteNative(inParcel);
LowpanCredential roundTrip = unmarshall(outParcel);
assertEquals(original, roundTrip);
assertArrayEquals(inParcel, outParcel);
}
@Test
public void testNativeParcelUnparcel() {
testNativeParcelUnparcel(
LowpanCredential.createMasterKey(
new byte[] {
(byte) 0x88,
(byte) 0x99,
(byte) 0xaa,
(byte) 0xbb,
(byte) 0xcc,
(byte) 0xdd,
(byte) 0xee,
(byte) 0xff
}));
testNativeParcelUnparcel(
LowpanCredential.createMasterKey(
new byte[] {
(byte) 0x88, (byte) 0x99, (byte) 0xaa, (byte) 0xbb, (byte) 0xcc
},
15));
}
/**
* Write a {@link LowpanCredential} into an empty parcel and return the underlying data.
*
* @see unmarshall(byte[])
*/
private static byte[] marshall(LowpanCredential addr) {
Parcel p = Parcel.obtain();
addr.writeToParcel(p, /* flags */ 0);
p.setDataPosition(0);
return p.marshall();
}
/**
* Read raw bytes into a parcel, and read a {@link LowpanCredential} back out of them.
*
* @see marshall(LowpanCredential)
*/
private static LowpanCredential unmarshall(byte[] data) {
Parcel p = Parcel.obtain();
p.unmarshall(data, 0, data.length);
p.setDataPosition(0);
return LowpanCredential.CREATOR.createFromParcel(p);
}
}

View File

@@ -0,0 +1,199 @@
/*
* Copyright (C) 2017 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.net.lowpan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LowpanIdentityTest {
static {
System.loadLibrary("frameworkslowpantestsjni");
}
private static native byte[] readAndWriteNative(byte[] inParcel);
public void testNativeParcelUnparcel(LowpanIdentity original) {
byte[] inParcel = marshall(original);
byte[] outParcel = readAndWriteNative(inParcel);
LowpanIdentity roundTrip = unmarshall(outParcel);
assertEquals(original, roundTrip);
assertEquals(original.hashCode(), roundTrip.hashCode());
assertEquals(original.getName(), roundTrip.getName());
assertArrayEquals(inParcel, outParcel);
}
@Test
public void testNativeParcelUnparcel1() {
testNativeParcelUnparcel(
new LowpanIdentity.Builder()
.setName("TestNet1")
.setPanid(0x1234)
.setXpanid(
new byte[] {
(byte) 0x00,
(byte) 0x11,
(byte) 0x22,
(byte) 0x33,
(byte) 0x44,
(byte) 0x55,
(byte) 0x66,
(byte) 0x77
})
.setType(LowpanInterface.NETWORK_TYPE_THREAD_V1)
.setChannel(15)
.build());
}
@Test
public void testNativeParcelUnparcel2() {
testNativeParcelUnparcel(
new LowpanIdentity.Builder()
.setName("TestNet2")
.setPanid(0x5678)
.setXpanid(
new byte[] {
(byte) 0x88,
(byte) 0x99,
(byte) 0xaa,
(byte) 0xbb,
(byte) 0xcc,
(byte) 0xdd,
(byte) 0xee,
(byte) 0xff
})
.setType("bork-bork-bork")
.setChannel(16)
.build());
}
@Test
public void testNativeParcelUnparcel3() {
testNativeParcelUnparcel(new LowpanIdentity.Builder().setName("TestNet3").build());
}
@Test
public void testNativeParcelUnparcel4() {
testNativeParcelUnparcel(new LowpanIdentity.Builder().build());
}
@Test
public void testNativeParcelUnparcel5() {
testNativeParcelUnparcel(
new LowpanIdentity.Builder()
.setRawName(
new byte[] {
(byte) 0x66,
(byte) 0x6F,
(byte) 0x6F,
(byte) 0xC2,
(byte) 0xAD,
(byte) 0xCD,
(byte) 0x8F,
(byte) 0xE1,
(byte) 0xA0,
(byte) 0x86,
(byte) 0xE1,
(byte) 0xA0,
(byte) 0x8B
})
.build());
}
@Test
public void testStringPrep1() {
LowpanIdentity identity =
new LowpanIdentity.Builder()
.setRawName(
new byte[] {
(byte) 0x66,
(byte) 0x6F,
(byte) 0x6F,
(byte) 0x20,
(byte) 0xC2,
(byte) 0xAD,
(byte) 0xCD,
(byte) 0x8F,
(byte) 0xE1,
(byte) 0xA0,
(byte) 0x86,
(byte) 0xE1,
(byte) 0xA0,
(byte) 0x8B
})
.build();
assertFalse(identity.isNameValid());
}
@Test
public void testStringPrep2() {
LowpanIdentity identity =
new LowpanIdentity.Builder()
.setRawName(
new byte[] {
(byte) 0x66, (byte) 0x6F, (byte) 0x6F, (byte) 0x20, (byte) 0x6F
})
.build();
assertEquals("foo o", identity.getName());
assertTrue(identity.isNameValid());
}
@Test
public void testStringPrep3() {
LowpanIdentity identity = new LowpanIdentity.Builder().setName("foo o").build();
assertTrue(identity.isNameValid());
assertEquals("foo o", identity.getName());
}
/**
* Write a {@link LowpanIdentity} into an empty parcel and return the underlying data.
*
* @see unmarshall(byte[])
*/
private static byte[] marshall(LowpanIdentity addr) {
Parcel p = Parcel.obtain();
addr.writeToParcel(p, /* flags */ 0);
p.setDataPosition(0);
return p.marshall();
}
/**
* Read raw bytes into a parcel, and read a {@link LowpanIdentity} back out of them.
*
* @see marshall(LowpanIdentity)
*/
private static LowpanIdentity unmarshall(byte[] data) {
Parcel p = Parcel.obtain();
p.unmarshall(data, 0, data.length);
p.setDataPosition(0);
return LowpanIdentity.CREATOR.createFromParcel(p);
}
}

View File

@@ -16,26 +16,22 @@
package android.net.lowpan;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.*;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.net.LinkAddress;
import android.os.Handler;
import android.os.IBinder;
import android.os.test.TestLooper;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Map;
import java.util.HashMap;
/** Unit tests for android.net.lowpan.LowpanInterface. */
@RunWith(AndroidJUnit4.class)
@@ -64,7 +60,8 @@ public class LowpanInterfaceTest {
when(mLowpanInterfaceService.getName()).thenReturn("wpan0");
when(mLowpanInterfaceService.asBinder()).thenReturn(mLowpanInterfaceBinder);
mLowpanInterface = new LowpanInterface(mContext, mLowpanInterfaceService, mTestLooper.getLooper());
mLowpanInterface =
new LowpanInterface(mContext, mLowpanInterfaceService, mTestLooper.getLooper());
}
@Test
@@ -81,12 +78,8 @@ public class LowpanInterfaceTest {
return listener instanceof ILowpanInterfaceListener;
}));
// Build a changed property map
Map<String, Object> changedProperties = new HashMap<>();
LowpanProperties.KEY_INTERFACE_STATE.putInMap(changedProperties, LowpanInterface.STATE_OFFLINE);
// Change some properties
mInterfaceListener.onPropertiesChanged(changedProperties);
mInterfaceListener.onStateChanged(LowpanInterface.STATE_OFFLINE);
mTestLooper.dispatchAll();
// Verify that the property was changed
@@ -94,4 +87,66 @@ public class LowpanInterfaceTest {
.onStateChanged(
argThat(stateString -> stateString.equals(LowpanInterface.STATE_OFFLINE)));
}
@Test
public void testLinkAddressCallback() throws Exception {
// Register our callback
mLowpanInterface.registerCallback(mLowpanInterfaceCallback);
// Verify a listener was added
verify(mLowpanInterfaceService)
.addListener(
argThat(
listener -> {
mInterfaceListener = listener;
return listener instanceof ILowpanInterfaceListener;
}));
final LinkAddress linkAddress = new LinkAddress("fe80::1/64");
// Change some properties
mInterfaceListener.onLinkAddressAdded(linkAddress.toString());
mTestLooper.dispatchAll();
// Verify that the property was changed
verify(mLowpanInterfaceCallback)
.onLinkAddressAdded(argThat(addr -> addr.equals(linkAddress)));
// Change some properties
mInterfaceListener.onLinkAddressRemoved(linkAddress.toString());
mTestLooper.dispatchAll();
// Verify that the property was changed
verify(mLowpanInterfaceCallback)
.onLinkAddressRemoved(argThat(addr -> addr.equals(linkAddress)));
}
@Test
public void testBogusLinkAddressCallback() throws Exception {
// Register our callback
mLowpanInterface.registerCallback(mLowpanInterfaceCallback);
// Verify a listener was added
verify(mLowpanInterfaceService)
.addListener(
argThat(
listener -> {
mInterfaceListener = listener;
return listener instanceof ILowpanInterfaceListener;
}));
// Change some properties
mInterfaceListener.onLinkAddressAdded("fe80:::1/640");
mTestLooper.dispatchAll();
// Verify that no callback was called.
verifyNoMoreInteractions(mLowpanInterfaceCallback);
// Change some properties
mInterfaceListener.onLinkAddressRemoved("fe80:::1/640");
mTestLooper.dispatchAll();
// Verify that no callback was called.
verifyNoMoreInteractions(mLowpanInterfaceCallback);
}
}

View File

@@ -16,10 +16,9 @@
package android.net.lowpan;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.*;
import android.content.Context;

View File

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2017 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.net.lowpan;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertArrayEquals;
import android.os.Parcel;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class LowpanProvisionTest {
static {
System.loadLibrary("frameworkslowpantestsjni");
}
private static native byte[] readAndWriteNative(byte[] inParcel);
public void testNativeParcelUnparcel(LowpanProvision original) {
byte[] inParcel = marshall(original);
byte[] outParcel = readAndWriteNative(inParcel);
LowpanProvision roundTrip = unmarshall(outParcel);
assertEquals(original, roundTrip);
assertArrayEquals(inParcel, outParcel);
}
@Test
public void testNativeParcelUnparcel() {
testNativeParcelUnparcel(
new LowpanProvision.Builder()
.setLowpanIdentity(
new LowpanIdentity.Builder()
.setName("TestNet1")
.setPanid(0x1234)
.setXpanid(
new byte[] {
(byte) 0x00,
(byte) 0x11,
(byte) 0x22,
(byte) 0x33,
(byte) 0x44,
(byte) 0x55,
(byte) 0x66,
(byte) 0x77
})
.setType(LowpanInterface.NETWORK_TYPE_THREAD_V1)
.setChannel(15)
.build())
.build());
testNativeParcelUnparcel(
new LowpanProvision.Builder()
.setLowpanIdentity(
new LowpanIdentity.Builder()
.setName("TestNet2")
.setPanid(0x5678)
.setXpanid(
new byte[] {
(byte) 0x88,
(byte) 0x99,
(byte) 0xaa,
(byte) 0xbb,
(byte) 0xcc,
(byte) 0xdd,
(byte) 0xee,
(byte) 0xff
})
.setType("bork-bork-bork")
.setChannel(16)
.build())
.setLowpanCredential(
LowpanCredential.createMasterKey(
new byte[] {
(byte) 0x88,
(byte) 0x99,
(byte) 0xaa,
(byte) 0xbb,
(byte) 0xcc,
(byte) 0xdd,
(byte) 0xee,
(byte) 0xff
}))
.build());
}
/**
* Write a {@link LowpanProvision} into an empty parcel and return the underlying data.
*
* @see unmarshall(byte[])
*/
private static byte[] marshall(LowpanProvision addr) {
Parcel p = Parcel.obtain();
addr.writeToParcel(p, /* flags */ 0);
p.setDataPosition(0);
return p.marshall();
}
/**
* Read raw bytes into a parcel, and read a {@link LowpanProvision} back out of them.
*
* @see marshall(LowpanProvision)
*/
private static LowpanProvision unmarshall(byte[] data) {
Parcel p = Parcel.obtain();
p.unmarshall(data, 0, data.length);
p.setDataPosition(0);
return LowpanProvision.CREATOR.createFromParcel(p);
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2017 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.
*/
#include <memory>
#include <binder/Parcel.h>
#include "LowpanBeaconInfoTest.h"
using android::net::lowpan::LowpanBeaconInfo;
/**
* Reads exactly one LowpanBeaconInfo from 'parcelData' assuming that it is a Parcel. Any bytes afterward
* are ignored.
*/
static LowpanBeaconInfo unmarshall(JNIEnv* env, jbyteArray parcelData) {
const int length = env->GetArrayLength(parcelData);
std::unique_ptr<uint8_t> bytes(new uint8_t[length]);
env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast<jbyte*>(bytes.get()));
android::Parcel p;
p.setData(bytes.get(), length);
LowpanBeaconInfo value;
value.readFromParcel(&p);
return value;
}
/**
* Creates a Java byte[] array and writes the contents of 'addr' to it as a Parcel containing
* exactly one object.
*
* Every LowpanBeaconInfo maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and
* 'unmarshall(e, marshall(e, x))' should be fixed points.
*/
static jbyteArray marshall(JNIEnv* env, const LowpanBeaconInfo& addr) {
android::Parcel p;
addr.writeToParcel(&p);
const int length = p.dataSize();
jbyteArray parcelData = env->NewByteArray(length);
env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast<const jbyte*>(p.data()));
return parcelData;
}
extern "C"
JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanBeaconInfoTest_readAndWriteNative(JNIEnv* env, jclass,
jbyteArray inParcel) {
const LowpanBeaconInfo value = unmarshall(env, inParcel);
return marshall(env, value);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef _ANDROID_NET_LOWPANBEACONINFOTEST_H_
#define _ANDROID_NET_LOWPANBEACONINFOTEST_H_
#include <jni.h>
#include <android/net/lowpan/LowpanBeaconInfo.h>
extern "C"
JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanBeaconInfoTest_readAndWriteNative(JNIEnv* env, jclass,
jbyteArray inParcel);
#endif // _ANDROID_NET_LOWPANBEACONINFOTEST_H_

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2017 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.
*/
#include <memory>
#include <binder/Parcel.h>
#include "LowpanChannelInfoTest.h"
using android::net::lowpan::LowpanChannelInfo;
/**
* Reads exactly one LowpanChannelInfo from 'parcelData' assuming that it is a Parcel. Any bytes afterward
* are ignored.
*/
static LowpanChannelInfo unmarshall(JNIEnv* env, jbyteArray parcelData) {
const int length = env->GetArrayLength(parcelData);
std::unique_ptr<uint8_t> bytes(new uint8_t[length]);
env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast<jbyte*>(bytes.get()));
android::Parcel p;
p.setData(bytes.get(), length);
LowpanChannelInfo value;
value.readFromParcel(&p);
return value;
}
/**
* Creates a Java byte[] array and writes the contents of 'addr' to it as a Parcel containing
* exactly one object.
*
* Every LowpanChannelInfo maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and
* 'unmarshall(e, marshall(e, x))' should be fixed points.
*/
static jbyteArray marshall(JNIEnv* env, const LowpanChannelInfo& addr) {
android::Parcel p;
addr.writeToParcel(&p);
const int length = p.dataSize();
jbyteArray parcelData = env->NewByteArray(length);
env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast<const jbyte*>(p.data()));
return parcelData;
}
extern "C"
JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanChannelInfoTest_readAndWriteNative(JNIEnv* env, jclass,
jbyteArray inParcel) {
const LowpanChannelInfo value = unmarshall(env, inParcel);
return marshall(env, value);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef _ANDROID_NET_LOWPANCHANNELINFOTEST_H_
#define _ANDROID_NET_LOWPANCHANNELINFOTEST_H_
#include <jni.h>
#include <android/net/lowpan/LowpanChannelInfo.h>
extern "C"
JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanChannelInfoTest_readAndWriteNative(JNIEnv* env, jclass,
jbyteArray inParcel);
#endif // _ANDROID_NET_LOWPANCHANNELINFOTEST_H_

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2017 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.
*/
#include <memory>
#include <binder/Parcel.h>
#include "LowpanCredentialTest.h"
using android::net::lowpan::LowpanCredential;
/**
* Reads exactly one LowpanCredential from 'parcelData' assuming that it is a Parcel. Any bytes afterward
* are ignored.
*/
static LowpanCredential unmarshall(JNIEnv* env, jbyteArray parcelData) {
const int length = env->GetArrayLength(parcelData);
std::unique_ptr<uint8_t> bytes(new uint8_t[length]);
env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast<jbyte*>(bytes.get()));
android::Parcel p;
p.setData(bytes.get(), length);
LowpanCredential value;
value.readFromParcel(&p);
return value;
}
/**
* Creates a Java byte[] array and writes the contents of 'addr' to it as a Parcel containing
* exactly one object.
*
* Every LowpanCredential maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and
* 'unmarshall(e, marshall(e, x))' should be fixed points.
*/
static jbyteArray marshall(JNIEnv* env, const LowpanCredential& addr) {
android::Parcel p;
addr.writeToParcel(&p);
const int length = p.dataSize();
jbyteArray parcelData = env->NewByteArray(length);
env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast<const jbyte*>(p.data()));
return parcelData;
}
extern "C"
JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanCredentialTest_readAndWriteNative(JNIEnv* env, jclass,
jbyteArray inParcel) {
const LowpanCredential value = unmarshall(env, inParcel);
return marshall(env, value);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef _ANDROID_NET_LOWPANCREDENTIALTEST_H_
#define _ANDROID_NET_LOWPANCREDENTIALTEST_H_
#include <jni.h>
#include <android/net/lowpan/LowpanCredential.h>
extern "C"
JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanCredentialTest_readAndWriteNative(JNIEnv* env, jclass,
jbyteArray inParcel);
#endif // _ANDROID_NET_LOWPANCREDENTIALTEST_H_

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2017 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.
*/
#include <memory>
#include <binder/Parcel.h>
#include "LowpanIdentityTest.h"
using android::net::lowpan::LowpanIdentity;
/**
* Reads exactly one LowpanIdentity from 'parcelData' assuming that it is a Parcel. Any bytes afterward
* are ignored.
*/
static LowpanIdentity unmarshall(JNIEnv* env, jbyteArray parcelData) {
const int length = env->GetArrayLength(parcelData);
std::unique_ptr<uint8_t> bytes(new uint8_t[length]);
env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast<jbyte*>(bytes.get()));
android::Parcel p;
p.setData(bytes.get(), length);
LowpanIdentity value;
value.readFromParcel(&p);
return value;
}
/**
* Creates a Java byte[] array and writes the contents of 'addr' to it as a Parcel containing
* exactly one object.
*
* Every LowpanIdentity maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and
* 'unmarshall(e, marshall(e, x))' should be fixed points.
*/
static jbyteArray marshall(JNIEnv* env, const LowpanIdentity& addr) {
android::Parcel p;
addr.writeToParcel(&p);
const int length = p.dataSize();
jbyteArray parcelData = env->NewByteArray(length);
env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast<const jbyte*>(p.data()));
return parcelData;
}
extern "C"
JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanIdentityTest_readAndWriteNative(JNIEnv* env, jclass,
jbyteArray inParcel) {
const LowpanIdentity value = unmarshall(env, inParcel);
return marshall(env, value);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef _ANDROID_NET_LOWPANIDENTITYTEST_H_
#define _ANDROID_NET_LOWPANIDENTITYTEST_H_
#include <jni.h>
#include <android/net/lowpan/LowpanIdentity.h>
extern "C"
JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanIdentityTest_readAndWriteNative(JNIEnv* env, jclass,
jbyteArray inParcel);
#endif // _ANDROID_NET_LOWPANIDENTITYTEST_H_

View File

@@ -0,0 +1,66 @@
/*
* Copyright (C) 2017 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.
*/
#include <memory>
#include <binder/Parcel.h>
#include "LowpanProvisionTest.h"
using android::net::lowpan::LowpanProvision;
/**
* Reads exactly one LowpanProvision from 'parcelData' assuming that it is a Parcel. Any bytes afterward
* are ignored.
*/
static LowpanProvision unmarshall(JNIEnv* env, jbyteArray parcelData) {
const int length = env->GetArrayLength(parcelData);
std::unique_ptr<uint8_t> bytes(new uint8_t[length]);
env->GetByteArrayRegion(parcelData, 0, length, reinterpret_cast<jbyte*>(bytes.get()));
android::Parcel p;
p.setData(bytes.get(), length);
LowpanProvision value;
value.readFromParcel(&p);
return value;
}
/**
* Creates a Java byte[] array and writes the contents of 'addr' to it as a Parcel containing
* exactly one object.
*
* Every LowpanProvision maps to a unique parcel object, so both 'marshall(e, unmarshall(e, x))' and
* 'unmarshall(e, marshall(e, x))' should be fixed points.
*/
static jbyteArray marshall(JNIEnv* env, const LowpanProvision& addr) {
android::Parcel p;
addr.writeToParcel(&p);
const int length = p.dataSize();
jbyteArray parcelData = env->NewByteArray(length);
env->SetByteArrayRegion(parcelData, 0, length, reinterpret_cast<const jbyte*>(p.data()));
return parcelData;
}
extern "C"
JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanProvisionTest_readAndWriteNative(JNIEnv* env, jclass,
jbyteArray inParcel) {
const LowpanProvision value = unmarshall(env, inParcel);
return marshall(env, value);
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2017 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.
*/
#ifndef _ANDROID_NET_LOWPANPROVISIONTEST_H_
#define _ANDROID_NET_LOWPANPROVISIONTEST_H_
#include <jni.h>
#include <android/net/lowpan/LowpanProvision.h>
extern "C"
JNIEXPORT jbyteArray Java_android_net_lowpan_LowpanProvisionTest_readAndWriteNative(JNIEnv* env, jclass,
jbyteArray inParcel);
#endif // _ANDROID_NET_LOWPANPROVISIONTEST_H_