summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-07-19 07:24:14 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-07-19 07:24:14 +0000
commit8c221ccd4b43cd66ba9747b864e71fb38c4da517 (patch)
tree5784aaa8c9f07b7559c69d667ebdc63fc69242f6
parentffc04990533192ead6ac903ce5b4a3c6e97a3031 (diff)
parentd38415634a6e0d2175e888618a6ebc52dfcb861e (diff)
downloadlowpan-8c221ccd4b43cd66ba9747b864e71fb38c4da517.tar.gz
release-request-bd6aa7dd-7b02-4794-942c-14599bf61208-for-git_oc-mr1-release-4193791 snap-temp-L98700000083613807
Change-Id: Ida2b0899cc054ba49367c8a96801f04fb8aff827
-rw-r--r--.gitattributes2
-rw-r--r--command/java/com/android/commands/lowpan/LowpanCtl.java180
-rw-r--r--libandroid_net_lowpan/Android.mk33
-rw-r--r--libandroid_net_lowpan/LowpanBeaconInfo.cpp218
-rw-r--r--libandroid_net_lowpan/LowpanChannelInfo.cpp114
-rw-r--r--libandroid_net_lowpan/LowpanCredential.cpp149
-rw-r--r--libandroid_net_lowpan/LowpanIdentity.cpp189
-rw-r--r--libandroid_net_lowpan/LowpanProvision.cpp121
-rw-r--r--libandroid_net_lowpan/include/android/net/lowpan/LowpanBeaconInfo.h101
-rw-r--r--libandroid_net_lowpan/include/android/net/lowpan/LowpanChannelInfo.h64
-rw-r--r--libandroid_net_lowpan/include/android/net/lowpan/LowpanCredential.h72
-rw-r--r--libandroid_net_lowpan/include/android/net/lowpan/LowpanIdentity.h90
-rw-r--r--libandroid_net_lowpan/include/android/net/lowpan/LowpanProvision.h69
-rw-r--r--service/java/com/android/server/lowpan/LowpanInterfaceTracker.java96
-rw-r--r--service/java/com/android/server/lowpan/LowpanServiceImpl.java22
15 files changed, 1399 insertions, 121 deletions
diff --git a/.gitattributes b/.gitattributes
index f0600ce..bc24d41 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,5 @@
*.java text whitespace=trailing-space,tab-in-indent,tabwidth=4,blank-at-eol,blank-at-eof
+*.cpp text whitespace=trailing-space,tab-in-indent,tabwidth=4,blank-at-eol,blank-at-eof
+*.h text whitespace=trailing-space,tab-in-indent,tabwidth=4,blank-at-eol,blank-at-eof
*.aidl text whitespace=trailing-space,tab-in-indent,tabwidth=4,blank-at-eol,blank-at-eof
*.xml text whitespace=trailing-space,tab-in-indent,tabwidth=4,blank-at-eol,blank-at-eof
diff --git a/command/java/com/android/commands/lowpan/LowpanCtl.java b/command/java/com/android/commands/lowpan/LowpanCtl.java
index e23c094..8e36841 100644
--- a/command/java/com/android/commands/lowpan/LowpanCtl.java
+++ b/command/java/com/android/commands/lowpan/LowpanCtl.java
@@ -26,7 +26,7 @@ import android.net.lowpan.LowpanInterface;
import android.net.lowpan.LowpanManager;
import android.net.lowpan.LowpanProvision;
import android.net.lowpan.LowpanScanner;
-import android.os.IBinder;
+import android.net.LinkAddress;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.util.AndroidRuntimeException;
@@ -57,18 +57,35 @@ public class LowpanCtl extends BaseCommand {
public void onShowUsage(PrintStream out) {
out.println(
"usage: lowpanctl [options] [subcommand] [subcommand-options]\n"
+ + "options:\n"
+ + " -I / --interface <iface-name> ..... Interface Name\n"
+ + "subcommands:\n"
+ " lowpanctl status\n"
+ " lowpanctl form\n"
+ " lowpanctl join\n"
+ + " lowpanctl attach\n"
+ " lowpanctl leave\n"
- + " lowpanctl up\n"
- + " lowpanctl down\n"
- + " lowpanctl get [property-name]\n"
- + " lowpanctl set [property-name]\n"
+ + " lowpanctl enable\n"
+ + " lowpanctl disable\n"
+ + " lowpanctl show-credential\n"
+ " lowpanctl scan\n"
+ " lowpanctl reset\n"
+ " lowpanctl list\n"
+ + "\n"
+ + "usage: lowpanctl [options] join/form/attach [network-name]\n"
+ + "subcommand-options:\n"
+ + " --name <network-name> ............. Network Name\n"
+ + " -p / --panid <panid> .............. PANID\n"
+ + " -c / --channel <channel> .......... Channel Index\n"
+ + " -x / --xpanid <xpanid> ............ XPANID\n"
+ + " -k / --master-key <master-key> .... Master Key\n"
+ + " --master-key-index <key-index> .... Key Index\n"
+ + "\n"
+ + "usage: lowpanctl [options] show-credential\n"
+ + "subcommand-options:\n"
+ + " -r / --raw ........................ Print only key contents\n"
+ "\n");
+
}
private class CommandErrorException extends AndroidRuntimeException {
@@ -129,11 +146,17 @@ public class LowpanCtl extends BaseCommand {
} else if (op.equals("scan") || op.equals("netscan") || op.equals("ns")) {
runNetScan();
break;
- } else if (op.equals("attach") || op.equals("up")) {
+ } else if (op.equals("attach")) {
runAttach();
break;
- } else if (op.equals("detach") || op.equals("down")) {
- runDetach();
+ } else if (op.equals("enable")) {
+ runEnable();
+ break;
+ } else if (op.equals("disable")) {
+ runDisable();
+ break;
+ } else if (op.equals("show-credential")) {
+ runShowCredential();
break;
} else if (op.equals("join")) {
runJoin();
@@ -144,12 +167,6 @@ public class LowpanCtl extends BaseCommand {
} else if (op.equals("leave")) {
runLeave();
break;
- } else if (op.equals("get") || op.equals("getprop")) {
- runGetProp();
- break;
- } else if (op.equals("set") || op.equals("setprop")) {
- runSetProp();
- break;
} else if (op.equals("energyscan") || op.equals("energy") || op.equals("es")) {
runEnergyScan();
break;
@@ -176,6 +193,14 @@ public class LowpanCtl extends BaseCommand {
getLowpanInterface().reset();
}
+ private void runEnable() throws LowpanException {
+ getLowpanInterface().setEnabled(true);
+ }
+
+ private void runDisable() throws LowpanException {
+ getLowpanInterface().setEnabled(false);
+ }
+
private LowpanProvision getProvisionFromArgs(boolean credentialRequired) {
LowpanProvision.Builder builder = new LowpanProvision.Builder();
Map<String, Object> properties = new HashMap();
@@ -200,6 +225,8 @@ public class LowpanCtl extends BaseCommand {
masterKey = HexDump.hexStringToByteArray(nextArgRequired());
} else if (arg.equals("--master-key-index")) {
masterKeyIndex = Integer.decode(nextArgRequired());
+ } else if (arg.equals("--help")) {
+ throwCommandError("");
} else if (arg.startsWith("-") || hasName) {
throwCommandError("Unrecognized argument \"" + arg + "\"");
} else {
@@ -237,10 +264,6 @@ public class LowpanCtl extends BaseCommand {
System.out.println("Attached.");
}
- private void runDetach() throws LowpanException {
- getLowpanInterface().setUp(false);
- }
-
private void runLeave() throws LowpanException {
getLowpanInterface().leave();
}
@@ -262,10 +285,10 @@ public class LowpanCtl extends BaseCommand {
if (provision.getLowpanCredential() != null) {
System.out.println(
"Forming "
- + provision.getLowpanIdentity().toString()
+ + provision.getLowpanIdentity()
+ " with provided credential");
} else {
- System.out.println("Forming " + provision.getLowpanIdentity().toString());
+ System.out.println("Forming " + provision.getLowpanIdentity());
}
getLowpanInterface().form(provision);
@@ -273,92 +296,57 @@ public class LowpanCtl extends BaseCommand {
System.out.println("Formed.");
}
- private String propAsString(String key, Object value) {
- if (value instanceof byte[]) {
- value = HexDump.toHexString((byte[]) value);
- } else if (value instanceof String[]) {
- if (((String[]) value).length == 0) {
- value = "{ }";
- } else {
- String renderedValue = "{\n";
- for (String row : (String[]) value) {
- renderedValue += "\t\"" + row + "\"\n";
- }
- value = renderedValue + "}";
- }
- } else if (value instanceof int[]) {
- if (((int[]) value).length == 0) {
- value = "{ }";
- } else {
- String renderedValue = "{\n";
- for (int row : (int[]) value) {
- renderedValue += "\t" + Integer.toString(row) + "\n";
- }
- value = renderedValue + "}";
- }
- } else if ((value instanceof Long) && (key.equals(ILowpanInterface.KEY_NETWORK_XPANID))) {
- value = "0x" + Long.toHexString((Long) value);
- } else if ((value instanceof Integer)
- && (key.equals(ILowpanInterface.KEY_NETWORK_PANID)
- || key.equals("Thread:RLOC16"))) {
- value = String.format("0x%04X", (Integer) value & 0xFFFF);
+ private void runStatus() throws LowpanException, RemoteException {
+ LowpanInterface iface = getLowpanInterface();
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(iface.getName())
+ .append("\t")
+ .append(iface.getState() + " (" + iface.getRole() + ")");
+
+ if (iface.isUp()) {
+ sb.append(" UP");
}
- return value.toString();
- }
- private void runGetProp() throws LowpanException, RemoteException {
- String key = nextArg();
+ if (iface.isConnected()) {
+ sb.append(" CONNECTED");
+ }
- if (key == null) {
- try {
- String key_list[] = getILowpanInterface().getPropertyKeys();
+ if (iface.isCommissioned()) {
+ sb.append(" COMMISSIONED");
+ }
- for (String subkey : key_list) {
- Object value;
- try {
- value = getILowpanInterface().getPropertyAsString(subkey);
- } catch (Exception x) {
- value = x;
- }
- System.out.println(subkey + " => " + propAsString(subkey, value));
- }
- } catch (RemoteException x) {
- x.rethrowAsRuntimeException();
- }
- } else {
- Object value = getILowpanInterface().getPropertyAsString(key);
- System.out.println(propAsString(key, value));
+ sb
+ .append("\n\t")
+ .append(getLowpanInterface().getLowpanIdentity());
+
+ for (LinkAddress addr : iface.getLinkAddresses()) {
+ sb.append("\n\t").append(addr);
}
- }
- private void runSetProp() {
- System.out.println("Command not implemented");
+ sb.append("\n");
+ System.out.println(sb.toString());
}
- private void runStatus() throws LowpanException, RemoteException {
- String statusKeys[] = {
- ILowpanInterface.KEY_INTERFACE_ENABLED,
- ILowpanInterface.KEY_INTERFACE_STATE,
- "org.wpantund.Daemon:Version",
- "org.wpantund.NCP:Version",
- "org.wpantund.Config:NCP:DriverName",
- "org.wpantund.IPv6:LinkLocalAddress",
- "org.wpantund.IPv6:MeshLocalAddress",
- };
- System.out.println(
- "Current Network => " + getLowpanInterface().getLowpanIdentity().toString());
-
- for (String key : statusKeys) {
- Object value;
- try {
- value = getILowpanInterface().getPropertyAsString(key);
- if (value != null) {
- System.out.println(key + " => " + propAsString(key, value));
- }
- } catch (ServiceSpecificException x) {
- // Skip keys which cause remote exceptions.
+ private void runShowCredential() throws LowpanException, RemoteException {
+ LowpanInterface iface = getLowpanInterface();
+ boolean raw = false;
+ String arg;
+ while ((arg = nextArg()) != null) {
+ if (arg.equals("--raw") || arg.equals("-r")) {
+ raw = true;
+ } else {
+ throwCommandError("Unrecognized argument \"" + arg + "\"");
}
}
+
+ LowpanCredential credential = iface.getLowpanCredential();
+ if (raw) {
+ System.out.println(HexDump.toHexString(credential.getMasterKey()));
+ } else {
+ System.out.println(
+ iface.getName() + "\t" + credential.toSensitiveString());
+ }
}
private void runListInterfaces() {
diff --git a/libandroid_net_lowpan/Android.mk b/libandroid_net_lowpan/Android.mk
new file mode 100644
index 0000000..730d97d
--- /dev/null
+++ b/libandroid_net_lowpan/Android.mk
@@ -0,0 +1,33 @@
+#
+# 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)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libandroid_net_lowpan
+LOCAL_MODULE_TAGS := optional
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_SHARED_LIBRARIES += libbase
+LOCAL_SHARED_LIBRARIES += libbinder
+LOCAL_SHARED_LIBRARIES += libutils
+LOCAL_SHARED_LIBRARIES += liblog
+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, ../../../../base/lowpan/java/android/net/lowpan)
+LOCAL_SRC_FILES += $(call all-cpp-files-under)
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libandroid_net_lowpan/LowpanBeaconInfo.cpp b/libandroid_net_lowpan/LowpanBeaconInfo.cpp
new file mode 100644
index 0000000..95746df
--- /dev/null
+++ b/libandroid_net_lowpan/LowpanBeaconInfo.cpp
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "LowpanBeaconInfo"
+
+#include <android/net/lowpan/LowpanBeaconInfo.h>
+
+#include <binder/Parcel.h>
+#include <log/log.h>
+#include <utils/Errors.h>
+
+using android::BAD_TYPE;
+using android::BAD_VALUE;
+using android::NO_ERROR;
+using android::Parcel;
+using android::status_t;
+using android::UNEXPECTED_NULL;
+using android::net::lowpan::LowpanBeaconInfo;
+using namespace ::android::binder;
+
+namespace android {
+
+namespace net {
+
+namespace lowpan {
+
+#define RETURN_IF_FAILED(calledOnce) \
+ { \
+ status_t returnStatus = calledOnce; \
+ if (returnStatus) { \
+ ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
+ return returnStatus; \
+ } \
+ }
+
+LowpanBeaconInfo::Builder::Builder() {
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setName(const std::string& value) {
+ mIdentityBuilder.setName(value);
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setType(const std::string& value) {
+ mIdentityBuilder.setType(value);
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setType(const ::android::String16& value) {
+ mIdentityBuilder.setType(value);
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setXpanid(const std::vector<uint8_t>& value) {
+ mIdentityBuilder.setXpanid(value);
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setXpanid(const uint8_t* valuePtr, int32_t valueLen) {
+ mIdentityBuilder.setXpanid(valuePtr, valueLen);
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setPanid(int32_t value) {
+ mIdentityBuilder.setPanid(value);
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setChannel(int32_t value) {
+ mIdentityBuilder.setChannel(value);
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setLowpanIdentity(const LowpanIdentity& value) {
+ mIdentityBuilder.setLowpanIdentity(value);
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setRssi(int32_t value) {
+ mRssi = value;
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setLqi(int32_t value) {
+ mLqi = value;
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setBeaconAddress(const std::vector<uint8_t>& value) {
+ mBeaconAddress = value;
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setBeaconAddress(const uint8_t* valuePtr, int32_t valueLen) {
+ mBeaconAddress.clear();
+ mBeaconAddress.insert(mBeaconAddress.end(), valuePtr, valuePtr + valueLen);
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::setFlag(int32_t value) {
+ mFlags.insert(value);
+ return *this;
+}
+
+LowpanBeaconInfo::Builder& LowpanBeaconInfo::Builder::clearFlag(int32_t value) {
+ mFlags.erase(value);
+ return *this;
+}
+
+LowpanBeaconInfo LowpanBeaconInfo::Builder::build(void) const {
+ return LowpanBeaconInfo(*this);
+}
+
+LowpanBeaconInfo::LowpanBeaconInfo(const LowpanBeaconInfo::Builder& builder) :
+ mIdentity(builder.mIdentityBuilder.build()),
+ mRssi(builder.mRssi),
+ mLqi(builder.mLqi),
+ mBeaconAddress(builder.mBeaconAddress),
+ mFlags(builder.mFlags)
+{
+}
+
+status_t LowpanBeaconInfo::writeToParcel(Parcel* parcel) const {
+ /*
+ * Keep implementation in sync with writeToParcel() in
+ * frameworks/base/lowpan/java/android/net/android/net/lowpan/LowpanBeaconInfo.java.
+ */
+
+ RETURN_IF_FAILED(mIdentity.writeToParcel(parcel));
+ RETURN_IF_FAILED(parcel->writeInt32(mRssi));
+ RETURN_IF_FAILED(parcel->writeInt32(mLqi));
+ RETURN_IF_FAILED(parcel->writeByteVector(mBeaconAddress));
+ RETURN_IF_FAILED(parcel->writeInt32(mFlags.size()));
+
+ std::set<int32_t>::const_iterator iter;
+ std::set<int32_t>::const_iterator end = mFlags.end();
+
+ for (iter = mFlags.begin(); iter != end; ++iter) {
+ RETURN_IF_FAILED(parcel->writeInt32(*iter));
+ }
+
+ return NO_ERROR;
+}
+
+status_t LowpanBeaconInfo::readFromParcel(const Parcel* parcel) {
+ /*
+ * Keep implementation in sync with readFromParcel() in
+ * frameworks/base/lowpan/java/android/net/android/net/lowpan/LowpanBeaconInfo.java.
+ */
+
+ RETURN_IF_FAILED(mIdentity.readFromParcel(parcel));
+ RETURN_IF_FAILED(parcel->readInt32(&mRssi));
+ RETURN_IF_FAILED(parcel->readInt32(&mLqi));
+ RETURN_IF_FAILED(parcel->readByteVector(&mBeaconAddress));
+
+ int32_t flagCount = 0;
+
+ RETURN_IF_FAILED(parcel->readInt32(&flagCount));
+
+ if (flagCount < 0) {
+ ALOGE("Bad flag count");
+ return BAD_VALUE;
+ }
+
+ mFlags.clear();
+
+ while (flagCount--) {
+ int32_t flag = 0;
+ RETURN_IF_FAILED(parcel->readInt32(&flag));
+ mFlags.insert(flag);
+ }
+
+ return NO_ERROR;
+}
+
+bool LowpanBeaconInfo::operator==(const LowpanBeaconInfo& rhs)
+{
+ if (mIdentity != rhs.mIdentity) {
+ return false;
+ }
+
+ if (mRssi != rhs.mRssi) {
+ return false;
+ }
+
+ if (mLqi != rhs.mLqi) {
+ return false;
+ }
+
+ if (mBeaconAddress != rhs.mBeaconAddress) {
+ return false;
+ }
+
+ if (mFlags != rhs.mFlags) {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace lowpan
+
+} // namespace net
+
+} // namespace android
diff --git a/libandroid_net_lowpan/LowpanChannelInfo.cpp b/libandroid_net_lowpan/LowpanChannelInfo.cpp
new file mode 100644
index 0000000..af4e7a2
--- /dev/null
+++ b/libandroid_net_lowpan/LowpanChannelInfo.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "LowpanChannelInfo"
+
+#include <android/net/lowpan/LowpanChannelInfo.h>
+
+#include <binder/Parcel.h>
+#include <log/log.h>
+#include <utils/Errors.h>
+
+using android::BAD_TYPE;
+using android::BAD_VALUE;
+using android::NO_ERROR;
+using android::Parcel;
+using android::status_t;
+using android::UNEXPECTED_NULL;
+using android::net::lowpan::LowpanChannelInfo;
+using namespace ::android::binder;
+
+namespace android {
+
+namespace net {
+
+namespace lowpan {
+
+#define RETURN_IF_FAILED(calledOnce) \
+ { \
+ status_t returnStatus = calledOnce; \
+ if (returnStatus) { \
+ ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
+ return returnStatus; \
+ } \
+ }
+
+status_t LowpanChannelInfo::writeToParcel(Parcel* parcel) const {
+ /*
+ * Keep implementation in sync with writeToParcel() in
+ * frameworks/base/lowpan/java/android/net/android/net/lowpan/LowpanChannelInfo.java.
+ */
+
+ RETURN_IF_FAILED(parcel->writeInt32(mIndex));
+ RETURN_IF_FAILED(parcel->writeUtf8AsUtf16(mName));
+ RETURN_IF_FAILED(parcel->writeFloat(mSpectrumCenterFrequency));
+ RETURN_IF_FAILED(parcel->writeFloat(mSpectrumBandwidth));
+ RETURN_IF_FAILED(parcel->writeInt32(mMaxTxPower));
+ RETURN_IF_FAILED(parcel->writeBool(mIsMaskedByRegulatoryDomain));
+
+ return NO_ERROR;
+}
+
+status_t LowpanChannelInfo::readFromParcel(const Parcel* parcel) {
+ /*
+ * Keep implementation in sync with readFromParcel() in
+ * frameworks/base/lowpan/java/android/net/android/net/lowpan/LowpanChannelInfo.java.
+ */
+
+ RETURN_IF_FAILED(parcel->readInt32(&mIndex));
+ RETURN_IF_FAILED(parcel->readUtf8FromUtf16(&mName));
+ RETURN_IF_FAILED(parcel->readFloat(&mSpectrumCenterFrequency));
+ RETURN_IF_FAILED(parcel->readFloat(&mSpectrumBandwidth));
+ RETURN_IF_FAILED(parcel->readInt32(&mMaxTxPower));
+ RETURN_IF_FAILED(parcel->readBool(&mIsMaskedByRegulatoryDomain));
+
+ return NO_ERROR;
+}
+
+bool LowpanChannelInfo::operator==(const LowpanChannelInfo& rhs)
+{
+ if (mIndex != rhs.mIndex) {
+ return false;
+ }
+
+ if (mName != rhs.mName) {
+ return false;
+ }
+
+ if (mSpectrumCenterFrequency != rhs.mSpectrumCenterFrequency) {
+ return false;
+ }
+
+ if (mSpectrumBandwidth != rhs.mSpectrumBandwidth) {
+ return false;
+ }
+
+ if (mMaxTxPower != rhs.mMaxTxPower) {
+ return false;
+ }
+
+ if (mIsMaskedByRegulatoryDomain != rhs.mIsMaskedByRegulatoryDomain) {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace lowpan
+
+} // namespace net
+
+} // namespace android
diff --git a/libandroid_net_lowpan/LowpanCredential.cpp b/libandroid_net_lowpan/LowpanCredential.cpp
new file mode 100644
index 0000000..f0c6109
--- /dev/null
+++ b/libandroid_net_lowpan/LowpanCredential.cpp
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "LowpanCredential"
+
+#include <android/net/lowpan/LowpanCredential.h>
+
+#include <binder/Parcel.h>
+#include <log/log.h>
+#include <utils/Errors.h>
+
+using android::BAD_TYPE;
+using android::BAD_VALUE;
+using android::NO_ERROR;
+using android::Parcel;
+using android::status_t;
+using android::UNEXPECTED_NULL;
+using android::net::lowpan::LowpanCredential;
+using namespace ::android::binder;
+
+namespace android {
+
+namespace net {
+
+namespace lowpan {
+
+#define RETURN_IF_FAILED(calledOnce) \
+ { \
+ status_t returnStatus = calledOnce; \
+ if (returnStatus) { \
+ ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
+ return returnStatus; \
+ } \
+ }
+
+LowpanCredential::LowpanCredential() : mMasterKeyIndex(UNSPECIFIED_MASTER_KEY_INDEX) { }
+
+status_t LowpanCredential::initMasterKey(LowpanCredential& out, const uint8_t* masterKeyBytes, int masterKeyLen, int masterKeyIndex)
+{
+ if (masterKeyLen < 0) {
+ return BAD_INDEX;
+ } else if (masterKeyLen > MASTER_KEY_MAX_SIZE) {
+ return BAD_INDEX;
+ } else if (masterKeyBytes == NULL) {
+ return BAD_VALUE;
+ }
+
+ out.mMasterKey.clear();
+ out.mMasterKey.insert(out.mMasterKey.end(), masterKeyBytes, masterKeyBytes + masterKeyLen);
+ out.mMasterKeyIndex = masterKeyIndex;
+
+ return NO_ERROR;
+}
+
+status_t LowpanCredential::initMasterKey(LowpanCredential& out, const uint8_t* masterKeyBytes, int masterKeyLen)
+{
+ return LowpanCredential::initMasterKey(out, masterKeyBytes, masterKeyLen, 0);
+}
+
+status_t LowpanCredential::initMasterKey(LowpanCredential& out, const std::vector<uint8_t>& masterKey, int masterKeyIndex)
+{
+ return LowpanCredential::initMasterKey(out, &masterKey.front(), masterKey.size(), masterKeyIndex);
+}
+
+status_t LowpanCredential::initMasterKey(LowpanCredential& out, const std::vector<uint8_t>& masterKey)
+{
+ return LowpanCredential::initMasterKey(out, masterKey, 0);
+}
+
+bool LowpanCredential::isMasterKey() const {
+ return mMasterKey.size() > 0;
+}
+
+bool LowpanCredential::getMasterKey(std::vector<uint8_t>* masterKey) const {
+ if (isMasterKey()) {
+ *masterKey = mMasterKey;
+ return true;
+ }
+ return false;
+}
+
+bool LowpanCredential::getMasterKey(const uint8_t** masterKey, int* masterKeyLen) const {
+ if (isMasterKey()) {
+ if (masterKey) {
+ *masterKey = &mMasterKey.front();
+ }
+ if (masterKeyLen) {
+ *masterKeyLen = mMasterKey.size();
+ }
+ return true;
+ }
+ return false;
+}
+
+int LowpanCredential::getMasterKeyIndex() const {
+ return mMasterKeyIndex;
+}
+
+status_t LowpanCredential::writeToParcel(Parcel* parcel) const {
+ /*
+ * Keep implementation in sync with writeToParcel() in
+ * frameworks/base/lowpan/java/android/net/android/net/lowpan/LowpanCredential.java.
+ */
+ RETURN_IF_FAILED(parcel->writeByteVector(mMasterKey));
+ RETURN_IF_FAILED(parcel->writeInt32(mMasterKeyIndex));
+ return NO_ERROR;
+}
+
+status_t LowpanCredential::readFromParcel(const Parcel* parcel) {
+ /*
+ * Keep implementation in sync with readFromParcel() in
+ * frameworks/base/lowpan/java/android/net/android/net/lowpan/LowpanCredential.java.
+ */
+ RETURN_IF_FAILED(parcel->readByteVector(&mMasterKey));
+ RETURN_IF_FAILED(parcel->readInt32(&mMasterKeyIndex));
+ return NO_ERROR;
+}
+
+bool LowpanCredential::operator==(const LowpanCredential& rhs)
+{
+ if (mMasterKey != rhs.mMasterKey) {
+ return false;
+ }
+
+ if (mMasterKeyIndex != rhs.mMasterKeyIndex) {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace lowpan
+
+} // namespace net
+
+} // namespace android
diff --git a/libandroid_net_lowpan/LowpanIdentity.cpp b/libandroid_net_lowpan/LowpanIdentity.cpp
new file mode 100644
index 0000000..0e64c20
--- /dev/null
+++ b/libandroid_net_lowpan/LowpanIdentity.cpp
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "LowpanIdentity"
+
+#include <android/net/lowpan/LowpanIdentity.h>
+
+#include <binder/Parcel.h>
+#include <log/log.h>
+#include <utils/Errors.h>
+
+using android::BAD_TYPE;
+using android::BAD_VALUE;
+using android::NO_ERROR;
+using android::Parcel;
+using android::status_t;
+using android::UNEXPECTED_NULL;
+using android::net::lowpan::LowpanIdentity;
+using namespace ::android::binder;
+
+namespace android {
+
+namespace net {
+
+namespace lowpan {
+
+#define RETURN_IF_FAILED(calledOnce) \
+ { \
+ status_t returnStatus = calledOnce; \
+ if (returnStatus) { \
+ ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
+ return returnStatus; \
+ } \
+ }
+
+bool LowpanIdentity::getName(std::string* value) const {
+ if (value != NULL) {
+ *value = mName;
+ }
+ return true;
+}
+bool LowpanIdentity::getType(std::string* value) const {
+ if (value != NULL) {
+ *value = mType;
+ }
+ return true;
+}
+bool LowpanIdentity::getXpanid(std::vector<uint8_t>* value) const {
+ if (value != NULL) {
+ *value = mXpanid;
+ }
+ return true;
+}
+int32_t LowpanIdentity::getPanid(void) const {
+ return mPanid;
+}
+int32_t LowpanIdentity::getChannel(void) const {
+ return mChannel;
+}
+
+LowpanIdentity::Builder::Builder() {
+}
+
+LowpanIdentity::Builder& LowpanIdentity::Builder::setName(const std::string& value) {
+ mIdentity.mName = value;
+ return *this;
+}
+
+LowpanIdentity::Builder& LowpanIdentity::Builder::setType(const std::string& value) {
+ mIdentity.mType = value;
+ return *this;
+}
+
+LowpanIdentity::Builder& LowpanIdentity::Builder::setType(const ::android::String16& value) {
+ return setType(String8(value).string());
+}
+
+LowpanIdentity::Builder& LowpanIdentity::Builder::setXpanid(const std::vector<uint8_t>& value) {
+ mIdentity.mXpanid = value;
+ return *this;
+}
+
+LowpanIdentity::Builder& LowpanIdentity::Builder::setXpanid(const uint8_t* valuePtr, int32_t valueLen) {
+ mIdentity.mXpanid.clear();
+ mIdentity.mXpanid.insert(mIdentity.mXpanid.end(), valuePtr, valuePtr + valueLen);
+ return *this;
+}
+
+LowpanIdentity::Builder& LowpanIdentity::Builder::setPanid(int32_t value) {
+ mIdentity.mPanid = value;
+ return *this;
+}
+
+LowpanIdentity::Builder& LowpanIdentity::Builder::setChannel(int32_t value) {
+ mIdentity.mChannel = value;
+ return *this;
+}
+
+LowpanIdentity::Builder& LowpanIdentity::Builder::setLowpanIdentity(const LowpanIdentity& value) {
+ mIdentity = value;
+ return *this;
+}
+
+LowpanIdentity LowpanIdentity::Builder::build(void) const {
+ return mIdentity;
+}
+
+LowpanIdentity::LowpanIdentity() : mPanid(UNSPECIFIED_PANID), mChannel(UNSPECIFIED_CHANNEL) {
+}
+
+status_t LowpanIdentity::writeToParcel(Parcel* parcel) const {
+ /*
+ * Keep implementation in sync with writeToParcel() in
+ * frameworks/base/lowpan/java/android/net/android/net/lowpan/LowpanIdentity.java.
+ */
+
+ std::vector<int8_t> rawName(mName.begin(), mName.end());
+
+ RETURN_IF_FAILED(parcel->writeByteVector(rawName));
+ RETURN_IF_FAILED(parcel->writeUtf8AsUtf16(mType));
+ RETURN_IF_FAILED(parcel->writeByteVector(mXpanid));
+ RETURN_IF_FAILED(parcel->writeInt32(mPanid));
+ RETURN_IF_FAILED(parcel->writeInt32(mChannel));
+ return NO_ERROR;
+}
+
+status_t LowpanIdentity::readFromParcel(const Parcel* parcel) {
+ /*
+ * Keep implementation in sync with readFromParcel() in
+ * frameworks/base/lowpan/java/android/net/android/net/lowpan/LowpanIdentity.java.
+ */
+
+ std::vector<int8_t> rawName;
+
+ RETURN_IF_FAILED(parcel->readByteVector(&rawName));
+
+ mName = std::string((const char*)&rawName.front(), rawName.size());
+
+ RETURN_IF_FAILED(parcel->readUtf8FromUtf16(&mType));
+ RETURN_IF_FAILED(parcel->readByteVector(&mXpanid));
+ RETURN_IF_FAILED(parcel->readInt32(&mPanid));
+ RETURN_IF_FAILED(parcel->readInt32(&mChannel));
+ return NO_ERROR;
+}
+
+bool LowpanIdentity::operator==(const LowpanIdentity& rhs)
+{
+ const LowpanIdentity& lhs = *this;
+
+ if (lhs.mName != rhs.mName) {
+ return false;
+ }
+
+ if (lhs.mType != rhs.mType) {
+ return false;
+ }
+
+ if (lhs.mXpanid != rhs.mXpanid) {
+ return false;
+ }
+
+ if (lhs.mPanid != rhs.mPanid) {
+ return false;
+ }
+
+ if (lhs.mChannel != rhs.mChannel) {
+ return false;
+ }
+ return true;
+}
+
+} // namespace lowpan
+
+} // namespace net
+
+} // namespace android
diff --git a/libandroid_net_lowpan/LowpanProvision.cpp b/libandroid_net_lowpan/LowpanProvision.cpp
new file mode 100644
index 0000000..315ea54
--- /dev/null
+++ b/libandroid_net_lowpan/LowpanProvision.cpp
@@ -0,0 +1,121 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "LowpanProvision"
+
+#include <android/net/lowpan/LowpanProvision.h>
+
+#include <binder/Parcel.h>
+#include <log/log.h>
+#include <utils/Errors.h>
+
+using android::BAD_TYPE;
+using android::BAD_VALUE;
+using android::NO_ERROR;
+using android::Parcel;
+using android::status_t;
+using android::UNEXPECTED_NULL;
+using android::net::lowpan::LowpanProvision;
+using namespace ::android::binder;
+
+namespace android {
+
+namespace net {
+
+namespace lowpan {
+
+#define RETURN_IF_FAILED(calledOnce) \
+ { \
+ status_t returnStatus = calledOnce; \
+ if (returnStatus) { \
+ ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
+ return returnStatus; \
+ } \
+ }
+LowpanProvision::LowpanProvision(const LowpanIdentity& identity, const LowpanCredential& credential)
+ : mIdentity(identity), mCredential(credential), mHasCredential(true)
+{
+}
+
+LowpanProvision::LowpanProvision(const LowpanIdentity& identity)
+ : mIdentity(identity), mHasCredential(false)
+{
+}
+
+const LowpanIdentity* LowpanProvision::getLowpanIdentity() const {
+ return &mIdentity;
+}
+
+const LowpanCredential* LowpanProvision::getLowpanCredential() const {
+ return mHasCredential
+ ? &mCredential
+ : NULL;
+}
+
+status_t LowpanProvision::writeToParcel(Parcel* parcel) const {
+ /*
+ * Keep implementation in sync with writeToParcel() in
+ * frameworks/base/lowpan/java/android/net/android/net/lowpan/LowpanProvision.java.
+ */
+
+ RETURN_IF_FAILED(mIdentity.writeToParcel(parcel));
+ RETURN_IF_FAILED(parcel->writeBool(mHasCredential));
+
+ if (mHasCredential) {
+ RETURN_IF_FAILED(mCredential.writeToParcel(parcel));
+ }
+
+ return NO_ERROR;
+}
+
+status_t LowpanProvision::readFromParcel(const Parcel* parcel) {
+ /*
+ * Keep implementation in sync with readFromParcel() in
+ * frameworks/base/lowpan/java/android/net/android/net/lowpan/LowpanProvision.java.
+ */
+
+ RETURN_IF_FAILED(mIdentity.readFromParcel(parcel));
+ RETURN_IF_FAILED(parcel->readBool(&mHasCredential));
+
+ if (mHasCredential) {
+ RETURN_IF_FAILED(mCredential.readFromParcel(parcel));
+ }
+
+ return NO_ERROR;
+}
+
+bool LowpanProvision::operator==(const LowpanProvision& rhs)
+{
+ if (mIdentity != rhs.mIdentity) {
+ return false;
+ }
+
+ if (mHasCredential != rhs.mHasCredential) {
+ return false;
+ }
+
+ if (mHasCredential && mCredential != rhs.mCredential) {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace lowpan
+
+} // namespace net
+
+} // namespace android
diff --git a/libandroid_net_lowpan/include/android/net/lowpan/LowpanBeaconInfo.h b/libandroid_net_lowpan/include/android/net/lowpan/LowpanBeaconInfo.h
new file mode 100644
index 0000000..9a971ef
--- /dev/null
+++ b/libandroid_net_lowpan/include/android/net/lowpan/LowpanBeaconInfo.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_LOWPAN_BEACON_INFO_H
+#define ANDROID_LOWPAN_BEACON_INFO_H
+
+#include <binder/Parcelable.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+#include <set>
+
+#include "LowpanIdentity.h"
+
+namespace android {
+
+namespace net {
+
+namespace lowpan {
+
+/*
+ * C++ implementation of the Java class android.net.lowpan.LowpanBeaconInfo
+ */
+class LowpanBeaconInfo : public Parcelable {
+public:
+ static const int32_t FLAG_CAN_ASSIST = 1;
+
+ class Builder;
+ LowpanBeaconInfo() = default;
+ virtual ~LowpanBeaconInfo() = default;
+ LowpanBeaconInfo(const LowpanBeaconInfo& x) = default;
+
+ bool operator==(const LowpanBeaconInfo& rhs);
+ bool operator!=(const LowpanBeaconInfo& rhs) { return !(*this == rhs); }
+
+public:
+ // Overrides
+ status_t writeToParcel(Parcel* parcel) const override;
+ status_t readFromParcel(const Parcel* parcel) override;
+
+private:
+ LowpanBeaconInfo(const Builder& builder);
+
+private:
+ // Data
+ LowpanIdentity mIdentity;
+ int32_t mRssi;
+ int32_t mLqi;
+ std::vector<uint8_t> mBeaconAddress;
+ std::set<int32_t> mFlags;
+};
+
+class LowpanBeaconInfo::Builder {
+ friend class LowpanBeaconInfo;
+public:
+ Builder();
+ Builder& setName(const std::string& value);
+ Builder& setType(const std::string& value);
+ Builder& setType(const ::android::String16& value);
+ Builder& setXpanid(const std::vector<uint8_t>& value);
+ Builder& setXpanid(const uint8_t* valuePtr, int32_t valueLen);
+ Builder& setPanid(int32_t value);
+ Builder& setChannel(int32_t value);
+ Builder& setLowpanIdentity(const LowpanIdentity& value);
+
+ Builder& setRssi(int32_t value);
+ Builder& setLqi(int32_t value);
+ Builder& setBeaconAddress(const std::vector<uint8_t>& value);
+ Builder& setBeaconAddress(const uint8_t* valuePtr, int32_t valueLen);
+ Builder& setFlag(int32_t value);
+ Builder& clearFlag(int32_t value);
+
+ LowpanBeaconInfo build(void) const;
+private:
+ LowpanIdentity::Builder mIdentityBuilder;
+
+ int32_t mRssi;
+ int32_t mLqi;
+ std::vector<uint8_t> mBeaconAddress;
+ std::set<int32_t> mFlags;
+};
+
+} // namespace lowpan
+
+} // namespace net
+
+} // namespace android
+
+#endif // ANDROID_LOWPAN_BEACON_INFO_H
diff --git a/libandroid_net_lowpan/include/android/net/lowpan/LowpanChannelInfo.h b/libandroid_net_lowpan/include/android/net/lowpan/LowpanChannelInfo.h
new file mode 100644
index 0000000..e29820a
--- /dev/null
+++ b/libandroid_net_lowpan/include/android/net/lowpan/LowpanChannelInfo.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_LOWPAN_CHANNEL_INFO_H
+#define ANDROID_LOWPAN_CHANNEL_INFO_H
+
+#include <binder/Parcelable.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+#include <string>
+
+namespace android {
+
+namespace net {
+
+namespace lowpan {
+
+/*
+ * C++ implementation of the Java class android.net.lowpan.LowpanChannelInfo
+ */
+class LowpanChannelInfo : public Parcelable {
+public:
+ LowpanChannelInfo() = default;
+ virtual ~LowpanChannelInfo() = default;
+ LowpanChannelInfo(const LowpanChannelInfo& x) = default;
+
+ bool operator==(const LowpanChannelInfo& rhs);
+ bool operator!=(const LowpanChannelInfo& rhs) { return !(*this == rhs); }
+
+public:
+ // Overrides
+ status_t writeToParcel(Parcel* parcel) const override;
+ status_t readFromParcel(const Parcel* parcel) override;
+
+private:
+ // Data
+ int32_t mIndex;
+ std::string mName;
+ float mSpectrumCenterFrequency;
+ float mSpectrumBandwidth;
+ int32_t mMaxTxPower;
+ bool mIsMaskedByRegulatoryDomain;
+};
+
+} // namespace lowpan
+
+} // namespace net
+
+} // namespace android
+
+#endif // ANDROID_LOWPAN_CHANNEL_INFO_H
diff --git a/libandroid_net_lowpan/include/android/net/lowpan/LowpanCredential.h b/libandroid_net_lowpan/include/android/net/lowpan/LowpanCredential.h
new file mode 100644
index 0000000..c8ac90b
--- /dev/null
+++ b/libandroid_net_lowpan/include/android/net/lowpan/LowpanCredential.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_LOWPAN_CREDENTIAL_H
+#define ANDROID_LOWPAN_CREDENTIAL_H
+
+#include <binder/Parcelable.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace net {
+
+namespace lowpan {
+
+/*
+ * C++ implementation of the Java class android.net.lowpan.LowpanCredential
+ */
+class LowpanCredential : public Parcelable {
+public:
+ static const int32_t UNSPECIFIED_MASTER_KEY_INDEX = 0;
+ static const int MASTER_KEY_MAX_SIZE = 1048576;
+
+ LowpanCredential();
+ virtual ~LowpanCredential() = default;
+ LowpanCredential(const LowpanCredential& x) = default;
+
+ static status_t initMasterKey(LowpanCredential& out, const std::vector<uint8_t>& masterKey, int32_t masterKeyIndex);
+ static status_t initMasterKey(LowpanCredential& out, const std::vector<uint8_t>& masterKey);
+ static status_t initMasterKey(LowpanCredential& out, const uint8_t* masterKeyBytes, int masterKeyLen, int32_t masterKeyIndex);
+ static status_t initMasterKey(LowpanCredential& out, const uint8_t* masterKeyBytes, int masterKeyLen);
+
+ bool isMasterKey()const;
+ bool getMasterKey(std::vector<uint8_t>* masterKey)const;
+ bool getMasterKey(const uint8_t** masterKey, int* masterKeyLen)const;
+ int32_t getMasterKeyIndex()const;
+
+ bool operator==(const LowpanCredential& rhs);
+ bool operator!=(const LowpanCredential& rhs) { return !(*this == rhs); }
+
+public:
+ // Overrides
+ status_t writeToParcel(Parcel* parcel) const override;
+ status_t readFromParcel(const Parcel* parcel) override;
+
+private:
+ // Data
+ std::vector<uint8_t> mMasterKey;
+ int32_t mMasterKeyIndex;
+};
+
+} // namespace lowpan
+
+} // namespace net
+
+} // namespace android
+
+#endif // ANDROID_LOWPAN_CREDENTIAL_H
diff --git a/libandroid_net_lowpan/include/android/net/lowpan/LowpanIdentity.h b/libandroid_net_lowpan/include/android/net/lowpan/LowpanIdentity.h
new file mode 100644
index 0000000..c82446a
--- /dev/null
+++ b/libandroid_net_lowpan/include/android/net/lowpan/LowpanIdentity.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_LOWPAN_IDENTITY_H
+#define ANDROID_LOWPAN_IDENTITY_H
+
+#include <binder/Parcelable.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+#include <string>
+
+namespace android {
+
+namespace net {
+
+namespace lowpan {
+
+/*
+ * C++ implementation of the Java class android.net.lowpan.LowpanIdentity
+ */
+class LowpanIdentity : public Parcelable {
+public:
+ class Builder;
+ static const int32_t UNSPECIFIED_PANID = 0xFFFFFFFF;
+ static const int32_t UNSPECIFIED_CHANNEL = -1;
+
+ LowpanIdentity();
+ virtual ~LowpanIdentity() = default;
+ LowpanIdentity(const LowpanIdentity& x) = default;
+
+ bool operator==(const LowpanIdentity& rhs);
+ bool operator!=(const LowpanIdentity& rhs) { return !(*this == rhs); }
+
+ bool getName(std::string* value) const;
+ bool getType(std::string* value) const;
+ bool getXpanid(std::vector<uint8_t>* value) const;
+ int32_t getPanid(void) const;
+ int32_t getChannel(void) const;
+
+public:
+ // Overrides
+ status_t writeToParcel(Parcel* parcel) const override;
+ status_t readFromParcel(const Parcel* parcel) override;
+
+private:
+ // Data
+ std::string mName;
+ std::string mType;
+ std::vector<uint8_t> mXpanid;
+ int32_t mPanid;
+ int32_t mChannel;
+};
+
+class LowpanIdentity::Builder {
+public:
+ Builder();
+ Builder& setName(const std::string& value);
+ Builder& setType(const std::string& value);
+ Builder& setType(const ::android::String16& value);
+ Builder& setXpanid(const std::vector<uint8_t>& value);
+ Builder& setXpanid(const uint8_t* valuePtr, int32_t valueLen);
+ Builder& setPanid(int32_t value);
+ Builder& setChannel(int32_t value);
+ Builder& setLowpanIdentity(const LowpanIdentity& value);
+
+ LowpanIdentity build(void) const;
+private:
+ LowpanIdentity mIdentity;
+};
+
+} // namespace lowpan
+
+} // namespace net
+
+} // namespace android
+
+#endif // ANDROID_LOWPAN_IDENTITY_H
diff --git a/libandroid_net_lowpan/include/android/net/lowpan/LowpanProvision.h b/libandroid_net_lowpan/include/android/net/lowpan/LowpanProvision.h
new file mode 100644
index 0000000..128994c
--- /dev/null
+++ b/libandroid_net_lowpan/include/android/net/lowpan/LowpanProvision.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_LOWPAN_PROVISION_H
+#define ANDROID_LOWPAN_PROVISION_H
+
+#include <binder/Parcelable.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+#include "LowpanIdentity.h"
+#include "LowpanCredential.h"
+
+namespace android {
+
+namespace net {
+
+namespace lowpan {
+
+/*
+ * C++ implementation of the Java class android.net.lowpan.LowpanProvision
+ */
+class LowpanProvision : public Parcelable {
+public:
+ LowpanProvision() = default;
+ virtual ~LowpanProvision() = default;
+ LowpanProvision(const LowpanProvision& x) = default;
+
+ bool operator==(const LowpanProvision& rhs);
+ bool operator!=(const LowpanProvision& rhs) { return !(*this == rhs); }
+
+ LowpanProvision(const LowpanIdentity& identity, const LowpanCredential& credential);
+ LowpanProvision(const LowpanIdentity& identity);
+
+ const LowpanIdentity* getLowpanIdentity() const;
+ const LowpanCredential* getLowpanCredential() const;
+
+public:
+ // Overrides
+ status_t writeToParcel(Parcel* parcel) const override;
+ status_t readFromParcel(const Parcel* parcel) override;
+
+private:
+ // Data
+ LowpanIdentity mIdentity;
+ LowpanCredential mCredential;
+ bool mHasCredential;
+};
+
+} // namespace lowpan
+
+} // namespace net
+
+} // namespace android
+
+#endif // ANDROID_LOWPAN_PROVISION_H
diff --git a/service/java/com/android/server/lowpan/LowpanInterfaceTracker.java b/service/java/com/android/server/lowpan/LowpanInterfaceTracker.java
index afa3f80..89b058c 100644
--- a/service/java/com/android/server/lowpan/LowpanInterfaceTracker.java
+++ b/service/java/com/android/server/lowpan/LowpanInterfaceTracker.java
@@ -28,13 +28,16 @@ import android.net.NetworkFactory;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.ip.IpManager;
+import android.net.ip.IpManager.InitialConfiguration;
import android.net.ip.IpManager.ProvisioningConfiguration;
import android.net.lowpan.ILowpanInterface;
import android.net.lowpan.LowpanException;
import android.net.lowpan.LowpanInterface;
-import android.net.lowpan.LowpanProperties;
+import android.net.lowpan.LowpanRuntimeException;
import android.os.Looper;
import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import com.android.internal.util.HexDump;
import com.android.internal.util.Protocol;
@@ -112,7 +115,6 @@ class LowpanInterfaceTracker extends StateMachine {
final FaultState mFaultState = new FaultState();
final ConnectedState mConnectedState = new ConnectedState();
-
private LocalLowpanCallback mLocalLowpanCallback = new LocalLowpanCallback();
// Misc Private Classes
@@ -268,9 +270,13 @@ class LowpanInterfaceTracker extends StateMachine {
if (mHwAddr == null) {
byte[] hwAddr = null;
try {
- hwAddr = mLowpanInterface.getProperty(LowpanProperties.KEY_MAC_ADDRESS);
- } catch (LowpanException x) {
+ hwAddr = mLowpanInterface.getService().getMacAddress();
+
+ } catch (RemoteException | ServiceSpecificException x) {
+ // Don't let misbehavior of an interface service
+ // crash the system service.
Log.e(TAG, x.toString());
+ transitionTo(mFaultState);
}
if (hwAddr != null) {
@@ -296,7 +302,6 @@ class LowpanInterfaceTracker extends StateMachine {
}
break;
- case CMD_PROVISIONING_SUCCESS:
case CMD_LINK_PROPERTIES_CHANGE:
mLinkProperties = (LinkProperties) message.obj;
if (DBG) {
@@ -402,19 +407,75 @@ class LowpanInterfaceTracker extends StateMachine {
class ObtainingIpState extends State {
@Override
public void enter() {
- mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
- mNetworkAgent.sendNetworkInfo(mNetworkInfo);
+ InitialConfiguration initialConfiguration = new InitialConfiguration();
+
+ try {
+ for (LinkAddress address : mLowpanInterface.getLinkAddresses()) {
+ if (DBG) {
+ Log.i(TAG, "Adding link address: " + address);
+ }
+
+ initialConfiguration.ipAddresses.add(address);
+ IpPrefix prefix = new IpPrefix(address.getAddress(), address.getPrefixLength());
- final ProvisioningConfiguration provisioningConfiguration =
- mIpManager
- .buildProvisioningConfiguration()
- .withProvisioningTimeoutMs(0)
- .withoutIpReachabilityMonitor()
- .withoutIPv4()
- .build();
+ initialConfiguration.directlyConnectedRoutes.add(prefix);
+ }
+
+ for (IpPrefix prefix : mLowpanInterface.getLinkNetworks()) {
+ if (DBG) {
+ Log.i(TAG, "Adding directly connected route: " + prefix);
+ }
+
+ initialConfiguration.directlyConnectedRoutes.add(prefix);
+ }
+
+ } catch (LowpanException | LowpanRuntimeException x) {
+ Log.e(TAG, "Exception while populating InitialConfiguration: " + x);
+ transitionTo(mFaultState);
+ return;
+
+ } catch (RuntimeException x) {
+ if (x.getCause() instanceof RemoteException) {
+ // Don't let misbehavior of an interface service
+ // crash the system service.
+ Log.e(TAG, x.toString());
+ transitionTo(mFaultState);
- mIpManager.startProvisioning(provisioningConfiguration);
+ } else {
+ // This exception wasn't remote in origin, so we rethrow.
+ throw x;
+ }
+ }
+
+ if (!initialConfiguration.isValid()) {
+ Log.e(TAG, "Invalid initial configuration: " + initialConfiguration);
+ transitionTo(mFaultState);
+ return;
+ }
+
+ if (DBG) {
+ Log.d(TAG, "Using Initial configuration: " + initialConfiguration);
+ }
+
+ final ProvisioningConfiguration.Builder builder =
+ mIpManager.buildProvisioningConfiguration();
+
+ builder.withInitialConfiguration(initialConfiguration).withProvisioningTimeoutMs(0);
+
+ // LoWPAN networks generally don't have internet connectivity,
+ // so the reachability monitor would almost always fail.
+ builder.withoutIpReachabilityMonitor();
+
+ // We currently only support IPv6 on LoWPAN networks, although
+ // theoretically we could make this determination by examining
+ // the InitialConfiguration for any IPv4 addresses.
+ builder.withoutIPv4();
+
+ mIpManager.startProvisioning(builder.build());
+
+ mNetworkInfo.setDetailedState(DetailedState.OBTAINING_IPADDR, null, mHwAddr);
+ mNetworkAgent.sendNetworkInfo(mNetworkInfo);
}
@Override
@@ -424,7 +485,7 @@ class LowpanInterfaceTracker extends StateMachine {
case CMD_PROVISIONING_SUCCESS:
Log.i(TAG, "Provisioning Success: " + message.obj.toString());
transitionTo(mConnectedState);
- break;
+ return HANDLED;
}
return NOT_HANDLED;
}
@@ -493,9 +554,6 @@ class LowpanInterfaceTracker extends StateMachine {
mNetworkCapabilities.setLinkUpstreamBandwidthKbps(100);
mNetworkCapabilities.setLinkDownstreamBandwidthKbps(100);
- // Things don't seem to work properly without this. TODO: Investigate.
- //mNetworkCapabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
// CHECKSTYLE:OFF IndentationCheck
addState(mInitState);
addState(mDefaultState);
diff --git a/service/java/com/android/server/lowpan/LowpanServiceImpl.java b/service/java/com/android/server/lowpan/LowpanServiceImpl.java
index 08c4306..07677e3 100644
--- a/service/java/com/android/server/lowpan/LowpanServiceImpl.java
+++ b/service/java/com/android/server/lowpan/LowpanServiceImpl.java
@@ -25,6 +25,7 @@ import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.util.Log;
import java.util.HashMap;
import java.util.HashSet;
@@ -111,9 +112,12 @@ public class LowpanServiceImpl extends ILowpanManager.Stub {
for (ILowpanManagerListener listener : mListenerSet) {
try {
listener.onInterfaceRemoved(lowpanInterface);
- } catch (RemoteException x) {
- // Just skip.
+ } catch (RemoteException | ServiceSpecificException x) {
+ // Don't let misbehavior of a listener
+ // crash the system service.
Log.e(TAG, "Exception caught: " + x);
+
+ // TODO: Consider removing the listener...?
}
}
}
@@ -125,9 +129,12 @@ public class LowpanServiceImpl extends ILowpanManager.Stub {
for (ILowpanManagerListener listener : mListenerSet) {
try {
listener.onInterfaceAdded(lowpanInterface);
- } catch (RemoteException x) {
- // Just skip.
+ } catch (RemoteException | ServiceSpecificException x) {
+ // Don't let misbehavior of a listener
+ // crash the system service.
Log.e(TAG, "Exception caught: " + x);
+
+ // TODO: Consider removing the listener...?
}
}
}
@@ -161,7 +168,9 @@ public class LowpanServiceImpl extends ILowpanManager.Stub {
},
0);
- } catch (RemoteException x) {
+ } catch (RemoteException | ServiceSpecificException x) {
+ // Don't let misbehavior of an interface
+ // crash the system service.
Log.e(TAG, "Exception caught: " + x);
return;
}
@@ -224,7 +233,7 @@ public class LowpanServiceImpl extends ILowpanManager.Stub {
try {
name = lowpanInterface.getName();
- } catch (RemoteException x) {
+ } catch (RemoteException | ServiceSpecificException x) {
// Directly fetching the name failed, so fall back to
// a reverse lookup.
synchronized (mInterfaceMap) {
@@ -258,6 +267,7 @@ public class LowpanServiceImpl extends ILowpanManager.Stub {
0);
mListenerSet.add(listener);
} catch (RemoteException x) {
+ // We only get this exception if listener has already died.
Log.e(TAG, "Exception caught: " + x);
}
}