diff options
Diffstat (limited to 'lowpan')
8 files changed, 536 insertions, 450 deletions
diff --git a/lowpan/java/android/net/lowpan/ILowpanInterface.aidl b/lowpan/java/android/net/lowpan/ILowpanInterface.aidl index e49e72574a31..603dc3cfe641 100644 --- a/lowpan/java/android/net/lowpan/ILowpanInterface.aidl +++ b/lowpan/java/android/net/lowpan/ILowpanInterface.aidl @@ -16,103 +16,39 @@ package android.net.lowpan; +import android.net.IpPrefix; +import android.net.lowpan.ILowpanEnergyScanCallback; import android.net.lowpan.ILowpanInterfaceListener; import android.net.lowpan.ILowpanNetScanCallback; -import android.net.lowpan.ILowpanEnergyScanCallback; -import android.os.PersistableBundle; -import android.net.IpPrefix; +import android.net.lowpan.LowpanBeaconInfo; +import android.net.lowpan.LowpanChannelInfo; +import android.net.lowpan.LowpanCredential; +import android.net.lowpan.LowpanIdentity; +import android.net.lowpan.LowpanProvision; /** {@hide} */ interface ILowpanInterface { - ////////////////////////////////////////////////////////////////////////// - // Permission String Constants - - /* These are here for the sake of C++ interface implementations. */ + // These are here for the sake of C++ interface implementations. const String PERM_ACCESS_LOWPAN_STATE = "android.permission.ACCESS_LOWPAN_STATE"; const String PERM_CHANGE_LOWPAN_STATE = "android.permission.CHANGE_LOWPAN_STATE"; const String PERM_READ_LOWPAN_CREDENTIAL = "android.permission.READ_LOWPAN_CREDENTIAL"; - ////////////////////////////////////////////////////////////////////////// - // Property Key Constants - - /** Type: Boolean */ - const String KEY_INTERFACE_ENABLED = "android.net.lowpan.property.INTERFACE_ENABLED"; - - /** Type: Boolean */ - const String KEY_INTERFACE_UP = "android.net.lowpan.property.INTERFACE_UP"; - - /** Type: Boolean */ - const String KEY_INTERFACE_COMMISSIONED = "android.net.lowpan.property.INTERFACE_COMMISSIONED"; - - /** Type: Boolean */ - const String KEY_INTERFACE_CONNECTED = "android.net.lowpan.property.INTERFACE_CONNECTED"; - - /** Type: String */ - const String KEY_INTERFACE_STATE = "android.net.lowpan.property.INTERFACE_STATE"; - - /** Type: String */ - const String KEY_NETWORK_NAME = "android.net.lowpan.property.NETWORK_NAME"; - - /** Type: Integer */ - const String KEY_NETWORK_TYPE = "android.net.lowpan.property.NETWORK_TYPE"; - - /** Type: Integer */ - const String KEY_NETWORK_PANID = "android.net.lowpan.property.NETWORK_PANID"; - - /** Type: byte[] */ - const String KEY_NETWORK_XPANID = "android.net.lowpan.property.NETWORK_XPANID"; - - /** Type: String */ - const String KEY_NETWORK_ROLE = "android.net.lowpan.property.NETWORK_ROLE"; - - /** Type: byte[] */ - const String KEY_NETWORK_MASTER_KEY = "android.net.lowpan.property.NETWORK_MASTER_KEY"; - - /** Type: Integer */ - const String KEY_NETWORK_MASTER_KEY_INDEX - = "android.net.lowpan.property.NETWORK_MASTER_KEY_INDEX"; - - /** Type: int[] */ - const String KEY_SUPPORTED_CHANNELS = "android.net.lowpan.property.SUPPORTED_CHANNELS"; - - /** Type: Integer */ - const String KEY_CHANNEL = "android.net.lowpan.property.CHANNEL"; - - /** Type: int[] */ + /** + * Channel mask key. + * Used for setting a channel mask when starting a scan. + * Type: int[] + * */ const String KEY_CHANNEL_MASK = "android.net.lowpan.property.CHANNEL_MASK"; - /** Type: Integer */ + /** + * Max Transmit Power Key. + * Used for setting the maximum transmit power when starting a network scan. + * Type: Integer + * */ const String KEY_MAX_TX_POWER = "android.net.lowpan.property.MAX_TX_POWER"; - /** Type: Integer */ - const String KEY_RSSI = "android.net.lowpan.property.RSSI"; - - /** Type: Integer */ - const String KEY_LQI = "android.net.lowpan.property.LQI"; - - /** Type: byte[] */ - const String KEY_BEACON_ADDRESS = "android.net.lowpan.property.BEACON_ORIGIN_ADDRESS"; - - /** Type: Boolean */ - const String KEY_BEACON_CAN_ASSIST = "android.net.lowpan.property.BEACON_CAN_ASSIST"; - - /** Type: String */ - const String DRIVER_VERSION = "android.net.lowpan.property.DRIVER_VERSION"; - - /** Type: String */ - const String NCP_VERSION = "android.net.lowpan.property.NCP_VERSION"; - - /** Type: byte[] - * @hide */ - const String KEY_EXTENDED_ADDRESS = "android.net.lowpan.property.EXTENDED_ADDRESS"; - - /** Type: byte[] - * @hide */ - const String KEY_MAC_ADDRESS = "android.net.lowpan.property.MAC_ADDRESS"; - - ////////////////////////////////////////////////////////////////////////// // Interface States const String STATE_OFFLINE = "offline"; @@ -121,16 +57,26 @@ interface ILowpanInterface { const String STATE_ATTACHED = "attached"; const String STATE_FAULT = "fault"; - ////////////////////////////////////////////////////////////////////////// // Device Roles const String ROLE_END_DEVICE = "end-device"; const String ROLE_ROUTER = "router"; const String ROLE_SLEEPY_END_DEVICE = "sleepy-end-device"; const String ROLE_SLEEPY_ROUTER = "sleepy-router"; - const String ROLE_UNKNOWN = "unknown"; + const String ROLE_LEADER = "leader"; + const String ROLE_COORDINATOR = "coordinator"; + const String ROLE_DETACHED = "detached"; + + const String NETWORK_TYPE_UNKNOWN = "unknown"; + + /** + * Network type for Thread 1.x networks. + * + * @see android.net.lowpan.LowpanIdentity#getType + * @see #getLowpanIdentity + */ + const String NETWORK_TYPE_THREAD_V1 = "org.threadgroup.thread.v1"; - ////////////////////////////////////////////////////////////////////////// // Service-Specific Error Code Constants const int ERROR_UNSPECIFIED = 1; @@ -149,25 +95,49 @@ interface ILowpanInterface { const int ERROR_JOIN_FAILED_AT_AUTH = 14; const int ERROR_FORM_FAILED_AT_SCAN = 15; - ////////////////////////////////////////////////////////////////////////// // Methods @utf8InCpp String getName(); - void join(in Map parameters); - void form(in Map parameters); + @utf8InCpp String getNcpVersion(); + @utf8InCpp String getDriverVersion(); + LowpanChannelInfo[] getSupportedChannels(); + @utf8InCpp String[] getSupportedNetworkTypes(); + byte[] getMacAddress(); + + boolean isEnabled(); + void setEnabled(boolean enabled); + + boolean isUp(); + boolean isCommissioned(); + boolean isConnected(); + @utf8InCpp String getState(); + + @utf8InCpp String getRole(); + @utf8InCpp String getPartitionId(); + byte[] getExtendedAddress(); + + LowpanIdentity getLowpanIdentity(); + LowpanCredential getLowpanCredential(); + + @utf8InCpp String[] getLinkAddresses(); + IpPrefix[] getLinkNetworks(); + + void join(in LowpanProvision provision); + void form(in LowpanProvision provision); + void attach(in LowpanProvision provision); void leave(); void reset(); + void startCommissioningSession(in LowpanBeaconInfo beaconInfo); + void closeCommissioningSession(); + oneway void sendToCommissioner(in byte[] packet); + void beginLowPower(); - void pollForData(); + oneway void pollForData(); oneway void onHostWake(); - @utf8InCpp String[] getPropertyKeys(); - Map getProperties(in @utf8InCpp String[] keys); - void setProperties(in Map properties); - void addListener(ILowpanInterfaceListener listener); oneway void removeListener(ILowpanInterfaceListener listener); @@ -177,14 +147,9 @@ interface ILowpanInterface { void startEnergyScan(in Map properties, ILowpanEnergyScanCallback listener); oneway void stopEnergyScan(); - String[] copyLinkAddresses(); - IpPrefix[] copyLinkNetworks(); - void addOnMeshPrefix(in IpPrefix prefix, int flags); oneway void removeOnMeshPrefix(in IpPrefix prefix); void addExternalRoute(in IpPrefix prefix, int flags); oneway void removeExternalRoute(in IpPrefix prefix); - - @utf8InCpp String getPropertyAsString(@utf8InCpp String key); } diff --git a/lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl b/lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl index 0ae01a1873b5..5e4049a0fab8 100644 --- a/lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl +++ b/lowpan/java/android/net/lowpan/ILowpanInterfaceListener.aidl @@ -17,14 +17,29 @@ package android.net.lowpan; import android.net.IpPrefix; +import android.net.lowpan.LowpanIdentity; /** {@hide} */ interface ILowpanInterfaceListener { - oneway void onPropertiesChanged(in Map properties); + oneway void onEnabledChanged(boolean value); - oneway void onLinkNetworkAdded(in IpPrefix prefix); - oneway void onLinkNetworkRemoved(in IpPrefix prefix); + oneway void onConnectedChanged(boolean value); - oneway void onLinkAddressAdded(in String address); - oneway void onLinkAddressRemoved(in String address); + oneway void onUpChanged(boolean value); + + oneway void onRoleChanged(@utf8InCpp String value); + + oneway void onStateChanged(@utf8InCpp String value); + + oneway void onLowpanIdentityChanged(in LowpanIdentity value); + + oneway void onLinkNetworkAdded(in IpPrefix value); + + oneway void onLinkNetworkRemoved(in IpPrefix value); + + oneway void onLinkAddressAdded(@utf8InCpp String value); + + oneway void onLinkAddressRemoved(@utf8InCpp String value); + + oneway void onReceiveFromCommissioner(in byte[] packet); } diff --git a/lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl b/lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl index c20a6f8110c8..9743fce0b128 100644 --- a/lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl +++ b/lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 The Android Open Source Project + * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,8 +16,10 @@ package android.net.lowpan; +import android.net.lowpan.LowpanBeaconInfo; + /** {@hide} */ interface ILowpanNetScanCallback { - oneway void onNetScanBeacon(in Map parameters); + oneway void onNetScanBeacon(in LowpanBeaconInfo beacon); oneway void onNetScanFinished(); } diff --git a/lowpan/java/android/net/lowpan/LowpanCommissioningSession.java b/lowpan/java/android/net/lowpan/LowpanCommissioningSession.java index ee75f1aece5c..8f75e8db6243 100644 --- a/lowpan/java/android/net/lowpan/LowpanCommissioningSession.java +++ b/lowpan/java/android/net/lowpan/LowpanCommissioningSession.java @@ -18,9 +18,11 @@ package android.net.lowpan; import android.annotation.NonNull; import android.annotation.Nullable; -import android.net.Network; +import android.net.IpPrefix; +import android.os.DeadObjectException; import android.os.Handler; -import java.net.InetSocketAddress; +import android.os.Looper; +import android.os.RemoteException; /** * Commissioning Session. @@ -31,8 +33,15 @@ import java.net.InetSocketAddress; * @hide */ // @SystemApi -public abstract class LowpanCommissioningSession { - public LowpanCommissioningSession() {} +public class LowpanCommissioningSession { + + private final ILowpanInterface mBinder; + private final LowpanBeaconInfo mBeaconInfo; + private final ILowpanInterfaceListener mInternalCallback = new InternalCallback(); + private final Looper mLooper; + private Handler mHandler; + private Callback mCallback = null; + private volatile boolean mIsClosed = false; /** * Callback base class for {@link LowpanCommissioningSession} @@ -40,34 +49,175 @@ public abstract class LowpanCommissioningSession { * @hide */ // @SystemApi - public static abstract class Callback { + public abstract static class Callback { public void onReceiveFromCommissioner(@NonNull byte[] packet) {}; public void onClosed() {}; } + private class InternalCallback extends ILowpanInterfaceListener.Stub { + @Override + public void onStateChanged(String value) { + if (!mIsClosed) { + switch (value) { + case ILowpanInterface.STATE_OFFLINE: + case ILowpanInterface.STATE_FAULT: + synchronized (LowpanCommissioningSession.this) { + lockedCleanup(); + } + } + } + } + + @Override + public void onReceiveFromCommissioner(byte[] packet) { + mHandler.post( + () -> { + synchronized (LowpanCommissioningSession.this) { + if (!mIsClosed && (mCallback != null)) { + mCallback.onReceiveFromCommissioner(packet); + } + } + }); + } + + // We ignore all other callbacks. + @Override + public void onEnabledChanged(boolean value) {} + + @Override + public void onConnectedChanged(boolean value) {} + + @Override + public void onUpChanged(boolean value) {} + + @Override + public void onRoleChanged(String value) {} + + @Override + public void onLowpanIdentityChanged(LowpanIdentity value) {} + + @Override + public void onLinkNetworkAdded(IpPrefix value) {} + + @Override + public void onLinkNetworkRemoved(IpPrefix value) {} + + @Override + public void onLinkAddressAdded(String value) {} + + @Override + public void onLinkAddressRemoved(String value) {} + } + + LowpanCommissioningSession( + ILowpanInterface binder, LowpanBeaconInfo beaconInfo, Looper looper) { + mBinder = binder; + mBeaconInfo = beaconInfo; + mLooper = looper; + + if (mLooper != null) { + mHandler = new Handler(mLooper); + } else { + mHandler = new Handler(); + } + + try { + mBinder.addListener(mInternalCallback); + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + } + } + + private void lockedCleanup() { + // Note: this method is only called from synchronized contexts. + + if (!mIsClosed) { + try { + mBinder.removeListener(mInternalCallback); + + } catch (DeadObjectException x) { + /* We don't care if we receive a DOE at this point. + * DOE is as good as success as far as we are concerned. + */ + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + } + + if (mCallback != null) { + mHandler.post(() -> mCallback.onClosed()); + } + } + + mCallback = null; + mIsClosed = true; + } + /** TODO: doc */ @NonNull - public abstract LowpanBeaconInfo getBeaconInfo(); + public LowpanBeaconInfo getBeaconInfo() { + return mBeaconInfo; + } /** TODO: doc */ - public abstract void sendToCommissioner(@NonNull byte[] packet); + public void sendToCommissioner(@NonNull byte[] packet) { + if (!mIsClosed) { + try { + mBinder.sendToCommissioner(packet); + + } catch (DeadObjectException x) { + /* This method is a best-effort delivery. + * We don't care if we receive a DOE at this point. + */ + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + } + } + } /** TODO: doc */ - public abstract void setCallback(@Nullable Callback cb, @Nullable Handler handler); + public synchronized void setCallback(@Nullable Callback cb, @Nullable Handler handler) { + if (!mIsClosed) { + /* This class can be created with or without a default looper. + * Also, this method can be called with or without a specific + * handler. If a handler is specified, it is to always be used. + * Otherwise, if there was a Looper specified when this object + * was created, we create a new handle based on that looper. + * Otherwise we just create a default handler object. Since we + * don't really know how the previous handler was created, we + * end up always replacing it here. This isn't a huge problem + * because this method should be called infrequently. + */ + if (handler != null) { + mHandler = handler; + } else if (mLooper != null) { + mHandler = new Handler(mLooper); + } else { + mHandler = new Handler(); + } + mCallback = cb; + } + } /** TODO: doc */ - public abstract void close(); + public synchronized void close() { + if (!mIsClosed) { + try { + mBinder.closeCommissioningSession(); - /** - * This method is largely for Nest Weave, as an alternative to {@link #sendToCommissioner()} - * and @{link Callback#onReceiveFromCommissioner()}. - * - * <p>When used with the Network instance obtained from getNetwork(), the caller can use the - * given InetSocketAddress to communicate with the commissioner using a UDP (or, under certain - * circumstances, TCP) socket. - */ - public abstract @Nullable InetSocketAddress getInetSocketAddress(); + lockedCleanup(); - public abstract @Nullable Network getNetwork(); + } catch (DeadObjectException x) { + /* We don't care if we receive a DOE at this point. + * DOE is as good as success as far as we are concerned. + */ + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + } + } + } } diff --git a/lowpan/java/android/net/lowpan/LowpanInterface.java b/lowpan/java/android/net/lowpan/LowpanInterface.java index 55bf3994574d..57e91357b237 100644 --- a/lowpan/java/android/net/lowpan/LowpanInterface.java +++ b/lowpan/java/android/net/lowpan/LowpanInterface.java @@ -28,8 +28,6 @@ import android.os.RemoteException; import android.os.ServiceSpecificException; import android.util.Log; import java.util.HashMap; -import java.util.Map; -import java.util.Set; /** * Class for managing a specific Low-power Wireless Personal Area Network (LoWPAN) interface. @@ -41,13 +39,13 @@ public class LowpanInterface { private static final String TAG = LowpanInterface.class.getSimpleName(); /** Detached role. The interface is not currently attached to a network. */ - public static final String ROLE_DETACHED = "detached"; + public static final String ROLE_DETACHED = ILowpanInterface.ROLE_DETACHED; /** End-device role. End devices do not route traffic for other nodes. */ - public static final String ROLE_END_DEVICE = "end-device"; + public static final String ROLE_END_DEVICE = ILowpanInterface.ROLE_END_DEVICE; /** Router role. Routers help route traffic around the mesh network. */ - public static final String ROLE_ROUTER = "router"; + public static final String ROLE_ROUTER = ILowpanInterface.ROLE_ROUTER; /** * Sleepy End-Device role. @@ -57,7 +55,7 @@ public class LowpanInterface { * extraordinarilly low power consumption, but packet latency can be on the order of dozens of * seconds(depending on how the node is configured). */ - public static final String ROLE_SLEEPY_END_DEVICE = "sleepy-end-device"; + public static final String ROLE_SLEEPY_END_DEVICE = ILowpanInterface.ROLE_SLEEPY_END_DEVICE; /** * Sleepy-router role. @@ -65,13 +63,13 @@ public class LowpanInterface { * <p>Routers with this role are nominally asleep, waking up periodically to check in with other * routers and their children. */ - public static final String ROLE_SLEEPY_ROUTER = "sleepy-router"; + public static final String ROLE_SLEEPY_ROUTER = ILowpanInterface.ROLE_SLEEPY_ROUTER; /** TODO: doc */ - public static final String ROLE_LEADER = "leader"; + public static final String ROLE_LEADER = ILowpanInterface.ROLE_LEADER; /** TODO: doc */ - public static final String ROLE_COORDINATOR = "coordinator"; + public static final String ROLE_COORDINATOR = ILowpanInterface.ROLE_COORDINATOR; /** * Offline state. @@ -86,7 +84,7 @@ public class LowpanInterface { * @see #getState() * @see #STATE_FAULT */ - public static final String STATE_OFFLINE = "offline"; + public static final String STATE_OFFLINE = ILowpanInterface.STATE_OFFLINE; /** * Commissioning state. @@ -98,7 +96,7 @@ public class LowpanInterface { * @see #getState() * @hide */ - public static final String STATE_COMMISSIONING = "commissioning"; + public static final String STATE_COMMISSIONING = ILowpanInterface.STATE_COMMISSIONING; /** * Attaching state. @@ -116,7 +114,7 @@ public class LowpanInterface { * @see #STATE_ATTACHED * @see #getState() */ - public static final String STATE_ATTACHING = "attaching"; + public static final String STATE_ATTACHING = ILowpanInterface.STATE_ATTACHING; /** * Attached state. @@ -127,7 +125,7 @@ public class LowpanInterface { * @see #STATE_ATTACHING * @see #getState() */ - public static final String STATE_ATTACHED = "attached"; + public static final String STATE_ATTACHED = ILowpanInterface.STATE_ATTACHED; /** * Fault state. @@ -141,7 +139,7 @@ public class LowpanInterface { * @see #getState * @see #STATE_OFFLINE */ - public static final String STATE_FAULT = "fault"; + public static final String STATE_FAULT = ILowpanInterface.STATE_FAULT; /** * Network type for Thread 1.x networks. @@ -150,23 +148,9 @@ public class LowpanInterface { * @see #getLowpanIdentity * @hide */ - public static final String NETWORK_TYPE_THREAD = "org.threadgroup.thread.v1"; + public static final String NETWORK_TYPE_THREAD_V1 = ILowpanInterface.NETWORK_TYPE_THREAD_V1; - /** - * Network type for ZigBeeIP 1.x networks. - * - * @see android.net.lowpan.LowpanIdentity#getType - * @see #getLowpanIdentity - * @hide - */ - public static final String NETWORK_TYPE_ZIGBEE_IP = "org.zigbee.zigbeeip.v1"; - - private static final String NETWORK_PROPERTY_KEYS[] = { - LowpanProperties.KEY_NETWORK_NAME.getName(), - LowpanProperties.KEY_NETWORK_PANID.getName(), - LowpanProperties.KEY_NETWORK_XPANID.getName(), - LowpanProperties.KEY_CHANNEL.getName() - }; + public static final String EMPTY_PARTITION_ID = ""; /** * Callback base class for LowpanInterface @@ -187,8 +171,13 @@ public class LowpanInterface { public void onLowpanIdentityChanged(@NonNull LowpanIdentity value) {} - /** @hide */ - public void onPropertiesChanged(@NonNull Map properties) {} + public void onLinkNetworkAdded(IpPrefix prefix) {} + + public void onLinkNetworkRemoved(IpPrefix prefix) {} + + public void onLinkAddressAdded(LinkAddress address) {} + + public void onLinkAddressRemoved(LinkAddress address) {} } private final ILowpanInterface mBinder; @@ -222,74 +211,6 @@ public class LowpanInterface { return mBinder; } - // Private Property Helpers - - void setProperties(Map properties) throws LowpanException { - try { - mBinder.setProperties(properties); - - } catch (RemoteException x) { - throw x.rethrowAsRuntimeException(); - - } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); - } - } - - @NonNull - Map<String, Object> getProperties(String keys[]) throws LowpanException { - try { - return mBinder.getProperties(keys); - - } catch (RemoteException x) { - throw x.rethrowAsRuntimeException(); - - } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); - } - } - - /** @hide */ - public <T> void setProperty(LowpanProperty<T> key, T value) throws LowpanException { - HashMap<String, T> prop = new HashMap<>(); - prop.put(key.getName(), value); - setProperties(prop); - } - - /** @hide */ - @Nullable - public <T> T getProperty(LowpanProperty<T> key) throws LowpanException { - Map<String, Object> map = getProperties(new String[] {key.getName()}); - if (map != null && !map.isEmpty()) { - // We know there is only one value. - return (T) map.values().iterator().next(); - } - return null; - } - - @Nullable - <T> String getPropertyAsString(LowpanProperty<T> key) throws LowpanException { - try { - return mBinder.getPropertyAsString(key.getName()); - - } catch (RemoteException x) { - throw x.rethrowAsRuntimeException(); - - } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); - } - } - - int getPropertyAsInt(LowpanProperty<Integer> key) throws LowpanException { - Integer value = getProperty(key); - return (value != null) ? value : 0; - } - - boolean getPropertyAsBoolean(LowpanProperty<Boolean> key) throws LowpanException { - Boolean value = getProperty(key); - return (value != null) ? value : false; - } - // Public Actions /** @@ -306,15 +227,13 @@ public class LowpanInterface { */ public void form(@NonNull LowpanProvision provision) throws LowpanException { try { - Map<String, Object> parameters = new HashMap(); - provision.addToMap(parameters); - mBinder.form(parameters); + mBinder.form(provision); } catch (RemoteException x) { throw x.rethrowAsRuntimeException(); } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); + throw LowpanException.rethrowFromServiceSpecificException(x); } } @@ -328,15 +247,13 @@ public class LowpanInterface { */ public void join(@NonNull LowpanProvision provision) throws LowpanException { try { - Map<String, Object> parameters = new HashMap(); - provision.addToMap(parameters); - mBinder.join(parameters); + mBinder.join(provision); } catch (RemoteException x) { throw x.rethrowAsRuntimeException(); } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); + throw LowpanException.rethrowFromServiceSpecificException(x); } } @@ -348,13 +265,14 @@ public class LowpanInterface { * <p>This method will block execution until the operation has completed. */ public void attach(@NonNull LowpanProvision provision) throws LowpanException { - if (ROLE_DETACHED.equals(getRole())) { - Map<String, Object> parameters = new HashMap(); - provision.addToMap(parameters); - setProperties(parameters); - setUp(true); - } else { - throw new LowpanException(LowpanException.LOWPAN_ALREADY); + try { + mBinder.attach(provision); + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + + } catch (ServiceSpecificException x) { + throw LowpanException.rethrowFromServiceSpecificException(x); } } @@ -372,7 +290,7 @@ public class LowpanInterface { throw x.rethrowAsRuntimeException(); } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); + throw LowpanException.rethrowFromServiceSpecificException(x); } } @@ -382,9 +300,17 @@ public class LowpanInterface { */ public @NonNull LowpanCommissioningSession startCommissioningSession( @NonNull LowpanBeaconInfo beaconInfo) throws LowpanException { + try { + mBinder.startCommissioningSession(beaconInfo); + + return new LowpanCommissioningSession(mBinder, beaconInfo, mLooper); + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); - /* TODO: Implement startCommissioningSession */ - throw new LowpanException(LowpanException.LOWPAN_FEATURE_NOT_SUPPORTED); + } catch (ServiceSpecificException x) { + throw LowpanException.rethrowFromServiceSpecificException(x); + } } /** @@ -403,7 +329,7 @@ public class LowpanInterface { throw x.rethrowAsRuntimeException(); } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); + throw LowpanException.rethrowFromServiceSpecificException(x); } } @@ -415,6 +341,9 @@ public class LowpanInterface { try { return mBinder.getName(); + } catch (DeadObjectException x) { + return ""; + } catch (RemoteException x) { throw x.rethrowAsRuntimeException(); } @@ -428,9 +357,13 @@ public class LowpanInterface { */ public boolean isEnabled() { try { - return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_ENABLED); - } catch (LowpanException x) { + return mBinder.isEnabled(); + + } catch (DeadObjectException x) { return false; + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); } } @@ -444,7 +377,15 @@ public class LowpanInterface { * @hide */ public void setEnabled(boolean enabled) throws LowpanException { - setProperty(LowpanProperties.KEY_INTERFACE_ENABLED, enabled); + try { + mBinder.setEnabled(enabled); + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + + } catch (ServiceSpecificException x) { + throw LowpanException.rethrowFromServiceSpecificException(x); + } } /** @@ -454,22 +395,14 @@ public class LowpanInterface { */ public boolean isUp() { try { - return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_UP); - } catch (LowpanException x) { + return mBinder.isUp(); + + } catch (DeadObjectException x) { return false; - } - } - /** - * Bring up or shut down the network interface. - * - * <p>This method brings up or shuts down the network interface, attaching or (gracefully) - * detaching from the currently configured LoWPAN network as appropriate. - * - * @hide - */ - public void setUp(boolean interfaceUp) throws LowpanException { - setProperty(LowpanProperties.KEY_INTERFACE_UP, interfaceUp); + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + } } /** @@ -480,9 +413,13 @@ public class LowpanInterface { */ public boolean isConnected() { try { - return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_CONNECTED); - } catch (LowpanException x) { + return mBinder.isConnected(); + + } catch (DeadObjectException x) { return false; + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); } } @@ -492,9 +429,13 @@ public class LowpanInterface { */ public boolean isCommissioned() { try { - return getPropertyAsBoolean(LowpanProperties.KEY_INTERFACE_COMMISSIONED); - } catch (LowpanException x) { + return mBinder.isCommissioned(); + + } catch (DeadObjectException x) { return false; + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); } } @@ -514,90 +455,89 @@ public class LowpanInterface { */ public String getState() { try { - return getProperty(LowpanProperties.KEY_INTERFACE_STATE); - } catch (LowpanException x) { - Log.e(TAG, x.toString()); + return mBinder.getState(); + + } catch (DeadObjectException x) { return STATE_FAULT; + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + } + } + + /** Get network partition/fragment identifier. */ + public String getPartitionId() { + try { + return mBinder.getPartitionId(); + + } catch (DeadObjectException x) { + return EMPTY_PARTITION_ID; + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); } } /** TODO: doc */ public LowpanIdentity getLowpanIdentity() { - LowpanIdentity.Builder builder = new LowpanIdentity.Builder(); try { - builder.updateFromMap(getProperties(NETWORK_PROPERTY_KEYS)); - } catch (LowpanException x) { - // We ignore all LoWPAN-specitic exceptions here. - } + return mBinder.getLowpanIdentity(); - return builder.build(); - } + } catch (DeadObjectException x) { + return new LowpanIdentity(); - /** - * TODO: doc - * - * @hide - */ - public void setLowpanIdentity(LowpanIdentity network) throws LowpanException { - Map<String, Object> map = new HashMap(); - LowpanIdentity.addToMap(map, network); - setProperties(map); + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + } } /** TODO: doc */ @NonNull public String getRole() { - String role = null; - try { - role = getProperty(LowpanProperties.KEY_NETWORK_ROLE); - } catch (LowpanException x) { - // We ignore all LoWPAN-specitic exceptions here. - Log.e(TAG, x.toString()); - } + return mBinder.getRole(); - if (role == null) { - role = ROLE_DETACHED; - } + } catch (DeadObjectException x) { + return ROLE_DETACHED; - return role; + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + } } /** TODO: doc */ @Nullable public LowpanCredential getLowpanCredential() { - LowpanCredential credential = null; - try { - Integer keyIndex = getProperty(LowpanProperties.KEY_NETWORK_MASTER_KEY_INDEX); - - if (keyIndex == null) { - credential = - LowpanCredential.createMasterKey( - getProperty(LowpanProperties.KEY_NETWORK_MASTER_KEY)); - } else { - credential = - LowpanCredential.createMasterKey( - getProperty(LowpanProperties.KEY_NETWORK_MASTER_KEY), - keyIndex.intValue()); - } - } catch (LowpanException x) { - // We ignore all LoWPAN-specitic exceptions here. - Log.e(TAG, x.toString()); + return mBinder.getLowpanCredential(); + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); } + } + + public @NonNull String[] getSupportedNetworkTypes() throws LowpanException { + try { + return mBinder.getSupportedNetworkTypes(); - return credential; + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + + } catch (ServiceSpecificException x) { + throw LowpanException.rethrowFromServiceSpecificException(x); + } } - /** - * TODO: doc - * - * @hide - */ - public void setLowpanCredential(LowpanCredential networkCredential) throws LowpanException { - Map<String, Object> map = new HashMap(); - networkCredential.addToMap(map); - setProperties(map); + public @NonNull LowpanChannelInfo[] getSupportedChannels() throws LowpanException { + try { + return mBinder.getSupportedChannels(); + + } catch (RemoteException x) { + throw x.rethrowAsRuntimeException(); + + } catch (ServiceSpecificException x) { + throw LowpanException.rethrowFromServiceSpecificException(x); + } } // Listener Support @@ -627,57 +567,80 @@ public class LowpanInterface { } } - @Override public void onPropertiesChanged(Map properties) { - Runnable runnable = - () -> { - for (String key : (Set<String>) properties.keySet()) { - Object value = properties.get(key); - switch (key) { - case ILowpanInterface.KEY_INTERFACE_ENABLED: - cb.onEnabledChanged( - ((Boolean) value).booleanValue()); - break; - case ILowpanInterface.KEY_INTERFACE_UP: - cb.onUpChanged(((Boolean) value).booleanValue()); - break; - case ILowpanInterface.KEY_INTERFACE_CONNECTED: - cb.onConnectedChanged( - ((Boolean) value).booleanValue()); - break; - case ILowpanInterface.KEY_INTERFACE_STATE: - cb.onStateChanged((String) value); - break; - case ILowpanInterface.KEY_NETWORK_NAME: - case ILowpanInterface.KEY_NETWORK_PANID: - case ILowpanInterface.KEY_NETWORK_XPANID: - case ILowpanInterface.KEY_CHANNEL: - cb.onLowpanIdentityChanged(getLowpanIdentity()); - break; - case ILowpanInterface.KEY_NETWORK_ROLE: - cb.onRoleChanged(value.toString()); - break; - } - } - cb.onPropertiesChanged(properties); - }; - - mHandler.post(runnable); + @Override + public void onEnabledChanged(boolean value) { + mHandler.post(() -> cb.onEnabledChanged(value)); + } + + @Override + public void onConnectedChanged(boolean value) { + mHandler.post(() -> cb.onConnectedChanged(value)); + } + + @Override + public void onUpChanged(boolean value) { + mHandler.post(() -> cb.onUpChanged(value)); } - @Override public void onLinkNetworkAdded(IpPrefix prefix) { - // Support for this event isn't yet implemented. + @Override + public void onRoleChanged(String value) { + mHandler.post(() -> cb.onRoleChanged(value)); } - @Override public void onLinkNetworkRemoved(IpPrefix prefix) { - // Support for this event isn't yet implemented. + @Override + public void onStateChanged(String value) { + mHandler.post(() -> cb.onStateChanged(value)); } - @Override public void onLinkAddressAdded(String address) { - // Support for this event isn't yet implemented. + @Override + public void onLowpanIdentityChanged(LowpanIdentity value) { + mHandler.post(() -> cb.onLowpanIdentityChanged(value)); + } + + @Override + public void onLinkNetworkAdded(IpPrefix value) { + mHandler.post(() -> cb.onLinkNetworkAdded(value)); + } + + @Override + public void onLinkNetworkRemoved(IpPrefix value) { + mHandler.post(() -> cb.onLinkNetworkRemoved(value)); + } + + @Override + public void onLinkAddressAdded(String value) { + LinkAddress la; + try { + la = new LinkAddress(value); + } catch (IllegalArgumentException x) { + Log.e( + TAG, + "onLinkAddressAdded: Bad LinkAddress \"" + value + "\", " + x); + return; + } + mHandler.post(() -> cb.onLinkAddressAdded(la)); + } + + @Override + public void onLinkAddressRemoved(String value) { + LinkAddress la; + try { + la = new LinkAddress(value); + } catch (IllegalArgumentException x) { + Log.e( + TAG, + "onLinkAddressRemoved: Bad LinkAddress \"" + + value + + "\", " + + x); + return; + } + mHandler.post(() -> cb.onLinkAddressRemoved(la)); } - @Override public void onLinkAddressRemoved(String address) { - // Support for this event isn't yet implemented. + @Override + public void onReceiveFromCommissioner(byte[] packet) { + // This is only used by the LowpanCommissioningSession. } }; try { @@ -752,9 +715,9 @@ public class LowpanInterface { * * @hide */ - public LinkAddress[] copyLinkAddresses() throws LowpanException { + public LinkAddress[] getLinkAddresses() throws LowpanException { try { - String[] linkAddressStrings = mBinder.copyLinkAddresses(); + String[] linkAddressStrings = mBinder.getLinkAddresses(); LinkAddress[] ret = new LinkAddress[linkAddressStrings.length]; int i = 0; for (String str : linkAddressStrings) { @@ -766,7 +729,7 @@ public class LowpanInterface { throw x.rethrowAsRuntimeException(); } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); + throw LowpanException.rethrowFromServiceSpecificException(x); } } @@ -775,15 +738,15 @@ public class LowpanInterface { * * @hide */ - public IpPrefix[] copyLinkNetworks() throws LowpanException { + public IpPrefix[] getLinkNetworks() throws LowpanException { try { - return mBinder.copyLinkNetworks(); + return mBinder.getLinkNetworks(); } catch (RemoteException x) { throw x.rethrowAsRuntimeException(); } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); + throw LowpanException.rethrowFromServiceSpecificException(x); } } @@ -800,7 +763,7 @@ public class LowpanInterface { throw x.rethrowAsRuntimeException(); } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); + throw LowpanException.rethrowFromServiceSpecificException(x); } } @@ -837,7 +800,7 @@ public class LowpanInterface { throw x.rethrowAsRuntimeException(); } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); + throw LowpanException.rethrowFromServiceSpecificException(x); } } diff --git a/lowpan/java/android/net/lowpan/LowpanProperties.java b/lowpan/java/android/net/lowpan/LowpanProperties.java index f835260b842e..cc45ff85f723 100644 --- a/lowpan/java/android/net/lowpan/LowpanProperties.java +++ b/lowpan/java/android/net/lowpan/LowpanProperties.java @@ -16,74 +16,14 @@ package android.net.lowpan; -import android.net.IpPrefix; -import android.net.LinkAddress; - /** {@hide} */ public final class LowpanProperties { - public static final LowpanProperty<Boolean> KEY_INTERFACE_ENABLED = - new LowpanStandardProperty( - "android.net.lowpan.property.INTERFACE_ENABLED", Boolean.class); - public static final LowpanProperty<Boolean> KEY_INTERFACE_COMMISSIONED = - new LowpanStandardProperty( - "android.net.lowpan.property.INTERFACE_COMMISSIONED", Boolean.class); - public static final LowpanProperty<Boolean> KEY_INTERFACE_CONNECTED = - new LowpanStandardProperty( - "android.net.lowpan.property.INTERFACE_CONNECTED", Boolean.class); - public static final LowpanProperty<Boolean> KEY_INTERFACE_UP = - new LowpanStandardProperty("android.net.lowpan.property.INTERFACE_UP", Boolean.class); - public static final LowpanProperty<String> KEY_INTERFACE_STATE = - new LowpanStandardProperty("android.net.lowpan.property.INTERFACE_STATE", String.class); - - public static final LowpanProperty<String> KEY_NETWORK_NAME = - new LowpanStandardProperty("android.net.lowpan.property.NETWORK_NAME", Boolean.class); - public static final LowpanProperty<Integer> KEY_NETWORK_PANID = - new LowpanStandardProperty("android.net.lowpan.property.NETWORK_PANID", Integer.class); - public static final LowpanProperty<byte[]> KEY_NETWORK_XPANID = - new LowpanStandardProperty("android.net.lowpan.property.NETWORK_XPANID", byte[].class); - public static final LowpanProperty<byte[]> KEY_NETWORK_MASTER_KEY = - new LowpanStandardProperty( - "android.net.lowpan.property.NETWORK_MASTER_KEY", byte[].class); - public static final LowpanProperty<Integer> KEY_NETWORK_MASTER_KEY_INDEX = - new LowpanStandardProperty( - "android.net.lowpan.property.NETWORK_MASTER_KEY_INDEX", Integer.class); - public static final LowpanProperty<Integer> KEY_NETWORK_TYPE = - new LowpanStandardProperty("android.net.lowpan.property.NETWORK_TYPE", Integer.class); - public static final LowpanProperty<String> KEY_NETWORK_ROLE = - new LowpanStandardProperty("android.net.lowpan.property.NETWORK_ROLE", String.class); - - public static final LowpanProperty<Integer> KEY_CHANNEL = - new LowpanStandardProperty("android.net.lowpan.property.CHANNEL", Integer.class); public static final LowpanProperty<int[]> KEY_CHANNEL_MASK = new LowpanStandardProperty("android.net.lowpan.property.CHANNEL_MASK", int[].class); + public static final LowpanProperty<Integer> KEY_MAX_TX_POWER = new LowpanStandardProperty("android.net.lowpan.property.MAX_TX_POWER", Integer.class); - public static final LowpanProperty<Integer> KEY_RSSI = - new LowpanStandardProperty("android.net.lowpan.property.RSSI", Integer.class); - - public static final LowpanProperty<Integer> KEY_LQI = - new LowpanStandardProperty("android.net.lowpan.property.LQI", Integer.class); - public static final LowpanProperty<byte[]> KEY_BEACON_ADDRESS = - new LowpanStandardProperty("android.net.lowpan.property.BEACON_ADDRESS", byte[].class); - public static final LowpanProperty<Boolean> KEY_BEACON_CAN_ASSIST = - new LowpanStandardProperty( - "android.net.lowpan.property.BEACON_CAN_ASSIST", Boolean.class); - - public static final LowpanProperty<String> KEY_DRIVER_VERSION = - new LowpanStandardProperty("android.net.lowpan.property.DRIVER_VERSION", String.class); - - public static final LowpanProperty<String> KEY_NCP_VERSION = - new LowpanStandardProperty("android.net.lowpan.property.NCP_VERSION", String.class); - - /** @hide */ - public static final LowpanProperty<byte[]> KEY_EXTENDED_ADDRESS = - new LowpanStandardProperty( - "android.net.lowpan.property.EXTENDED_ADDRESS", byte[].class); - - /** @hide */ - public static final LowpanProperty<byte[]> KEY_MAC_ADDRESS = - new LowpanStandardProperty("android.net.lowpan.property.MAC_ADDRESS", byte[].class); /** @hide */ private LowpanProperties() {} diff --git a/lowpan/java/android/net/lowpan/LowpanScanner.java b/lowpan/java/android/net/lowpan/LowpanScanner.java index b0557ee5c19b..59156c429010 100644 --- a/lowpan/java/android/net/lowpan/LowpanScanner.java +++ b/lowpan/java/android/net/lowpan/LowpanScanner.java @@ -21,7 +21,6 @@ import android.annotation.Nullable; import android.os.Handler; import android.os.RemoteException; import android.os.ServiceSpecificException; -import android.util.Log; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -37,7 +36,7 @@ import java.util.Map; */ // @SystemApi public class LowpanScanner { - private static final String TAG = LowpanInterface.class.getSimpleName(); + private static final String TAG = LowpanScanner.class.getSimpleName(); // Public Classes @@ -174,7 +173,7 @@ public class LowpanScanner { ILowpanNetScanCallback binderListener = new ILowpanNetScanCallback.Stub() { - public void onNetScanBeacon(Map parameters) { + public void onNetScanBeacon(LowpanBeaconInfo beaconInfo) { Callback callback; Handler handler; @@ -187,12 +186,7 @@ public class LowpanScanner { return; } - Runnable runnable = - () -> - callback.onNetScanBeacon( - new LowpanBeaconInfo.Builder() - .updateFromMap(parameters) - .build()); + Runnable runnable = () -> callback.onNetScanBeacon(beaconInfo); if (handler != null) { handler.post(runnable); @@ -231,7 +225,7 @@ public class LowpanScanner { throw x.rethrowAsRuntimeException(); } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); + throw LowpanException.rethrowFromServiceSpecificException(x); } } @@ -246,9 +240,6 @@ public class LowpanScanner { } catch (RemoteException x) { throw x.rethrowAsRuntimeException(); - - } catch (ServiceSpecificException x) { - Log.e(TAG, x.toString()); } } @@ -315,7 +306,7 @@ public class LowpanScanner { throw x.rethrowAsRuntimeException(); } catch (ServiceSpecificException x) { - throw LowpanException.rethrowAsLowpanException(x); + throw LowpanException.rethrowFromServiceSpecificException(x); } } @@ -330,9 +321,6 @@ public class LowpanScanner { } catch (RemoteException x) { throw x.rethrowAsRuntimeException(); - - } catch (ServiceSpecificException x) { - Log.e(TAG, x.toString()); } } } diff --git a/lowpan/tests/java/android/net/lowpan/LowpanInterfaceTest.java b/lowpan/tests/java/android/net/lowpan/LowpanInterfaceTest.java index a495d3d7a784..f26a37ed71ce 100644 --- a/lowpan/tests/java/android/net/lowpan/LowpanInterfaceTest.java +++ b/lowpan/tests/java/android/net/lowpan/LowpanInterfaceTest.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.*; import android.content.Context; import android.content.pm.ApplicationInfo; +import android.net.LinkAddress; import android.os.Handler; import android.os.IBinder; import android.os.test.TestLooper; @@ -86,4 +87,66 @@ public class LowpanInterfaceTest { .onStateChanged( argThat(stateString -> stateString.equals(LowpanInterface.STATE_OFFLINE))); } + + @Test + public void testLinkAddressCallback() throws Exception { + // Register our callback + mLowpanInterface.registerCallback(mLowpanInterfaceCallback); + + // Verify a listener was added + verify(mLowpanInterfaceService) + .addListener( + argThat( + listener -> { + mInterfaceListener = listener; + return listener instanceof ILowpanInterfaceListener; + })); + + final LinkAddress linkAddress = new LinkAddress("fe80::1/64"); + + // Change some properties + mInterfaceListener.onLinkAddressAdded(linkAddress.toString()); + mTestLooper.dispatchAll(); + + // Verify that the property was changed + verify(mLowpanInterfaceCallback) + .onLinkAddressAdded(argThat(addr -> addr.equals(linkAddress))); + + // Change some properties + mInterfaceListener.onLinkAddressRemoved(linkAddress.toString()); + mTestLooper.dispatchAll(); + + // Verify that the property was changed + verify(mLowpanInterfaceCallback) + .onLinkAddressRemoved(argThat(addr -> addr.equals(linkAddress))); + } + + @Test + public void testBogusLinkAddressCallback() throws Exception { + // Register our callback + mLowpanInterface.registerCallback(mLowpanInterfaceCallback); + + // Verify a listener was added + verify(mLowpanInterfaceService) + .addListener( + argThat( + listener -> { + mInterfaceListener = listener; + return listener instanceof ILowpanInterfaceListener; + })); + + // Change some properties + mInterfaceListener.onLinkAddressAdded("fe80:::1/640"); + mTestLooper.dispatchAll(); + + // Verify that no callback was called. + verifyNoMoreInteractions(mLowpanInterfaceCallback); + + // Change some properties + mInterfaceListener.onLinkAddressRemoved("fe80:::1/640"); + mTestLooper.dispatchAll(); + + // Verify that no callback was called. + verifyNoMoreInteractions(mLowpanInterfaceCallback); + } } |