Merge "Revert "Initial support for proposed android.net.lowpan"" into oc-dr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
0716c8e60e
@@ -571,15 +571,6 @@ LOCAL_SRC_FILES += \
|
|||||||
|
|
||||||
LOCAL_AIDL_INCLUDES += system/update_engine/binder_bindings
|
LOCAL_AIDL_INCLUDES += system/update_engine/binder_bindings
|
||||||
|
|
||||||
LOCAL_AIDL_INCLUDES += frameworks/base/lowpan/java
|
|
||||||
LOCAL_SRC_FILES += \
|
|
||||||
lowpan/java/android/net/lowpan/ILowpanEnergyScanCallback.aidl \
|
|
||||||
lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl \
|
|
||||||
lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl \
|
|
||||||
lowpan/java/android/net/lowpan/ILowpanInterface.aidl \
|
|
||||||
lowpan/java/android/net/lowpan/ILowpanManagerListener.aidl \
|
|
||||||
lowpan/java/android/net/lowpan/ILowpanManager.aidl
|
|
||||||
|
|
||||||
# FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk
|
# FRAMEWORKS_BASE_JAVA_SRC_DIRS comes from build/core/pathmap.mk
|
||||||
LOCAL_AIDL_INCLUDES += \
|
LOCAL_AIDL_INCLUDES += \
|
||||||
$(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
|
$(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
|
||||||
|
|||||||
@@ -1326,27 +1326,6 @@
|
|||||||
<permission android:name="android.permission.NETWORK_SETTINGS"
|
<permission android:name="android.permission.NETWORK_SETTINGS"
|
||||||
android:protectionLevel="signature" />
|
android:protectionLevel="signature" />
|
||||||
|
|
||||||
<!-- #SystemApi @hide Allows applications to access information about LoWPAN interfaces.
|
|
||||||
<p>Not for use by third-party applications. -->
|
|
||||||
<permission android:name="android.permission.ACCESS_LOWPAN_STATE"
|
|
||||||
android:protectionLevel="signature|privileged" />
|
|
||||||
|
|
||||||
<!-- #SystemApi @hide Allows applications to change LoWPAN connectivity state.
|
|
||||||
<p>Not for use by third-party applications. -->
|
|
||||||
<permission android:name="android.permission.CHANGE_LOWPAN_STATE"
|
|
||||||
android:protectionLevel="signature|privileged" />
|
|
||||||
|
|
||||||
<!-- #SystemApi @hide Allows applications to read LoWPAN credential.
|
|
||||||
<p>Not for use by third-party applications. -->
|
|
||||||
<permission android:name="android.permission.READ_LOWPAN_CREDENTIAL"
|
|
||||||
android:protectionLevel="signature|privileged" />
|
|
||||||
|
|
||||||
<!-- #SystemApi @hide Allows a service to register or unregister
|
|
||||||
new LoWPAN interfaces.
|
|
||||||
<p>Not for use by third-party applications. -->
|
|
||||||
<permission android:name="android.permission.MANAGE_LOWPAN_INTERFACES"
|
|
||||||
android:protectionLevel="signature|privileged" />
|
|
||||||
|
|
||||||
<!-- ======================================= -->
|
<!-- ======================================= -->
|
||||||
<!-- Permissions for short range, peripheral networks -->
|
<!-- Permissions for short range, peripheral networks -->
|
||||||
<!-- ======================================= -->
|
<!-- ======================================= -->
|
||||||
|
|||||||
@@ -1,31 +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)
|
|
||||||
endif
|
|
||||||
@@ -1,23 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
interface ILowpanEnergyScanCallback {
|
|
||||||
oneway void onEnergyScanResult(int channel, int rssi);
|
|
||||||
oneway void onEnergyScanFinished();
|
|
||||||
}
|
|
||||||
@@ -1,154 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import android.net.lowpan.ILowpanInterfaceListener;
|
|
||||||
import android.net.lowpan.ILowpanNetScanCallback;
|
|
||||||
import android.net.lowpan.ILowpanEnergyScanCallback;
|
|
||||||
import android.os.PersistableBundle;
|
|
||||||
import android.net.IpPrefix;
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
interface ILowpanInterface {
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Permission String Constants
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
|
|
||||||
const String KEY_INTERFACE_ENABLED = "android.net.lowpan.property.INTERFACE_ENABLED";
|
|
||||||
const String KEY_INTERFACE_UP = "android.net.lowpan.property.INTERFACE_UP";
|
|
||||||
const String KEY_INTERFACE_COMMISSIONED = "android.net.lowpan.property.INTERFACE_COMMISSIONED";
|
|
||||||
const String KEY_INTERFACE_CONNECTED = "android.net.lowpan.property.INTERFACE_CONNECTED";
|
|
||||||
const String KEY_INTERFACE_STATE = "android.net.lowpan.property.INTERFACE_STATE";
|
|
||||||
|
|
||||||
const String KEY_NETWORK_NAME = "android.net.lowpan.property.NETWORK_NAME";
|
|
||||||
const String KEY_NETWORK_TYPE = "android.net.lowpan.property.NETWORK_TYPE";
|
|
||||||
const String KEY_NETWORK_PANID = "android.net.lowpan.property.NETWORK_PANID";
|
|
||||||
const String KEY_NETWORK_XPANID = "android.net.lowpan.property.NETWORK_XPANID";
|
|
||||||
const String KEY_NETWORK_ROLE = "android.net.lowpan.property.NETWORK_ROLE";
|
|
||||||
const String KEY_NETWORK_MASTER_KEY = "android.net.lowpan.property.NETWORK_MASTER_KEY";
|
|
||||||
const String KEY_NETWORK_MASTER_KEY_INDEX
|
|
||||||
= "android.net.lowpan.property.NETWORK_MASTER_KEY_INDEX";
|
|
||||||
|
|
||||||
const String KEY_SUPPORTED_CHANNELS = "android.net.lowpan.property.SUPPORTED_CHANNELS";
|
|
||||||
const String KEY_CHANNEL = "android.net.lowpan.property.CHANNEL";
|
|
||||||
const String KEY_CHANNEL_MASK = "android.net.lowpan.property.CHANNEL_MASK";
|
|
||||||
const String KEY_MAX_TX_POWER = "android.net.lowpan.property.MAX_TX_POWER";
|
|
||||||
const String KEY_RSSI = "android.net.lowpan.property.RSSI";
|
|
||||||
const String KEY_LQI = "android.net.lowpan.property.LQI";
|
|
||||||
|
|
||||||
const String KEY_LINK_ADDRESS_ARRAY = "android.net.lowpan.property.LINK_ADDRESS_ARRAY";
|
|
||||||
const String KEY_ROUTE_INFO_ARRAY = "android.net.lowpan.property.ROUTE_INFO_ARRAY";
|
|
||||||
|
|
||||||
const String KEY_BEACON_ADDRESS = "android.net.lowpan.property.BEACON_ORIGIN_ADDRESS";
|
|
||||||
const String KEY_BEACON_CAN_ASSIST = "android.net.lowpan.property.BEACON_CAN_ASSIST";
|
|
||||||
|
|
||||||
const String DRIVER_VERSION = "android.net.lowpan.property.DRIVER_VERSION";
|
|
||||||
const String NCP_VERSION = "android.net.lowpan.property.NCP_VERSION";
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
const String KEY_EXTENDED_ADDRESS = "android.net.lowpan.property.EXTENDED_ADDRESS";
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
const String KEY_MAC_ADDRESS = "android.net.lowpan.property.MAC_ADDRESS";
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Interface States
|
|
||||||
|
|
||||||
const String STATE_OFFLINE = "offline";
|
|
||||||
const String STATE_COMMISSIONING = "commissioning";
|
|
||||||
const String STATE_ATTACHING = "attaching";
|
|
||||||
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";
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Methods
|
|
||||||
|
|
||||||
@utf8InCpp String getName();
|
|
||||||
|
|
||||||
void join(in Map parameters);
|
|
||||||
void form(in Map parameters);
|
|
||||||
void leave();
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
void beginLowPower();
|
|
||||||
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);
|
|
||||||
|
|
||||||
void startNetScan(in Map properties, ILowpanNetScanCallback listener);
|
|
||||||
oneway void stopNetScan();
|
|
||||||
|
|
||||||
void startEnergyScan(in Map properties, ILowpanEnergyScanCallback listener);
|
|
||||||
oneway void stopEnergyScan();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
@@ -1,22 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
interface ILowpanInterfaceListener {
|
|
||||||
oneway void onPropertiesChanged(in Map properties);
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 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.net.lowpan.ILowpanInterface;
|
|
||||||
import android.net.lowpan.ILowpanManagerListener;
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
interface ILowpanManager {
|
|
||||||
|
|
||||||
const String LOWPAN_SERVICE_NAME = "lowpan";
|
|
||||||
|
|
||||||
ILowpanInterface getInterface(@utf8InCpp String name);
|
|
||||||
|
|
||||||
@utf8InCpp String[] getInterfaceList();
|
|
||||||
|
|
||||||
void addListener(ILowpanManagerListener listener);
|
|
||||||
void removeListener(ILowpanManagerListener listener);
|
|
||||||
|
|
||||||
void addInterface(ILowpanInterface lowpan_interface);
|
|
||||||
void removeInterface(ILowpanInterface lowpan_interface);
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 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.net.lowpan.ILowpanInterface;
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
interface ILowpanManagerListener {
|
|
||||||
oneway void onInterfaceAdded(ILowpanInterface lowpanInterface);
|
|
||||||
oneway void onInterfaceRemoved(ILowpanInterface lowpanInterface);
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2016 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;
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
interface ILowpanNetScanCallback {
|
|
||||||
oneway void onNetScanBeacon(in Map parameters);
|
|
||||||
oneway void onNetScanFinished();
|
|
||||||
}
|
|
||||||
@@ -1,150 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import com.android.internal.util.HexDump;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes a LoWPAN Beacon
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public class LowpanBeaconInfo extends LowpanIdentity {
|
|
||||||
|
|
||||||
private int mRssi = UNKNOWN;
|
|
||||||
private int mLqi = UNKNOWN;
|
|
||||||
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();
|
|
||||||
|
|
||||||
public Builder setRssi(int x) {
|
|
||||||
identity.mRssi = x;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setLqi(int x) {
|
|
||||||
identity.mLqi = x;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setBeaconAddress(byte x[]) {
|
|
||||||
identity.mBeaconAddress = x.clone();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setFlag(int x) {
|
|
||||||
identity.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);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LowpanBeaconInfo build() {
|
|
||||||
return identity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private LowpanBeaconInfo() {}
|
|
||||||
|
|
||||||
public int getRssi() {
|
|
||||||
return mRssi;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getLqi() {
|
|
||||||
return mLqi;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBeaconAddress() {
|
|
||||||
return mBeaconAddress.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Integer> getFlags() {
|
|
||||||
return mFlags.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFlagSet(int flag) {
|
|
||||||
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());
|
|
||||||
|
|
||||||
if (mRssi != UNKNOWN) {
|
|
||||||
sb.append(", RSSI: ").append(mRssi);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mLqi != UNKNOWN) {
|
|
||||||
sb.append(", LQI: ").append(mLqi);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mBeaconAddress != null) {
|
|
||||||
sb.append(", BeaconAddress: ").append(HexDump.toHexString(mBeaconAddress));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Integer flag : mFlags) {
|
|
||||||
switch (flag.intValue()) {
|
|
||||||
case FLAG_CAN_ASSIST:
|
|
||||||
sb.append(", CAN_ASSIST");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sb.append(", FLAG_").append(Integer.toHexString(flag));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
|
|
||||||
/** Provides detailed information about a given channel. */
|
|
||||||
//@SystemApi
|
|
||||||
public class LowpanChannelInfo {
|
|
||||||
|
|
||||||
public static final int UNKNOWN_POWER = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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 int mMaxTransmitPower = UNKNOWN_POWER;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Public Getters and Setters
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIndex() {
|
|
||||||
return mIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxTransmitPower() {
|
|
||||||
return mMaxTransmitPower;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMaskedByRegulatoryDomain() {
|
|
||||||
return mIsMaskedByRegulatoryDomain;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getSpectrumCenterFrequency() {
|
|
||||||
return mSpectrumCenterFrequency;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getSpectrumBandwidth() {
|
|
||||||
return mSpectrumBandwidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
StringBuffer sb = new StringBuffer();
|
|
||||||
|
|
||||||
sb.append("Channel ").append(mIndex);
|
|
||||||
|
|
||||||
if (mName != null) {
|
|
||||||
sb.append(" (").append(mName).append(")");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mSpectrumCenterFrequency > 0.0f) {
|
|
||||||
sb.append(", SpectrumCenterFrequency: ").append(mSpectrumCenterFrequency).append("Hz");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mSpectrumBandwidth > 0.0f) {
|
|
||||||
sb.append(", SpectrumBandwidth: ").append(mSpectrumBandwidth).append("Hz");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mMaxTransmitPower != UNKNOWN_POWER) {
|
|
||||||
sb.append(", MaxTransmitPower: ").append(mMaxTransmitPower);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,73 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.net.Network;
|
|
||||||
import android.os.Handler;
|
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Commissioning Session.
|
|
||||||
*
|
|
||||||
* <p>This class enables a device to learn the credential needed to join a network using a technique
|
|
||||||
* called "in-band commissioning".
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public abstract class LowpanCommissioningSession {
|
|
||||||
public LowpanCommissioningSession() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback base class for {@link LowpanCommissioningSession}
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public class Callback {
|
|
||||||
public void onReceiveFromCommissioner(@NonNull byte[] packet) {};
|
|
||||||
|
|
||||||
public void onClosed() {};
|
|
||||||
}
|
|
||||||
|
|
||||||
/** TODO: doc */
|
|
||||||
@NonNull
|
|
||||||
public abstract LowpanBeaconInfo getBeaconInfo();
|
|
||||||
|
|
||||||
/** TODO: doc */
|
|
||||||
public abstract void sendToCommissioner(@NonNull byte[] packet);
|
|
||||||
|
|
||||||
/** TODO: doc */
|
|
||||||
public abstract void setCallback(@Nullable Callback cb, @Nullable Handler handler);
|
|
||||||
|
|
||||||
/** TODO: doc */
|
|
||||||
public abstract void close();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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();
|
|
||||||
|
|
||||||
public abstract @Nullable Network getNetwork();
|
|
||||||
}
|
|
||||||
@@ -1,93 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes a credential for a LoWPAN network.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public class LowpanCredential {
|
|
||||||
|
|
||||||
public static final int UNSPECIFIED_KEY_INDEX = 0;
|
|
||||||
|
|
||||||
private byte[] mMasterKey = null;
|
|
||||||
private int mMasterKeyIndex = UNSPECIFIED_KEY_INDEX;
|
|
||||||
|
|
||||||
LowpanCredential() {}
|
|
||||||
|
|
||||||
private LowpanCredential(byte[] masterKey, int keyIndex) {
|
|
||||||
setMasterKey(masterKey, keyIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
private LowpanCredential(byte[] masterKey) {
|
|
||||||
setMasterKey(masterKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LowpanCredential createMasterKey(byte[] masterKey) {
|
|
||||||
return new LowpanCredential(masterKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LowpanCredential createMasterKey(byte[] masterKey, int keyIndex) {
|
|
||||||
return new LowpanCredential(masterKey, keyIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMasterKey(byte[] masterKey) {
|
|
||||||
if (masterKey != null) {
|
|
||||||
masterKey = masterKey.clone();
|
|
||||||
}
|
|
||||||
mMasterKey = masterKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMasterKeyIndex(int keyIndex) {
|
|
||||||
mMasterKeyIndex = keyIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMasterKey(byte[] masterKey, int keyIndex) {
|
|
||||||
setMasterKey(masterKey);
|
|
||||||
setMasterKeyIndex(keyIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getMasterKey() {
|
|
||||||
if (mMasterKey != null) {
|
|
||||||
return mMasterKey.clone();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMasterKeyIndex() {
|
|
||||||
return mMasterKeyIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMasterKey() {
|
|
||||||
return mMasterKey != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addToMap(Map<String, Object> parameters) throws LowpanException {
|
|
||||||
if (isMasterKey()) {
|
|
||||||
LowpanProperties.KEY_NETWORK_MASTER_KEY.putInMap(parameters, getMasterKey());
|
|
||||||
LowpanProperties.KEY_NETWORK_MASTER_KEY_INDEX.putInMap(
|
|
||||||
parameters, getMasterKeyIndex());
|
|
||||||
} else {
|
|
||||||
throw new LowpanException("Unsupported Network Credential");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the result from one channel of an energy scan.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public class LowpanEnergyScanResult {
|
|
||||||
public static final int UNKNOWN = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
private int mChannel = UNKNOWN;
|
|
||||||
private int mMaxRssi = UNKNOWN;
|
|
||||||
|
|
||||||
public LowpanEnergyScanResult() {}
|
|
||||||
|
|
||||||
public int getChannel() {
|
|
||||||
return mChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxRssi() {
|
|
||||||
return mMaxRssi;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setChannel(int x) {
|
|
||||||
mChannel = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMaxRssi(int x) {
|
|
||||||
mMaxRssi = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "LowpanEnergyScanResult(channel: " + mChannel + ", maxRssi:" + mMaxRssi + ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,290 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import android.os.DeadObjectException;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.ServiceSpecificException;
|
|
||||||
import android.util.AndroidException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <code>LowpanException</code> is thrown if an action to a LoWPAN interface could not be performed
|
|
||||||
* or a LoWPAN interface property could not be fetched or changed.
|
|
||||||
*
|
|
||||||
* @see LowpanInterface
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert ServiceSpecificExceptions and Binder RemoteExceptions from LoWPAN binder interfaces
|
|
||||||
* into the correct public exceptions.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static void throwAsPublicException(Throwable t) throws LowpanException {
|
|
||||||
if (t instanceof ServiceSpecificException) {
|
|
||||||
ServiceSpecificException e = (ServiceSpecificException) t;
|
|
||||||
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);
|
|
||||||
} else if (t instanceof DeadObjectException) {
|
|
||||||
throw new LowpanException(LOWPAN_DEAD, t);
|
|
||||||
} else if (t instanceof RemoteException) {
|
|
||||||
throw new UnsupportedOperationException(
|
|
||||||
"An unknown RemoteException was thrown" + " which should never happen.", t);
|
|
||||||
} else if (t instanceof RuntimeException) {
|
|
||||||
RuntimeException e = (RuntimeException) t;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final int mReason;
|
|
||||||
|
|
||||||
public final int getReason() {
|
|
||||||
return mReason;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LowpanException(int problem) {
|
|
||||||
super(getDefaultMessage(problem));
|
|
||||||
mReason = problem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LowpanException(String message) {
|
|
||||||
super(getCombinedMessage(LOWPAN_ERROR, message));
|
|
||||||
mReason = LOWPAN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LowpanException(int problem, String message, Throwable cause) {
|
|
||||||
super(getCombinedMessage(problem, message), cause);
|
|
||||||
mReason = problem;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LowpanException(int problem, Throwable cause) {
|
|
||||||
super(getDefaultMessage(problem), cause);
|
|
||||||
mReason = problem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
public static String getDefaultMessage(int problem) {
|
|
||||||
String problemString;
|
|
||||||
|
|
||||||
// TODO: Does this need localization?
|
|
||||||
|
|
||||||
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:
|
|
||||||
default:
|
|
||||||
problemString = "The requested LoWPAN operation failed";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,179 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import com.android.internal.util.HexDump;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes an instance of a LoWPAN network.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public class LowpanIdentity {
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Builder
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
//@SystemApi
|
|
||||||
public static class Builder {
|
|
||||||
private final LowpanIdentity identity = new LowpanIdentity();
|
|
||||||
|
|
||||||
public Builder setName(String x) {
|
|
||||||
identity.mName = x;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setXpanid(byte x[]) {
|
|
||||||
identity.mXpanid = x.clone();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setPanid(int x) {
|
|
||||||
identity.mPanid = x;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
public Builder setType(int x) {
|
|
||||||
identity.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));
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LowpanIdentity build() {
|
|
||||||
return identity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LowpanIdentity() {}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Instance Variables
|
|
||||||
|
|
||||||
private String mName = null;
|
|
||||||
private byte[] mXpanid = null;
|
|
||||||
private int mType = UNKNOWN;
|
|
||||||
private int mPanid = UNKNOWN;
|
|
||||||
private int mChannel = UNKNOWN;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Public Getters and Setters
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getXpanid() {
|
|
||||||
return mXpanid.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPanid() {
|
|
||||||
return mPanid;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
public int getType() {
|
|
||||||
return mType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getChannel() {
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (mXpanid != null) {
|
|
||||||
sb.append(", XPANID: ").append(HexDump.toHexString(mXpanid));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPanid != UNKNOWN) {
|
|
||||||
sb.append(", PANID: ").append(String.format("0x%04X", mPanid));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mChannel != UNKNOWN) {
|
|
||||||
sb.append(", Channel: ").append(mChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,824 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.net.IpPrefix;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.IBinder;
|
|
||||||
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.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
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";
|
|
||||||
|
|
||||||
/** End-device role. End devices do not route traffic for other nodes. */
|
|
||||||
public static final String ROLE_END_DEVICE = "end-device";
|
|
||||||
|
|
||||||
/** Router role. Routers help route traffic around the mesh network. */
|
|
||||||
public static final String ROLE_ROUTER = "router";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sleepy End-Device role.
|
|
||||||
*
|
|
||||||
* <p>End devices with this role are nominally asleep, waking up periodically to check in with
|
|
||||||
* their parent to see if there are packets destined for them. Such devices are capable of
|
|
||||||
* 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";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sleepy-router role.
|
|
||||||
*
|
|
||||||
* <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";
|
|
||||||
|
|
||||||
/** TODO: doc */
|
|
||||||
public static final String ROLE_LEADER = "leader";
|
|
||||||
|
|
||||||
/** TODO: doc */
|
|
||||||
public static final String ROLE_COORDINATOR = "coordinator";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Offline state.
|
|
||||||
*
|
|
||||||
* <p>This is the initial state of the LoWPAN interface when the underlying driver starts. In
|
|
||||||
* this state the NCP is idle and not connected to any network.
|
|
||||||
*
|
|
||||||
* <p>This state can be explicitly entered by calling {@link #reset()}, {@link #leave()}, or
|
|
||||||
* <code>setUp(false)</code>, with the later two only working if we were not previously in the
|
|
||||||
* {@link #STATE_FAULT} state.
|
|
||||||
*
|
|
||||||
* @see #getState()
|
|
||||||
* @see #STATE_FAULT
|
|
||||||
*/
|
|
||||||
public static final String STATE_OFFLINE = "offline";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Commissioning state.
|
|
||||||
*
|
|
||||||
* <p>The interface enters this state after a call to {@link #startCommissioningSession()}. This
|
|
||||||
* state may only be entered directly from the {@link #STATE_OFFLINE} state.
|
|
||||||
*
|
|
||||||
* @see #startCommissioningSession()
|
|
||||||
* @see #getState()
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final String STATE_COMMISSIONING = "commissioning";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attaching state.
|
|
||||||
*
|
|
||||||
* <p>The interface enters this state when it starts the process of trying to find other nodes
|
|
||||||
* so that it can attach to any pre-existing network fragment, or when it is in the process of
|
|
||||||
* calculating the optimal values for unspecified parameters when forming a new network.
|
|
||||||
*
|
|
||||||
* <p>The interface may stay in this state for a prolonged period of time (or may spontaneously
|
|
||||||
* enter this state from {@link #STATE_ATTACHED}) if the underlying network technology is
|
|
||||||
* heirarchical (like ZigBeeIP) or if the device role is that of an "end-device" ({@link
|
|
||||||
* #ROLE_END_DEVICE} or {@link #ROLE_SLEEPY_END_DEVICE}). This is because such roles cannot
|
|
||||||
* create their own network fragments.
|
|
||||||
*
|
|
||||||
* @see #STATE_ATTACHED
|
|
||||||
* @see #getState()
|
|
||||||
*/
|
|
||||||
public static final String STATE_ATTACHING = "attaching";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attached state.
|
|
||||||
*
|
|
||||||
* <p>The interface enters this state from {@link #STATE_ATTACHING} once it is actively
|
|
||||||
* participating on a network fragment.
|
|
||||||
*
|
|
||||||
* @see #STATE_ATTACHING
|
|
||||||
* @see #getState()
|
|
||||||
*/
|
|
||||||
public static final String STATE_ATTACHED = "attached";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Fault state.
|
|
||||||
*
|
|
||||||
* <p>The interface will enter this state when the driver has detected some sort of problem from
|
|
||||||
* which it was not immediately able to recover.
|
|
||||||
*
|
|
||||||
* <p>This state can be entered spontaneously from any other state. Calling {@link #reset} will
|
|
||||||
* cause the device to return to the {@link #STATE_OFFLINE} state.
|
|
||||||
*
|
|
||||||
* @see #getState
|
|
||||||
* @see #STATE_OFFLINE
|
|
||||||
*/
|
|
||||||
public static final String STATE_FAULT = "fault";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Network type for Thread 1.x networks.
|
|
||||||
*
|
|
||||||
* @see android.net.lowpan.LowpanIdentity#getType
|
|
||||||
* @see #getLowpanIdentity
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final String NETWORK_TYPE_THREAD = "org.threadgroup.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()
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback base class for LowpanInterface
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public abstract static class Callback {
|
|
||||||
public void onConnectedChanged(boolean value) {}
|
|
||||||
|
|
||||||
public void onEnabledChanged(boolean value) {}
|
|
||||||
|
|
||||||
public void onUpChanged(boolean value) {}
|
|
||||||
|
|
||||||
public void onRoleChanged(@NonNull String value) {}
|
|
||||||
|
|
||||||
public void onStateChanged(@NonNull String state) {}
|
|
||||||
|
|
||||||
public void onLowpanIdentityChanged(@NonNull LowpanIdentity value) {}
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
public void onPropertiesChanged(@NonNull Map properties) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ILowpanInterface mBinder;
|
|
||||||
private final HashMap<Integer, ILowpanInterfaceListener> mListenerMap = new HashMap<>();
|
|
||||||
|
|
||||||
/** Map between IBinder identity hashes and LowpanInstance objects. */
|
|
||||||
private static final HashMap<Integer, LowpanInterface> sInstanceMap = new HashMap<>();
|
|
||||||
|
|
||||||
private LowpanInterface(IBinder binder) {
|
|
||||||
mBinder = ILowpanInterface.Stub.asInterface(binder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the LowpanInterface object associated with this IBinder. Returns null if this IBinder
|
|
||||||
* does not implement the appropriate interface.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public static final LowpanInterface from(IBinder binder) {
|
|
||||||
Integer hashCode = Integer.valueOf(System.identityHashCode(binder));
|
|
||||||
LowpanInterface instance;
|
|
||||||
|
|
||||||
synchronized (sInstanceMap) {
|
|
||||||
instance = sInstanceMap.get(hashCode);
|
|
||||||
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new LowpanInterface(binder);
|
|
||||||
sInstanceMap.put(hashCode, instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
public static final LowpanInterface from(ILowpanInterface iface) {
|
|
||||||
return from(iface.asBinder());
|
|
||||||
}
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
public static final LowpanInterface getInterfaceFromBinder(IBinder binder) {
|
|
||||||
return from(binder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the IBinder object associated with this interface.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public IBinder getBinder() {
|
|
||||||
return mBinder.asBinder();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void throwAsPublicException(Throwable t) throws LowpanException {
|
|
||||||
LowpanException.throwAsPublicException(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Private Property Helpers
|
|
||||||
|
|
||||||
void setProperties(Map properties) throws LowpanException {
|
|
||||||
try {
|
|
||||||
mBinder.setProperties(properties);
|
|
||||||
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// Catch and ignore all binder exceptions
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
Map<String, Object> getProperties(String keys[]) throws LowpanException {
|
|
||||||
try {
|
|
||||||
return mBinder.getProperties(keys);
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// Catch and ignore all binder exceptions
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
return new HashMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @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) {
|
|
||||||
// Catch and ignore all binder exceptions
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Public Actions
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Form a new network with the given network information optional credential. Unspecified fields
|
|
||||||
* in the network information will be filled in with reasonable values. If the network
|
|
||||||
* credential is unspecified, one will be generated automatically.
|
|
||||||
*
|
|
||||||
* <p>This method will block until either the network was successfully formed or an error
|
|
||||||
* prevents the network form being formed.
|
|
||||||
*
|
|
||||||
* <p>Upon success, the interface will be up and attached to the newly formed network.
|
|
||||||
*
|
|
||||||
* @see #join(LowpanProvision)
|
|
||||||
*/
|
|
||||||
public void form(@NonNull LowpanProvision provision) throws LowpanException {
|
|
||||||
try {
|
|
||||||
Map<String, Object> parameters = new HashMap();
|
|
||||||
provision.addToMap(parameters);
|
|
||||||
mBinder.form(parameters);
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to join a new network with the given network information. This method will block
|
|
||||||
* until either the network was successfully joined or an error prevented the network from being
|
|
||||||
* formed. Upon success, the interface will be up and attached to the newly joined network.
|
|
||||||
*
|
|
||||||
* <p>Note that “joining” is distinct from “attaching”: Joining requires at least one other peer
|
|
||||||
* device to be present in order for the operation to complete successfully.
|
|
||||||
*/
|
|
||||||
public void join(@NonNull LowpanProvision provision) throws LowpanException {
|
|
||||||
try {
|
|
||||||
Map<String, Object> parameters = new HashMap();
|
|
||||||
provision.addToMap(parameters);
|
|
||||||
mBinder.join(parameters);
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attaches to the network described by identity and credential. This is similar to {@link
|
|
||||||
* #join}, except that (assuming the identity and credential are valid) it will always succeed
|
|
||||||
* and provision the interface, even if there are no peers nearby.
|
|
||||||
*
|
|
||||||
* <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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bring down the network interface and forget all non-volatile details about the current
|
|
||||||
* network.
|
|
||||||
*
|
|
||||||
* <p>This method will block execution until the operation has completed.
|
|
||||||
*/
|
|
||||||
public void leave() throws LowpanException {
|
|
||||||
try {
|
|
||||||
mBinder.leave();
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start a new commissioning session. Will fail if the interface is attached to a network or if
|
|
||||||
* the interface is disabled.
|
|
||||||
*/
|
|
||||||
public @NonNull LowpanCommissioningSession startCommissioningSession(
|
|
||||||
@NonNull LowpanBeaconInfo beaconInfo) throws LowpanException {
|
|
||||||
|
|
||||||
/* TODO: Implement startCommissioningSession */
|
|
||||||
throw new LowpanException(LowpanException.LOWPAN_FEATURE_NOT_SUPPORTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset this network interface as if it has been power cycled. Will bring the network interface
|
|
||||||
* down if it was previously up. Will not erase any non-volatile settings.
|
|
||||||
*
|
|
||||||
* <p>This method will block execution until the operation has completed.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public void reset() throws LowpanException {
|
|
||||||
try {
|
|
||||||
mBinder.reset();
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Public Getters and Setters
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the name of this network interface.
|
|
||||||
*
|
|
||||||
* <p>Will return empty string if this interface is no longer viable.
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public String getName() {
|
|
||||||
try {
|
|
||||||
return mBinder.getName();
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// Catch and ignore all binder exceptions
|
|
||||||
// when fetching the name.
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
// Catch and ignore all service-specific exceptions
|
|
||||||
// when fetching the name.
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if the interface is enabled or disabled.
|
|
||||||
*
|
|
||||||
* @see #setEnabled
|
|
||||||
* @see android.net.lowpan.LowpanException#LOWPAN_DISABLED
|
|
||||||
*/
|
|
||||||
public boolean isEnabled() {
|
|
||||||
try {
|
|
||||||
return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_ENABLED);
|
|
||||||
} catch (LowpanException x) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Enables or disables the LoWPAN interface. When disabled, the interface is put into a low-power
|
|
||||||
* state and all commands that require the NCP to be queried will fail with {@link
|
|
||||||
* android.net.lowpan.LowpanException#LOWPAN_DISABLED}.
|
|
||||||
*
|
|
||||||
* @see #isEnabled
|
|
||||||
* @see android.net.lowpan.LowpanException#LOWPAN_DISABLED
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public void setEnabled(boolean enabled) throws LowpanException {
|
|
||||||
setProperty(LowpanProperties.KEY_INTERFACE_ENABLED, enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if the network interface is up or down.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public boolean isUp() {
|
|
||||||
try {
|
|
||||||
return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_UP);
|
|
||||||
} catch (LowpanException x) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if there is at least one peer in range.
|
|
||||||
*
|
|
||||||
* @return <code>true</code> if we have at least one other peer in range, <code>false</code>
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
public boolean isConnected() {
|
|
||||||
try {
|
|
||||||
return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_CONNECTED);
|
|
||||||
} catch (LowpanException x) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if this interface is currently commissioned onto an existing network. If the
|
|
||||||
* interface is commissioned, the interface may be brought up using setUp().
|
|
||||||
*/
|
|
||||||
public boolean isCommissioned() {
|
|
||||||
try {
|
|
||||||
return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_COMMISSIONED);
|
|
||||||
} catch (LowpanException x) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get interface state
|
|
||||||
*
|
|
||||||
* <h3>State Diagram</h3>
|
|
||||||
*
|
|
||||||
* <img src="LowpanInterface-1.png" />
|
|
||||||
*
|
|
||||||
* @return The current state of the interface.
|
|
||||||
* @see #STATE_OFFLINE
|
|
||||||
* @see #STATE_COMMISSIONING
|
|
||||||
* @see #STATE_ATTACHING
|
|
||||||
* @see #STATE_ATTACHED
|
|
||||||
* @see #STATE_FAULT
|
|
||||||
*/
|
|
||||||
public String getState() {
|
|
||||||
try {
|
|
||||||
return getProperty(LowpanProperties.KEY_INTERFACE_STATE);
|
|
||||||
} catch (LowpanException x) {
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
return STATE_FAULT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 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 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (role == null) {
|
|
||||||
role = ROLE_DETACHED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** TODO: doc */
|
|
||||||
@Nullable
|
|
||||||
public LowpanCredential getLowpanCredential() {
|
|
||||||
LowpanCredential credential = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Integer keyIndex = getProperty(LowpanProperties.KEY_NETWORK_MASTER_KEY_INDEX);
|
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
return credential;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: doc
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public void setLowpanCredential(LowpanCredential networkCredential) throws LowpanException {
|
|
||||||
Map<String, Object> map = new HashMap();
|
|
||||||
networkCredential.addToMap(map);
|
|
||||||
setProperties(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Listener Support
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a subclass of {@link LowpanInterface.Callback} to receive events.
|
|
||||||
*
|
|
||||||
* @param cb Subclass of {@link LowpanInterface.Callback} which will receive events.
|
|
||||||
* @param handler If not <code>null</code>, events will be dispatched via the given handler
|
|
||||||
* object. If <code>null</code>, the thread upon which events will be dispatched is
|
|
||||||
* unspecified.
|
|
||||||
* @see #registerCallback(Callback)
|
|
||||||
* @see #unregisterCallback(Callback)
|
|
||||||
*/
|
|
||||||
public void registerCallback(@NonNull Callback cb, @Nullable Handler handler) {
|
|
||||||
ILowpanInterfaceListener.Stub listenerBinder =
|
|
||||||
new ILowpanInterfaceListener.Stub() {
|
|
||||||
public void onPropertiesChanged(Map<String, Object> properties) {
|
|
||||||
Runnable runnable =
|
|
||||||
new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (handler != null) {
|
|
||||||
handler.post(runnable);
|
|
||||||
} else {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
mBinder.addListener(listenerBinder);
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// Log and ignore. If this happens, this interface
|
|
||||||
// is likely dead anyway.
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
}
|
|
||||||
synchronized (mListenerMap) {
|
|
||||||
mListenerMap.put(System.identityHashCode(cb), listenerBinder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a subclass of {@link LowpanInterface.Callback} to receive events.
|
|
||||||
*
|
|
||||||
* <p>The thread upon which events will be dispatched is unspecified.
|
|
||||||
*
|
|
||||||
* @param cb Subclass of {@link LowpanInterface.Callback} which will receive events.
|
|
||||||
* @see #registerCallback(Callback, Handler)
|
|
||||||
* @see #unregisterCallback(Callback)
|
|
||||||
*/
|
|
||||||
public void registerCallback(Callback cb) {
|
|
||||||
registerCallback(cb, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregisters a previously registered callback class.
|
|
||||||
*
|
|
||||||
* @param cb Subclass of {@link LowpanInterface.Callback} which was previously registered to
|
|
||||||
* receive events.
|
|
||||||
* @see #registerCallback(Callback, Handler)
|
|
||||||
* @see #registerCallback(Callback)
|
|
||||||
*/
|
|
||||||
public void unregisterCallback(Callback cb) {
|
|
||||||
int hashCode = System.identityHashCode(cb);
|
|
||||||
ILowpanInterfaceListener listenerBinder = mListenerMap.get(hashCode);
|
|
||||||
|
|
||||||
if (listenerBinder != null) {
|
|
||||||
synchronized (mListenerMap) {
|
|
||||||
mListenerMap.remove(hashCode);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
mBinder.removeListener(listenerBinder);
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// Catch and ignore all binder exceptions
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Active and Passive Scanning
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link android.net.lowpan.LowpanScanner} object for this interface.
|
|
||||||
*
|
|
||||||
* <p>This method allocates a new unique object for each call.
|
|
||||||
*
|
|
||||||
* @see android.net.lowpan.LowpanScanner
|
|
||||||
*/
|
|
||||||
public @NonNull LowpanScanner createScanner() {
|
|
||||||
return new LowpanScanner(mBinder);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Route Management
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advertise the given IP prefix as an on-mesh prefix.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public void addOnMeshPrefix(IpPrefix prefix, int flags) throws LowpanException {
|
|
||||||
try {
|
|
||||||
mBinder.addOnMeshPrefix(prefix, flags);
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove an IP prefix previously advertised by this device from the list of advertised on-mesh
|
|
||||||
* prefixes.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public void removeOnMeshPrefix(IpPrefix prefix) {
|
|
||||||
try {
|
|
||||||
mBinder.removeOnMeshPrefix(prefix);
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// Catch and ignore all binder exceptions
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
// Catch and ignore all service exceptions
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advertise this device to other devices on the mesh network as having a specific route to the
|
|
||||||
* given network. This device will then receive forwarded traffic for that network.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public void addExternalRoute(IpPrefix prefix, int flags) throws LowpanException {
|
|
||||||
try {
|
|
||||||
mBinder.addExternalRoute(prefix, flags);
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Revoke a previously advertised specific route to the given network.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public void removeExternalRoute(IpPrefix prefix) {
|
|
||||||
try {
|
|
||||||
mBinder.removeExternalRoute(prefix);
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// Catch and ignore all binder exceptions
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
// Catch and ignore all service exceptions
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,283 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.DeadObjectException;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.os.ServiceManager;
|
|
||||||
import android.util.AndroidException;
|
|
||||||
import android.util.Log;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manager object for looking up LoWPAN interfaces.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public class LowpanManager {
|
|
||||||
private static final String TAG = LowpanManager.class.getSimpleName();
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Public Classes
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
//@SystemApi
|
|
||||||
public abstract static class Callback {
|
|
||||||
public void onInterfaceAdded(LowpanInterface lowpan_interface) {}
|
|
||||||
|
|
||||||
public void onInterfaceRemoved(LowpanInterface lowpan_interface) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Instance Variables
|
|
||||||
|
|
||||||
private ILowpanManager mManager;
|
|
||||||
private HashMap<Integer, ILowpanManagerListener> mListenerMap = new HashMap<>();
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
private static LowpanManager sSingletonInstance;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Static Methods
|
|
||||||
|
|
||||||
/** Returns a reference to the LowpanManager object, allocating it if necessary. */
|
|
||||||
public static LowpanManager getManager() {
|
|
||||||
return from(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LowpanManager from(Context context) {
|
|
||||||
// TODO: Actually get this from the context!
|
|
||||||
|
|
||||||
if (sSingletonInstance == null) {
|
|
||||||
sSingletonInstance = new LowpanManager();
|
|
||||||
}
|
|
||||||
return sSingletonInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private LowpanManager constructor. Since we are a singleton, we do not allow external
|
|
||||||
* construction.
|
|
||||||
*/
|
|
||||||
private LowpanManager() {}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Private Methods
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a reference to the ILowpanManager interface, provided by the LoWPAN Manager Service.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
private ILowpanManager getILowpanManager() {
|
|
||||||
ILowpanManager manager = mManager;
|
|
||||||
if (manager == null) {
|
|
||||||
IBinder serviceBinder =
|
|
||||||
new ServiceManager().getService(ILowpanManager.LOWPAN_SERVICE_NAME);
|
|
||||||
mManager = manager = ILowpanManager.Stub.asInterface(serviceBinder);
|
|
||||||
|
|
||||||
// Add any listeners
|
|
||||||
synchronized (mListenerMap) {
|
|
||||||
for (Integer hashObj : mListenerMap.keySet()) {
|
|
||||||
try {
|
|
||||||
manager.addListener(mListenerMap.get(hashObj));
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// Consider any failure here as implying the manager is defunct
|
|
||||||
mManager = manager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Public Methods
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a reference to the requested LowpanInterface object. If the given interface doesn't
|
|
||||||
* exist, or it is not a LoWPAN interface, returns null.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public LowpanInterface getInterface(@NonNull String name) {
|
|
||||||
LowpanInterface ret = null;
|
|
||||||
ILowpanManager manager = getILowpanManager();
|
|
||||||
|
|
||||||
// Maximum number of tries is two. We should only try
|
|
||||||
// more than once if our manager has died or there
|
|
||||||
// was some sort of AIDL buffer full event.
|
|
||||||
for (int i = 0; i < 2 && manager != null; i++) {
|
|
||||||
try {
|
|
||||||
ILowpanInterface iface = manager.getInterface(name);
|
|
||||||
if (iface != null) {
|
|
||||||
ret = LowpanInterface.getInterfaceFromBinder(iface.asBinder());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// In all of the cases when we get this exception, we reconnect and try again
|
|
||||||
mManager = null;
|
|
||||||
manager = getILowpanManager();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a reference to the first registered LowpanInterface object. If there are no LoWPAN
|
|
||||||
* interfaces registered, returns null.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
public LowpanInterface getInterface() {
|
|
||||||
String[] ifaceList = getInterfaceList();
|
|
||||||
if (ifaceList != null && ifaceList.length > 0) {
|
|
||||||
return getInterface(ifaceList[0]);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string array containing the names of LoWPAN interfaces. This list may contain fewer
|
|
||||||
* interfaces if the calling process does not have permissions to see individual interfaces.
|
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public String[] getInterfaceList() {
|
|
||||||
ILowpanManager manager = getILowpanManager();
|
|
||||||
|
|
||||||
if (manager != null) {
|
|
||||||
try {
|
|
||||||
return manager.getInterfaceList();
|
|
||||||
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// In all of the cases when we get this exception, we reconnect and try again
|
|
||||||
mManager = null;
|
|
||||||
try {
|
|
||||||
manager = getILowpanManager();
|
|
||||||
if (manager != null) {
|
|
||||||
return manager.getInterfaceList();
|
|
||||||
}
|
|
||||||
} catch (RemoteException ex) {
|
|
||||||
// Something weird is going on, so we log it
|
|
||||||
// and fall back thru to returning an empty array.
|
|
||||||
Log.e(TAG, ex.toString());
|
|
||||||
mManager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return empty list if we have no service.
|
|
||||||
return new String[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a callback object to receive notifications when LoWPAN interfaces are added or
|
|
||||||
* removed.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public void registerCallback(@NonNull Callback cb, @Nullable Handler handler)
|
|
||||||
throws LowpanException {
|
|
||||||
ILowpanManagerListener.Stub listenerBinder =
|
|
||||||
new ILowpanManagerListener.Stub() {
|
|
||||||
public void onInterfaceAdded(ILowpanInterface lowpan_interface) {
|
|
||||||
Runnable runnable =
|
|
||||||
new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
cb.onInterfaceAdded(
|
|
||||||
LowpanInterface.getInterfaceFromBinder(
|
|
||||||
lowpan_interface.asBinder()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (handler != null) {
|
|
||||||
handler.post(runnable);
|
|
||||||
} else {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onInterfaceRemoved(ILowpanInterface lowpan_interface) {
|
|
||||||
Runnable runnable =
|
|
||||||
new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
cb.onInterfaceRemoved(
|
|
||||||
LowpanInterface.getInterfaceFromBinder(
|
|
||||||
lowpan_interface.asBinder()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (handler != null) {
|
|
||||||
handler.post(runnable);
|
|
||||||
} else {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
ILowpanManager manager = getILowpanManager();
|
|
||||||
if (manager != null) {
|
|
||||||
try {
|
|
||||||
manager.addListener(listenerBinder);
|
|
||||||
} catch (DeadObjectException x) {
|
|
||||||
mManager = null;
|
|
||||||
// Tickle the ILowpanManager instance, which might
|
|
||||||
// get us added back.
|
|
||||||
getILowpanManager();
|
|
||||||
} catch (Throwable x) {
|
|
||||||
LowpanException.throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
synchronized (mListenerMap) {
|
|
||||||
mListenerMap.put(Integer.valueOf(System.identityHashCode(cb)), listenerBinder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
public void registerCallback(@NonNull Callback cb) throws LowpanException {
|
|
||||||
registerCallback(cb, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregisters a previously registered {@link LowpanManager.Callback} object.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public void unregisterCallback(@NonNull Callback cb) throws AndroidException {
|
|
||||||
Integer hashCode = Integer.valueOf(System.identityHashCode(cb));
|
|
||||||
ILowpanManagerListener listenerBinder = mListenerMap.get(hashCode);
|
|
||||||
if (listenerBinder != null) {
|
|
||||||
synchronized (mListenerMap) {
|
|
||||||
mListenerMap.remove(hashCode);
|
|
||||||
}
|
|
||||||
if (getILowpanManager() != null) {
|
|
||||||
try {
|
|
||||||
mManager.removeListener(listenerBinder);
|
|
||||||
} catch (DeadObjectException x) {
|
|
||||||
mManager = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,125 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import android.net.LinkAddress;
|
|
||||||
import android.net.RouteInfo;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/** {@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);
|
|
||||||
|
|
||||||
public static final LowpanProperty<List<LinkAddress>> KEY_LINK_ADDRESS_ARRAY =
|
|
||||||
new LowpanStandardProperty(
|
|
||||||
"android.net.lowpan.property.LINK_ADDRESS_ARRAY", LinkAddress[].class);
|
|
||||||
|
|
||||||
public static final LowpanProperty<List<RouteInfo>> KEY_ROUTE_INFO_ARRAY =
|
|
||||||
new LowpanStandardProperty(
|
|
||||||
"android.net.lowpan.property.ROUTE_INFO_ARRAY", RouteInfo[].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() {}
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
static final class LowpanStandardProperty<T> extends LowpanProperty<T> {
|
|
||||||
private final String mName;
|
|
||||||
private final Class<T> mType;
|
|
||||||
|
|
||||||
LowpanStandardProperty(String name, Class<T> type) {
|
|
||||||
mName = name;
|
|
||||||
mType = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<T> getType() {
|
|
||||||
return mType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/** {@hide} */
|
|
||||||
public abstract class LowpanProperty<T> {
|
|
||||||
public abstract String getName();
|
|
||||||
|
|
||||||
public abstract Class<T> getType();
|
|
||||||
|
|
||||||
public void putInMap(Map map, T value) {
|
|
||||||
map.put(getName(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getFromMap(Map map) {
|
|
||||||
return (T) map.get(getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,104 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
import android.annotation.Nullable;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Describes the information needed to describe a network
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public class LowpanProvision {
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Builder
|
|
||||||
|
|
||||||
/** @hide */
|
|
||||||
//@SystemApi
|
|
||||||
public static class Builder {
|
|
||||||
private final LowpanProvision provision = new LowpanProvision();
|
|
||||||
|
|
||||||
public Builder setLowpanIdentity(@NonNull LowpanIdentity identity) {
|
|
||||||
provision.mIdentity = identity;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder setLowpanCredential(@NonNull LowpanCredential credential) {
|
|
||||||
provision.mCredential = credential;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LowpanProvision build() {
|
|
||||||
return provision;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private LowpanProvision() {}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Instance Variables
|
|
||||||
|
|
||||||
private LowpanIdentity mIdentity = new LowpanIdentity();
|
|
||||||
private LowpanCredential mCredential = null;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Public Getters and Setters
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public LowpanIdentity getLowpanIdentity() {
|
|
||||||
return mIdentity;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public LowpanCredential getLowpanCredential() {
|
|
||||||
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();
|
|
||||||
|
|
||||||
sb.append("LowpanProvision { identity => ").append(mIdentity.toString());
|
|
||||||
|
|
||||||
if (mCredential != null) {
|
|
||||||
sb.append(", credential: ").append(mCredential.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
sb.append("}");
|
|
||||||
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,317 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package android.net.lowpan;
|
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
|
||||||
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;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* LoWPAN Scanner
|
|
||||||
*
|
|
||||||
* <p>This class allows performing network (active) scans and energy (passive) scans.
|
|
||||||
*
|
|
||||||
* @see LowpanInterface
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public class LowpanScanner {
|
|
||||||
private static final String TAG = LowpanInterface.class.getSimpleName();
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Public Classes
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback base class for LowpanScanner
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
//@SystemApi
|
|
||||||
public abstract static class Callback {
|
|
||||||
public void onNetScanBeacon(LowpanBeaconInfo beacon) {}
|
|
||||||
|
|
||||||
public void onEnergyScanResult(LowpanEnergyScanResult result) {}
|
|
||||||
|
|
||||||
public void onScanFinished() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Instance Variables
|
|
||||||
|
|
||||||
private ILowpanInterface mBinder;
|
|
||||||
private Callback mCallback = null;
|
|
||||||
private Handler mHandler = null;
|
|
||||||
private List<Integer> mChannelMask = null;
|
|
||||||
private int mTxPower = Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Constructors/Accessors and Exception Glue
|
|
||||||
|
|
||||||
LowpanScanner(@NonNull ILowpanInterface binder) {
|
|
||||||
mBinder = binder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets an instance of {@link LowpanScanner.Callback} to receive events. */
|
|
||||||
public void setCallback(@Nullable Callback cb, @Nullable Handler handler) {
|
|
||||||
mCallback = cb;
|
|
||||||
mHandler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sets an instance of {@link LowpanScanner.Callback} to receive events. */
|
|
||||||
public void setCallback(@Nullable Callback cb) {
|
|
||||||
setCallback(cb, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the channel mask to use when scanning.
|
|
||||||
*
|
|
||||||
* @param mask The channel mask to use when scanning. If <code>null</code>, any previously set
|
|
||||||
* channel mask will be cleared and all channels not masked by the current regulatory zone
|
|
||||||
* will be scanned.
|
|
||||||
*/
|
|
||||||
public void setChannelMask(@Nullable Collection<Integer> mask) {
|
|
||||||
if (mask == null) {
|
|
||||||
mChannelMask = null;
|
|
||||||
} else {
|
|
||||||
if (mChannelMask == null) {
|
|
||||||
mChannelMask = new ArrayList<>();
|
|
||||||
} else {
|
|
||||||
mChannelMask.clear();
|
|
||||||
}
|
|
||||||
mChannelMask.addAll(mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the current channel mask.
|
|
||||||
*
|
|
||||||
* @return the current channel mask, or <code>null</code> if no channel mask is currently set.
|
|
||||||
*/
|
|
||||||
public @Nullable Collection<Integer> getChannelMask() {
|
|
||||||
return mChannelMask.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a channel to the channel mask used for scanning.
|
|
||||||
*
|
|
||||||
* <p>If a channel mask was previously <code>null</code>, a new one is created containing only
|
|
||||||
* this channel. May be called multiple times to add additional channels ot the channel mask.
|
|
||||||
*
|
|
||||||
* @see #setChannelMask
|
|
||||||
* @see #getChannelMask
|
|
||||||
* @see #getTxPower
|
|
||||||
*/
|
|
||||||
public void addChannel(int channel) {
|
|
||||||
if (mChannelMask == null) {
|
|
||||||
mChannelMask = new ArrayList<>();
|
|
||||||
}
|
|
||||||
mChannelMask.add(Integer.valueOf(channel));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the maximum transmit power to be used for active scanning.
|
|
||||||
*
|
|
||||||
* <p>The actual transmit power used is the lesser of this value and the currently configured
|
|
||||||
* maximum transmit power for the interface.
|
|
||||||
*
|
|
||||||
* @see #getTxPower
|
|
||||||
*/
|
|
||||||
public void setTxPower(int txPower) {
|
|
||||||
mTxPower = txPower;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the maximum transmit power used for active scanning.
|
|
||||||
*
|
|
||||||
* @see #setTxPower
|
|
||||||
*/
|
|
||||||
public int getTxPower() {
|
|
||||||
return mTxPower;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, Object> createScanOptionMap() {
|
|
||||||
Map<String, Object> map = new HashMap();
|
|
||||||
|
|
||||||
if (mChannelMask != null) {
|
|
||||||
LowpanProperties.KEY_CHANNEL_MASK.putInMap(
|
|
||||||
map, mChannelMask.stream().mapToInt(i -> i).toArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mTxPower != Integer.MAX_VALUE) {
|
|
||||||
LowpanProperties.KEY_MAX_TX_POWER.putInMap(map, Integer.valueOf(mTxPower));
|
|
||||||
}
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start a network scan.
|
|
||||||
*
|
|
||||||
* <p>This method will return once the scan has started.
|
|
||||||
*
|
|
||||||
* @see #stopNetScan
|
|
||||||
*/
|
|
||||||
public void startNetScan() throws LowpanException {
|
|
||||||
Map<String, Object> map = createScanOptionMap();
|
|
||||||
|
|
||||||
ILowpanNetScanCallback binderListener =
|
|
||||||
new ILowpanNetScanCallback.Stub() {
|
|
||||||
public void onNetScanBeacon(Map parameters) {
|
|
||||||
Callback callback = mCallback;
|
|
||||||
Handler handler = mHandler;
|
|
||||||
|
|
||||||
if (callback == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Runnable runnable = () -> callback.onNetScanBeacon(
|
|
||||||
new LowpanBeaconInfo.Builder()
|
|
||||||
.updateFromMap(parameters)
|
|
||||||
.build());
|
|
||||||
|
|
||||||
if (handler != null) {
|
|
||||||
handler.post(runnable);
|
|
||||||
} else {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onNetScanFinished() {
|
|
||||||
Callback callback = mCallback;
|
|
||||||
Handler handler = mHandler;
|
|
||||||
|
|
||||||
if (callback == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Runnable runnable = () -> callback.onScanFinished();
|
|
||||||
|
|
||||||
if (handler != null) {
|
|
||||||
handler.post(runnable);
|
|
||||||
} else {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
mBinder.startNetScan(map, binderListener);
|
|
||||||
} catch (ServiceSpecificException|RemoteException x) {
|
|
||||||
LowpanException.throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop a network scan currently in progress.
|
|
||||||
*
|
|
||||||
* @see #startNetScan
|
|
||||||
*/
|
|
||||||
public void stopNetScan() {
|
|
||||||
try {
|
|
||||||
mBinder.stopNetScan();
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// Catch and ignore all binder exceptions
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start an energy scan.
|
|
||||||
*
|
|
||||||
* <p>This method will return once the scan has started.
|
|
||||||
*
|
|
||||||
* @see #stopEnergyScan
|
|
||||||
*/
|
|
||||||
public void startEnergyScan() throws LowpanException {
|
|
||||||
Map<String, Object> map = createScanOptionMap();
|
|
||||||
|
|
||||||
ILowpanEnergyScanCallback binderListener =
|
|
||||||
new ILowpanEnergyScanCallback.Stub() {
|
|
||||||
public void onEnergyScanResult(int channel, int rssi) {
|
|
||||||
Callback callback = mCallback;
|
|
||||||
Handler handler = mHandler;
|
|
||||||
|
|
||||||
if (callback == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Runnable runnable = () -> {
|
|
||||||
if (callback != null) {
|
|
||||||
LowpanEnergyScanResult result =
|
|
||||||
new LowpanEnergyScanResult();
|
|
||||||
result.setChannel(channel);
|
|
||||||
result.setMaxRssi(rssi);
|
|
||||||
callback.onEnergyScanResult(result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (handler != null) {
|
|
||||||
handler.post(runnable);
|
|
||||||
} else {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onEnergyScanFinished() {
|
|
||||||
Callback callback = mCallback;
|
|
||||||
Handler handler = mHandler;
|
|
||||||
|
|
||||||
if (callback == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Runnable runnable = () -> callback.onScanFinished();
|
|
||||||
|
|
||||||
if (handler != null) {
|
|
||||||
handler.post(runnable);
|
|
||||||
} else {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
mBinder.startEnergyScan(map, binderListener);
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
LowpanException.throwAsPublicException(x);
|
|
||||||
} catch (ServiceSpecificException x) {
|
|
||||||
LowpanException.throwAsPublicException(x);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop an energy scan currently in progress.
|
|
||||||
*
|
|
||||||
* @see #startEnergyScan
|
|
||||||
*/
|
|
||||||
public void stopEnergyScan() {
|
|
||||||
try {
|
|
||||||
mBinder.stopEnergyScan();
|
|
||||||
} catch (RemoteException x) {
|
|
||||||
// Catch and ignore all binder exceptions
|
|
||||||
Log.e(TAG, x.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
<HTML>
|
|
||||||
<BODY>
|
|
||||||
<p>@SystemApi</p>
|
|
||||||
<!-- @hide -->
|
|
||||||
<p>Provides classes to manage Low-power Wireless Personal Area Network (LoWPAN) functionality on the device.
|
|
||||||
Examples of such network technologies include <a href="http://threadgroup.org/">Thread</a> and
|
|
||||||
<a href="http://www.zigbee.org/zigbee-for-developers/network-specifications/zigbeeip/">ZigBee IP</a>.</p>
|
|
||||||
<p>The LoWPAN APIs provide a means by which applications can communicate
|
|
||||||
with the lower-level wireless stack that provides LoWPAN network access.</p>
|
|
||||||
|
|
||||||
<p>Some APIs may require the following user permissions:</p>
|
|
||||||
<ul>
|
|
||||||
<li>{@link android.Manifest.permission#ACCESS_LOWPAN_STATE}</li>
|
|
||||||
<li>{@link android.Manifest.permission#CHANGE_LOWPAN_STATE}</li>
|
|
||||||
<li>TBD</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p class="note"><strong>Note:</strong> Not all Android-powered devices provide LoWPAN functionality.
|
|
||||||
If your application uses these APIs, declare so with a <a
|
|
||||||
href="{@docRoot}guide/topics/manifest/uses-feature-element.html">{@code <uses-feature>}</a>
|
|
||||||
element in the manifest file:</p>
|
|
||||||
<pre>
|
|
||||||
<manifest ...>
|
|
||||||
<uses-feature android:name="android.hardware.lowpan" />
|
|
||||||
...
|
|
||||||
</manifest>
|
|
||||||
</pre>
|
|
||||||
</BODY>
|
|
||||||
</HTML>
|
|
||||||
Reference in New Issue
Block a user