Network Example

PART 3. ESF Examples
Network Configuration Example

 

Overview

·         Prerequisites

Network Configuration with ESF

·         Hardware Setup

·         Determining Your Network Interfaces

·         ESF Networking API

Connecting to an Access Point

·         Implement the Bundle

·         Deploying the Bundle

Create an Access Point

·         Testing Your Access Point

Overview

This section provides an example showing how to create an ESF bundle that can be used to reconfigure the network interfaces of your device.  In this example, you will learn how to

 

·         Create a plugin that configures the network interfaces

·         Connect to a wireless access point

·         Create a wireless access point

 

As written, the example code simply configures the device with a static Wi-Fi configuration.  In most normal usage, you would not use Java code to do this, but rather you would simply configure the device’s settings through the ESF Gateway Administration configuration Web page. 

 

A more likely way in which this example could be used is for an application in which the IP network interfaces need to be dynamically modified based on some external trigger or condition, such as geo-fencing.  The ESF software allows the device to be programmatically changed via its APIs based on application-specific logic.

 

Prerequisites

·         Setting up ESF Development Environment

·         Hello World Using the ESF Logger

 


Network Configuration with ESF

Hardware Setup

For this example, you will need to have available an embedded device running ESF with at least one Ethernet port and Wi-Fi support.

 

For the Connecting to an Access Point section you will also need a wireless access point, and you will need to know the following information about the access point:

·         SSID (Network Name)

·         Security Type (WEP, WPA, or WPA2), if any

·         Password/Passphrase, if any

 

For the Creating an Access Point section, you will also need:

·         A wireless device, such as a laptop, to test the access point

·         Optionally, you may connect the ESF device’s Ethernet port to another network, to use ESF as a gateway to that network

 

Determining Your Network Interfaces

In order to determine your network interfaces, run one of the following commands at a terminal on the embedded gateway:

 

ifconfig -a

or

ip link show

 

Typical network interfaces will look like

  • lo – Loopback interface.
  • eth0 – First Ethernet network interface.
  • wlan0 – First Wireless network interface.
  • ppp0 – First Point-to-Point Protocol network interface which could be a dial up modem, PPTP VPN connection, cellular modem, etc.

 

Make note of your wireless interface.  For this tutorial, we will assume the wireless interface name is ‘wlan0’.

 

ESF Networking API

The networking API consists of two basic services: com.eurotech.framework.net.NetworkService and com.eurotech.framework.net.NetworkAdminService.

 

The NetworkService is used to get the current state of the network.  For example, the getNetworkInterfaces() method will return a List of NetInterface objects (such as EthernetInterface or WifiInterface) for each interface.  These provide a detailed representation of the current state of that interface, such as its type, whether it is currently up, and its current address, which is returned by the getNetInterfaceAddresses() method as a List of NetInterfaceAddress objects.  The NetworkService can also be used to get a List of all the network interface names available on the system, or a List of all the Wi-Fi access points that can currently be detected from the system.

 

The NetworkAdminService is used to get and set the configuration for each interface.  Similar to the NetworkService, it has a getNetworkInterfaceConfigs() which returns a List of NetInterfaceConfig objects (such as EthernetInterfaceConfig and WifiInterfaceConfig) for each interface.  These have the same methods as a NetInterface object, but represent the current configuration for that interface.  For a NetInterfaceConfig object, the getNetInterfaceAddress() method will return a List of NetInterfaceAddressConfig objects.  These NetInterfaceAddressConfig instances in turn contain a List of NetConfig objects that define the configuration for that interface.

 

There are many types of NetConfig objects, including:

·         NetConfigIP4 – Contains the IPv4 address configuration

·         WifiConfig – Contains the Wi-Fi configuration
Note that a WifiInterfaceAddressConfig may contain multiple WifiConfigs, since a configuration might exist for one or more Wi-Fi modes.  The currently active WifiConfig is the one with a WifiMode that matches the WifiInterfaceAddressConfig WifiMode.

·         DhcpServerConfigIP4 – Contains the IPv4-based DHCP server configuration

·         DnsServerConfigIP4 – Contains the IPv4-based DNS server configuration

·         FirewallNatConfig – Contains the firewall NAT configuration

 

These NetConfigs can also be used to configure an interface by providing them as a List to the updateEthernetInterfaceConfig(), updateWifiInterfaceConfig(), or updateModemInterfaceConfig() methods in the NetworkAdminService.

 


Connecting to an Access Point

In this section, you will write an ESF network configuration bundle that sets up the Wi-Fi interface as a client to a wireless access point.

 

Implementing the Bundle

To implement this network configuration bundle, you will use the same general method as in the Hello World Using the ESF Logger, but the actual code in this example will have the following differences from the Hello World example:

 

·         Create a new Plug-in Project named “com.eurotech.example.network” instead of “com.eurotech.example.hello_osgi”, and set an OSGi framework to standard.  Uncheck Generate an activator and set the Execution Environment to match the JVM on your target device.

·         In the Imported Packages section of the Dependencies tab of the MANIFEST.MF include the following packages:

o   com.eurotech.framework

o   com.eurotech.framework.net

o   com.eurotech.framework.net.dhcp

o   com.eurotech.framework.net.firewall

o   com.eurotech.framework.net.wifi

o   org.osgi.service.component

o   org.slf4j

·         Create a class named “NetworkConfigExample” in the package com.eurotech.example.network.

·         Create an OSGI-INF folder in the package com.eurotech.example.network.  Add a Component Class with parent folder com.eurotech.example.network/OSGI-INF, Component Name com.eurotech.example.network, and Class com.eurotech.example.network.NetworkConfigExample.

·         In the component.xml file, select the Services tab.  Under Referenced Services, add com.eurotech.framework.net.NetworkAdminService.  Edit the properties of this service, and configure the Bind property to setNetworkAdminService and Unbind to unsetNetworkAdminService as shown in the following screen capture.  These are required because of the dependency on NetworkAdminService.

 

networkAdminService.png

 

Now you need to write the source code.  Below are the three files that need to be implemented:

 

·         META-INF/MANIFEST.MF - OSGI manifest that describes the bundle and it’s dependencies

·         OSGI-INF/component.xml - declarative services definition describing what services are exposed by and consumed by this bundle

·         com.eurotech.example.network.NetworkConfigExample.java - main implementation class

 

The META-INF/MANIFEST.MF file should look as follows when complete (with the possible exception that your RequiredExecutionEnvironment should match the Java version running on the target, such as “JavaSE-1.7”).  Also note whitespace is significant in this file.  Make sure yours matches this file exactly.

 

 

Manifest-Version: 1.0

Bundle-ManifestVersion: 2

Bundle-Name: Network

Bundle-SymbolicName: com.eurotech.example.network

Bundle-Version: 1.0.0.qualifier

Bundle-Vendor: EUROTECH

Bundle-RequiredExecutionEnvironment: JavaSE-1.7

Import-Package: com.eurotech.framework,

 com.eurotech.framework.net,

 com.eurotech.framework.net.dhcp,

 com.eurotech.framework.net.firewall,

 com.eurotech.framework.net.wifi,

 org.osgi.service.component;version="1.2.0",

 org.slf4j;version="1.6.4"

Service-Component: OSGI-INF/component.xml

 

 

 

The OSGI-INF/component.xml Source tab should already match the following content.

 

 

<?xml version="1.0" encoding="UTF-8"?>

<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="activate" deactivate="deactivate" name="com.eurotech.example.network">

   <implementation class="com.eurotech.example.network.NetworkConfigExample"/>

   <reference bind="setNetworkAdminService" cardinality="1..1" interface="com.eurotech.framework.net.NetworkAdminService" name="NetworkAdminService" policy="static" unbind="unsetNetworkAdminService"/>

</scr:component>

 

 

 

Copy the following source code and paste into the com.eurotech.example.network.NetworkConfigExample.java file.  By default, this example code will connect to the access point (the createWirelessAccessPoint() statement in the activate() method is commented out).

 

 

package com.eurotech.example.network;

 

import java.util.ArrayList;

import java.util.List;

 

import org.osgi.service.component.ComponentContext;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

 

import com.eurotech.framework.EsfException;

import com.eurotech.framework.net.IP4Address;

import com.eurotech.framework.net.IPAddress;

import com.eurotech.framework.net.NetConfig;

import com.eurotech.framework.net.NetConfigIP4;

import com.eurotech.framework.net.NetInterfaceStatus;

import com.eurotech.framework.net.NetworkAdminService;

import com.eurotech.framework.net.dhcp.DhcpServerConfigIP4;

import com.eurotech.framework.net.firewall.FirewallNatConfig;

import com.eurotech.framework.net.wifi.WifiCiphers;

import com.eurotech.framework.net.wifi.WifiConfig;

import com.eurotech.framework.net.wifi.WifiMode;

import com.eurotech.framework.net.wifi.WifiRadioMode;

import com.eurotech.framework.net.wifi.WifiSecurity;

 

public class NetworkConfigExample {

 

     private static final Logger s_logger = LoggerFactory.getLogger(NetworkConfigExample.class);

 

     private NetworkAdminService m_netAdminService;

 

     // ----------------------------------------------------------------

     //

     //   Dependencies

     //

     // ----------------------------------------------------------------

 

     public void setNetworkAdminService(NetworkAdminService netAdminService) {

           this.m_netAdminService = netAdminService;

     }

 

     public void unsetNetworkAdminService(NetworkAdminService netAdminService) {

           this.m_netAdminService = null;

     }

    

    

     // ----------------------------------------------------------------

     //

     //   Activation APIs

     //

     // ----------------------------------------------------------------

 

     protected void activate(ComponentContext componentContext) {

           s_logger.info("Activating NetworkConfigExample...");

          

           connectToWirelessAccessPoint();

//         createWirelessAccessPoint();

          

           s_logger.info("Activating NetworkConfigExample... Done.");

     }

 

     protected void deactivate(ComponentContext componentContext) {

           s_logger.info("Deactivating NetworkConfigExample...");

 

           s_logger.info("Deactivating NetworkConfigExample... Done.");

     }

    

    

     // ----------------------------------------------------------------

     //

     //   Private Methods

     //

     // ----------------------------------------------------------------

 

     /**

      * Connect to a wireless access point using the hard-coded parameters below

      */

     private void connectToWirelessAccessPoint() {

           String interfaceName = "wlan0";

          

           // Create a NetConfigIP4 - configure as a WAN (gateway) interface, and a DHCP client

           NetInterfaceStatus netInterfaceStatus = NetInterfaceStatus.netIPv4StatusEnabledWAN;

           boolean dhcpClient = true;

           boolean autoConnect = true;

           NetConfigIP4 netConfigIP4 = new NetConfigIP4(netInterfaceStatus, autoConnect, dhcpClient);

 

           // Create a WifiConfig managed mode client

           String driver = "nl80211";

           String ssid = "access_point_ssid";

           String password = "password";

           WifiSecurity security = WifiSecurity.SECURITY_WPA2;

           WifiCiphers ciphers = WifiCiphers.CCMP_TKIP;

           int[] channels = {1,2,3,4,5,6,7,8,9,10,11};

 

           WifiConfig wifiConfig = new WifiConfig();

           wifiConfig.setMode(WifiMode.INFRA);

           wifiConfig.setDriver(driver);

           wifiConfig.setSSID(ssid);

           wifiConfig.setPasskey(password);

           wifiConfig.setSecurity(security);

           wifiConfig.setChannels(channels);

           wifiConfig.setGroupCiphers(ciphers);

           wifiConfig.setPairwiseCiphers(ciphers);

 

           // Create a NetConfig List

           List<NetConfig> netConfigs = new ArrayList<NetConfig>();

           netConfigs.add(netConfigIP4);

           netConfigs.add(wifiConfig);         

          

           // Configure the interface

           try{

                s_logger.info("Reconfiguring " + interfaceName + " to connect to " + ssid);

                m_netAdminService.disableInterface(interfaceName);

                m_netAdminService.updateWifiInterfaceConfig(interfaceName, autoConnect, null, netConfigs);

               

                s_logger.info("Enable " + interfaceName);

                m_netAdminService.enableInterface(interfaceName, dhcpClient);

           } catch(EsfException e) {

                s_logger.error("Error connecting to wireless access point", e);

           }

     }   

    

     /**

      * Create a wireless access point

      */

     private void createWirelessAccessPoint() {

           try{

                String interfaceName = "wlan0";

    

                // Create a NetConfigIP4 - configure as a LAN interface with a manual IP address

                NetInterfaceStatus netInterfaceStatus = NetInterfaceStatus.netIPv4StatusEnabledLAN;

                boolean dhcpClient = false;

                boolean autoConnect = true;

                IP4Address ipAddress = (IP4Address) IPAddress.parseHostAddress("172.16.10.1");

                IP4Address subnetMask = (IP4Address) IPAddress.parseHostAddress("255.255.255.0");

               

                NetConfigIP4 netConfigIP4 = new NetConfigIP4(netInterfaceStatus, autoConnect);

                netConfigIP4.setAddress(ipAddress);

                netConfigIP4.setSubnetMask(subnetMask);

               

                // Create a WifiConfig access point

                String driver = "nl80211";

                String ssid = "NetworkConfigExample";

                String password = "password";

                WifiSecurity security = WifiSecurity.SECURITY_WPA2;

                WifiCiphers ciphers = WifiCiphers.CCMP_TKIP;

                int[] channels = {1};

                WifiRadioMode radioMode = WifiRadioMode.RADIO_MODE_80211g;

                String hwMode = "g";

               

                WifiConfig wifiConfig = new WifiConfig();

                wifiConfig.setMode(WifiMode.MASTER);

                wifiConfig.setDriver(driver);

                wifiConfig.setSSID(ssid);

                wifiConfig.setPasskey(password);

                wifiConfig.setSecurity(security);

                wifiConfig.setChannels(channels);

                wifiConfig.setGroupCiphers(ciphers);

                wifiConfig.setPairwiseCiphers(ciphers);

                wifiConfig.setRadioMode(radioMode);

                wifiConfig.setHardwareMode(hwMode);

 

               

                // Create a DhcpServerConfig to enable DHCP server functionality

                int defaultLeaseTime = 7200;

                int maximumLeaseTime = 7200;

                IP4Address routerAddress = ipAddress;

                IP4Address rangeStart = (IP4Address) IPAddress.parseHostAddress("172.16.10.100");

                IP4Address rangeEnd = (IP4Address) IPAddress.parseHostAddress("172.16.10.200");

                IP4Address dhcpSubnetMask = (IP4Address) IPAddress.parseHostAddress("255.255.255.0");

                IP4Address subnet = (IP4Address) IPAddress.parseHostAddress("172.16.10.0");          

                short prefix = 24;

                boolean passDns = true;

 

                List<IP4Address> dnsServers = new ArrayList<IP4Address>();

                dnsServers.add(ipAddress);                      // Use our IP as the DNS server

               

                DhcpServerConfigIP4 dhcpServerConfigIP4 = new DhcpServerConfigIP4(

                           interfaceName, true, subnet, routerAddress, dhcpSubnetMask, defaultLeaseTime,

                           maximumLeaseTime, prefix, rangeStart, rangeEnd, passDns, dnsServers);

 

                // Create a FirewallNatConfig to enable NAT (network address translation)

                // note that the destination interface is determined dynamically

                FirewallNatConfig natConfig = new FirewallNatConfig(interfaceName, "tbd", true); 

 

    

                // Create a NetConfig List

                List<NetConfig> netConfigs = new ArrayList<NetConfig>();

                netConfigs.add(netConfigIP4);

                netConfigs.add(wifiConfig);

                netConfigs.add(dhcpServerConfigIP4);

                netConfigs.add(natConfig);

               

                // Configure the interface

                s_logger.info("Reconfiguring " + interfaceName + " as an access point with SSID: " + ssid);

                m_netAdminService.disableInterface(interfaceName);

                m_netAdminService.updateWifiInterfaceConfig(interfaceName, autoConnect, null, netConfigs);

               

                s_logger.info("Enable " + interfaceName);

                m_netAdminService.enableInterface(interfaceName, dhcpClient);

           } catch(Exception e) {

                s_logger.error("Error configuring as an access point", e);

           }

     }

}

 

 

 

Modify the parameters in the connectToWirelessAccessPoint() method with the specific values for the access point you want to connect to, including the variables for SSID, password, and security settings:

 

 

           String ssid = "access_point_ssid";

           String password = "password";

           WifiSecurity security = WifiSecurity.SECURITY_WPA2;

 

 

At this point, the bundle implementation is complete.  Make sure to save all files before proceeding.

 

Export the OSGI bundle as a stand-alone plug-in, following the instructions in Hello World Using the ESF Logger.

 

Deploying the Bundle

In order to proceed, you need to know the IP address of your embedded gateway that is running ESF.  Follow the mToolkit instructions for installing a single bundle to the remote target device.  Once the bundle has finished deploying, it will set the device’s network configuration and attempt to connect to a Wi-Fi access point using the configured parameters in the connectToWirelessAccessPoint() method.

 

Testing Connection to Access Point

You can run the ‘ifconfig’ command at a terminal on the embedded gateway to verify that the interface (wlan0) has acquired an IP address.

 

To show the current connection status to the access point, run the following commands:

 

wpa_cli -i wlan0 status

iw dev wlan0 link

iw dev wlan0 station dump

 


Creating an Access Point

This example code can be modified slightly to make the gateway function as an access point instead of connecting to an access point.

 

To do this, modify the activate() method in the NetworkConfigExample.java file to comment out “connectToWirelessAccessPoint()” and uncomment “createWirelessAccessPoint()”.

 

 

protected void activate(ComponentContext componentContext) {

     s_logger.info("Activating NetworkConfigExample...");

          

//   connectToWirelessAccessPoint();

     createWirelessAccessPoint();

          

     s_logger.info("Activating NetworkConfigExample... Done.");

}

 

Modify the access point configuration variables under createWirelessAccessPoint() for your needs, if necessary, such as the variables:

 

 

                IP4Address ipAddress = (IP4Address) IPAddress.parseHostAddress("172.16.10.1");

                IP4Address subnetMask = (IP4Address) IPAddress.parseHostAddress("255.255.255.0");

               

                // Create a WifiConfig access point

                String driver = "nl80211";

                String ssid = "NetworkConfigExample";

                String password = "password";

 

 

Export the bundle again as a stand-alone OSGi plug-in and redeploy it to the target device.  Now it should reconfigure itself to create an access point with an active DHCP server, DNS proxy forwarding, and NAT enabled.

 

Testing Your Access Point

You can run the ‘ifconfig’ command at a terminal on the embedded gateway to verify that the interface (wlan0) has a fixed IP address.

 

To view information on the Wi-Fi access point, including interface name, wireless channel, and MAC address, type:

 

iw dev wlan0 info

 

To monitor connect and disconnect events from the access point, type:

 

iw event –f

 

Use another wireless client, such as a laptop, to verify that you can connect to the access point, that it receives an IP address, and that it can ping the network.  When the client connects to the access point, the console should show a “new station” connection event.

 

To view information on the currently connect clients, including signal strength and bitrate, type:

 

iw dev wlan0 station dump

 

 

Optionally, if the gateway has another interface configured for WAN with connection to the Internet, then the wireless client should be able to reach the Internet using this access point as its gateway.  The setup for the other interface is not covered in this example, but it would need to be configured in the device using the ESF Gateway Administration configuration Web page.