Skip to content

Most visited

Recently visited

navigation

LoWPAN

The Low-Power Wireless Personal Area Networks (LoWPAN) API enables developers to manage and configure IP-based, low-power, lossy networks, such as Thread networks.

On these networks, Android devices can communicate directly with other peer devices, even ultra-low power battery operated nodes that may not have WiFi or Bluetooth connectivity (such as door locks and window sensors). These IPv6 mesh networks are secure and resilient with no single point of failure.

The Android Things LoWPAN API enables applications to perform the following functions:

In order for devices to participate on the same network they must all share the same provisioning parameters, consisting of the network identity and the network credential. If either of these parameters are different, devices will be unable to communicate with each other.

Hardware considerations

To develop LoWPAN applications, you will need a radio module running as an OpenThread Network Co-Processor (NCP). One recommended kit is the nRF52840-PDK. You will need a standard micro USB-B to USB-A cable to connect this kit to your Android Things device.

To get OpenThread running on the development kit, follow the instructions on this page.

Managing the interface connection

In order for the device to be associated with a LoWPAN network, you need to get an instance of class LowpanInterface. Class LowpanManager does this for you. Your application can use this manager to look up LowpanInterface objects on your Android device.

Provisioning parameters, such as the network identity information (LowpanIdentity) and the associated credential (LowpanCredential), are stored persistently and are automatically restored at boot-up. To forget these parameters, you must explicitly abandon the network by calling leave().

public class HomeActivity extends Activity {

    LowpanInterface mLowpanInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        LowpanManager lowpanManager = LowpanManager.getManager();
        mLowpanInterface = lowpanManager.getInterface(); // Or get an interface by name
        if (mLowpanInterface == null) {
            // Is the radio module connected and a user driver registered?
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        /* Detach from any network we might be attached to. */
        if (mLowpanInterface != null) {
            mLowpanInterface.leave();
        }
    }
}

Scanning for nearby networks

Create a LowpanScanner with callbacks to handle received events.

LowpanScanner mLowpanScanner;

private void scanForNetworks() throws LowpanException {
    mLowpanScanner = mLowpanInterface.createScanner();
    mLowpanScanner.setCallback(mScanCallback);
    mLowpanScanner.startNetScan();
}

private void stopNetworkScan() {
    mLowpanScanner.stopNetScan();
}

private LowpanScanner.Callback mScanCallback = new LowpanScanner.Callback() {
    @Override
    public void onNetScanBeacon(LowpanBeaconInfo beacon) {
        LowpanIdentity network = beacon.getLowpanIdentity();
        Log.d("LoWPAN", "Network Beacon: " + network.getName());

    }

    @Override
    public void onScanFinished() {
        // Release a semaphore
    }
};

Once the scan is finished, you should have a list of available networks.

Joining an existing network

Use the join() method of LowpanInterface when you know there is at least one other device in range on the network you are trying to join and you want the application to fail hard if it can't find it.

First, you need a LowpanProvisioningParams object. Create one using a LowpanIdentity object and a LowpanCredential object. Call the join() method of class LowpanInterface with the provisioning parameters (LowpanProvisioningParams) to create the network.

You can also obtain the LowpanIdentity object from a scan of available networks (see Scanning for nearby networks for the callback definitions).

private void joinNetwork(LowpanInterface lowpanInterface) throws LowpanException {

    final LowpanIdentity identity = new LowpanIdentity.Builder()
            .setName("YourNetwork")
            .setXpanid("DEBA7AB1E5EAF00D")
            .setPanid(0x1337)
            .setChannel(15)
            .build();

    final LowpanCredential credential = LowpanCredential
            .createMasterKey("00112233445566778899AABBCCDDEEFF");

    final LowpanProvisioningParams provision = new LowpanProvisioningParams.Builder()
            .setLowpanIdentity(identity)
            .setLowpanCredential(credential)
            .build();

    lowpanInterface.join(provision);
}

For the LowpanCredential object, you will need to obtain the credential out-of-band (for example, through wifi or the cloud) or supply your own. This is known as out-of-band commissioning.

Creating a new network

Use form() to create a new, empty network with only the device on it. Many of the provisioning fields can be autogenerated with reasonable, non-conflicting defaults. When you use form(), there must not be an existing partition in range with the same network parameters (LowpanIdentity) or else the operation will fail.

The LowpanProvisioningParams object passed to form() may be underspecified: fields in LowpanInterface that aren't specified will be filled in with reasonable, non-conflicting defaults. If a LowpanCredential isn't in the provision, a new one will be securely generated.

Call the form() method of class LowpanInterface with the provisioning parameters (LowpanProvisioningParams) to create the network.

private void formNetwork(LowpanInterface lowpanInterface) throws LowpanException {

    /* We are only specifying the network name here. By
     * doing this we allow the interface to pick reasonable
     * defaults for other required fields. If we specified
     * our own values for those fields, they would be used
     * instead.
     */
    final LowpanIdentity identity = new LowpanIdentity.Builder()
            .setName("MyNetwork")
            .build();

    /* Not specifying a LowpanCredential here tells “form()”
     * that we want the interface to generate the master key
     * for us.
     */
    final LowpanProvisioningParams provision = new LowpanProvisioningParams.Builder()
            .setLowpanIdentity(identity)
            .build();

    lowpanInterface.form(provision);
}

Monitoring connectivity and state changes

Attach a LowpanInterface.Callback to listen for state changes on a specific interface. The onLowpanIdentityChanged() method reports a successful attempt to create or join a network. If an error occurs during this process, it is reported through the onProvisionException() method.

You can use onStateChanged() to react to low-level events from the hardware, such as when an interface is enabled or a fault has occurred and the LowpanInterface needs to be reset.

public class HomeActivity extends Activity {

    LowpanInterface mLowpanInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...

        mLowpanInterface.registerCallback(mCallback);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        mLowpanInterface.unregisterCallback(mCallback);
        ...
    }

    private LowpanInterface.Callback mCallback = new LowpanInterface.Callback() {

        @Override
        public void onStateChanged(int state) {
            /* Handle interface state changes. */
        }

        @Override
        public void onLowpanIdentityChanged(LowpanIdentity identity) {
            /* Form, join, or leave completed successfully. */
        }

        @Override
        public void onProvisionException(Exception exception) {
            /* An error occurred during form or join. */
        }
    };
}

Add the required permissions

Accessing the LowpanManager API requires the ACCESS_LOWPAN_STATE permission. Creating and joining networks from a LowpanInterface requires the CHANGE_LOWPAN_STATE permission. Add the required permissions to your app's manifest file:

<uses-permission android:name="com.google.android.things.permission.ACCESS_LOWPAN_STATE" />
<uses-permission android:name="com.google.android.things.permission.CHANGE_LOWPAN_STATE" />

Command line reference

During development and testing, you can use the lowpanctl command line tool to perform LoWPAN operations on registered interfaces and verify status:

lowpanctl [options] command

Use an adb shell to access this tool.

The table below lists the supported commands and explains their meaning and usage.

Global Options Description
{-I | --interface} interface Target LoWPAN interface (e.g. wpan1). If this option is omitted, commands will operate on the default interface.
Interface Commands Description
list List the available LoWPAN interfaces on the device.
status Display information about the LoWPAN interface, such as the IP address and current network parameters.
enable Enable the LoWPAN interface. This will re-attach to the current network if the network unless the parameters were cleared with leave.
disable Disable the LoWPAN interface. This will detach from the current network and remember the network parameters.
reset Send a reset command to the LoWPAN interface.
Network Options Description
--name network_name Name of the LoWPAN network.
{-p | --panid} panid PANID to associate with the network.
{-c | --channel} channel Wireless channel to use for the network.
{-x | --xpanid} xpanid XPANID to associate with the network.
{-k | --master-key} master_key Master key to use as the network credential.
Network Commands Description
scan Initiate a scan for nearby LoWPAN networks and list the results.
form [network_options] Create a new LoWPAN network.
join [network_options] Join an existing LoWPAN network. Will return an error if the network does not exist or the supplied credentials are invalid for that network.
attach [network_options] Provision the LoWPAN interface with the given network info.
leave Detach from the current LoWPAN network and forget the network parameters.
show-credential Display the network credential for the currently attached network.

The following example demonstrates using lowpanctl to form a new network and verify that the interface is attached:

$ adb shell lowpanctl list
wpan1

$ adb shell lowpanctl -I wpan1 status
wpan1   offline (detached) UP

$ adb shell lowpanctl -I wpan1 form --name testnetwork
Forming Name:testnetwork
Formed.

$ adb shell lowpanctl -I wpan1 status
wpan1   attached (leader) UP CONNECTED COMMISSIONED
    Name:testnetwork, PANID:0x1337, Channel:25
    fdcb:2c9e:2fb8:0:ac7a:efe9:1b0c:d40a/64
    fe80::d097:3908:99c1:c647/64
This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Follow Google Developers on WeChat

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience. (Dec 2017 Android Platform & Tools Survey)