Initial support for proposed android.net.lowpan
Change-Id: I0bf8edb5199d50d2a549a353b2785aef8134ff92
This commit is contained in:
@@ -558,6 +558,15 @@ LOCAL_SRC_FILES += \
|
||||
|
||||
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
|
||||
LOCAL_AIDL_INCLUDES += \
|
||||
$(FRAMEWORKS_BASE_JAVA_SRC_DIRS) \
|
||||
|
||||
@@ -1322,6 +1322,27 @@
|
||||
<permission android:name="android.permission.NETWORK_SETTINGS"
|
||||
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 -->
|
||||
<!-- ======================================= -->
|
||||
|
||||
31
lowpan/Android.mk
Normal file
31
lowpan/Android.mk
Normal file
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# 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
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
154
lowpan/java/android/net/lowpan/ILowpanInterface.aidl
Normal file
154
lowpan/java/android/net/lowpan/ILowpanInterface.aidl
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
22
lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl
Normal file
22
lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
35
lowpan/java/android/net/lowpan/ILowpanManager.aidl
Normal file
35
lowpan/java/android/net/lowpan/ILowpanManager.aidl
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
25
lowpan/java/android/net/lowpan/ILowpanManagerListener.aidl
Normal file
25
lowpan/java/android/net/lowpan/ILowpanManagerListener.aidl
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
23
lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl
Normal file
23
lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
150
lowpan/java/android/net/lowpan/LowpanBeaconInfo.java
Normal file
150
lowpan/java/android/net/lowpan/LowpanBeaconInfo.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
87
lowpan/java/android/net/lowpan/LowpanChannelInfo.java
Normal file
87
lowpan/java/android/net/lowpan/LowpanChannelInfo.java
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
93
lowpan/java/android/net/lowpan/LowpanCredential.java
Normal file
93
lowpan/java/android/net/lowpan/LowpanCredential.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
54
lowpan/java/android/net/lowpan/LowpanEnergyScanResult.java
Normal file
54
lowpan/java/android/net/lowpan/LowpanEnergyScanResult.java
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 + ")";
|
||||
}
|
||||
}
|
||||
290
lowpan/java/android/net/lowpan/LowpanException.java
Normal file
290
lowpan/java/android/net/lowpan/LowpanException.java
Normal file
@@ -0,0 +1,290 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
179
lowpan/java/android/net/lowpan/LowpanIdentity.java
Normal file
179
lowpan/java/android/net/lowpan/LowpanIdentity.java
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
824
lowpan/java/android/net/lowpan/LowpanInterface.java
Normal file
824
lowpan/java/android/net/lowpan/LowpanInterface.java
Normal file
@@ -0,0 +1,824 @@
|
||||
/*
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
283
lowpan/java/android/net/lowpan/LowpanManager.java
Normal file
283
lowpan/java/android/net/lowpan/LowpanManager.java
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
125
lowpan/java/android/net/lowpan/LowpanProperties.java
Normal file
125
lowpan/java/android/net/lowpan/LowpanProperties.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
34
lowpan/java/android/net/lowpan/LowpanProperty.java
Normal file
34
lowpan/java/android/net/lowpan/LowpanProperty.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
104
lowpan/java/android/net/lowpan/LowpanProvision.java
Normal file
104
lowpan/java/android/net/lowpan/LowpanProvision.java
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
};
|
||||
317
lowpan/java/android/net/lowpan/LowpanScanner.java
Normal file
317
lowpan/java/android/net/lowpan/LowpanScanner.java
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
29
lowpan/java/android/net/lowpan/package.html
Normal file
29
lowpan/java/android/net/lowpan/package.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<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