diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-07-19 07:24:14 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-07-19 07:24:14 +0000 |
commit | 8c221ccd4b43cd66ba9747b864e71fb38c4da517 (patch) | |
tree | 5784aaa8c9f07b7559c69d667ebdc63fc69242f6 | |
parent | ffc04990533192ead6ac903ce5b4a3c6e97a3031 (diff) | |
parent | d38415634a6e0d2175e888618a6ebc52dfcb861e (diff) | |
download | lowpan-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-- | .gitattributes | 2 | ||||
-rw-r--r-- | command/java/com/android/commands/lowpan/LowpanCtl.java | 180 | ||||
-rw-r--r-- | libandroid_net_lowpan/Android.mk | 33 | ||||
-rw-r--r-- | libandroid_net_lowpan/LowpanBeaconInfo.cpp | 218 | ||||
-rw-r--r-- | libandroid_net_lowpan/LowpanChannelInfo.cpp | 114 | ||||
-rw-r--r-- | libandroid_net_lowpan/LowpanCredential.cpp | 149 | ||||
-rw-r--r-- | libandroid_net_lowpan/LowpanIdentity.cpp | 189 | ||||
-rw-r--r-- | libandroid_net_lowpan/LowpanProvision.cpp | 121 | ||||
-rw-r--r-- | libandroid_net_lowpan/include/android/net/lowpan/LowpanBeaconInfo.h | 101 | ||||
-rw-r--r-- | libandroid_net_lowpan/include/android/net/lowpan/LowpanChannelInfo.h | 64 | ||||
-rw-r--r-- | libandroid_net_lowpan/include/android/net/lowpan/LowpanCredential.h | 72 | ||||
-rw-r--r-- | libandroid_net_lowpan/include/android/net/lowpan/LowpanIdentity.h | 90 | ||||
-rw-r--r-- | libandroid_net_lowpan/include/android/net/lowpan/LowpanProvision.h | 69 | ||||
-rw-r--r-- | service/java/com/android/server/lowpan/LowpanInterfaceTracker.java | 96 | ||||
-rw-r--r-- | service/java/com/android/server/lowpan/LowpanServiceImpl.java | 22 |
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); } } |