node package manager
Loosely couple your services. Use Orgs to version and reuse your code. Create a free org »

cordova-plugin-nabto

Cordova Plugin Nabto - 2.4

Nabto ApS client plugin for Cordova.

Nabto provides a full communication infrastructure to allow direct, encrypted communication between clients and IoT devices - the Nabto communication platform. The platform supports direct peer-to-peer connectivity through NAT traversal with fallback through central relay.

The Cordova plugin allows hybrid client apps to use Nabto RPC to invoke uNabto devices, i.e. to retrieve data or control the device.

For an example of such a hybrid app, see Ionic Starter for Nabto / AppMyProduct.

Installation

  1. Download Nabto libraries and assets to cordova-plugin-nabto/src/nabto/ (See "Source File Structure" section). This step can be skipped if installing directly from npm.
  2. Install cordova plugin: cordova plugin add cordova-plugin-nabto.
  3. For iOS projects replace linker flag -ObjC with -force_load $(BUILT_PRODUCTS_DIR)/libCordova.a -lstdc++ (in platforms/ios/cordova/build.xcconfig)
  4. Start using as described in the Example and API section.

Example

A simple example using the Cordova Nabto plugin:

// Wait for cordova to fully load
document.addEventListener('deviceready', function() {
  
  // Start Nabto and login as guest
  nabto.startupAndOpenProfile(function() {
 
    // set the device interface definition to use
    nabto.rpcSetDefaultInterface("<unabto_queries><query name='my_wind_speed.json' id='2'><request></request><response format='json'><parameter name='speed' type='uint32'/></response></query></unabto_queries>", function() {
 
      // prepare invocation - note: may show a full screen ad if device is associated a free tier AMP product
      nabto.prepareInvoke(['demo.nabto.net'], function() {
 
        // invoke a function on the device
        nabto.rpcInvoke('nabto://demo.nabto.net/my_wind_speed.json?', function(error, result) {
          if (error) {
            console.log(error.message);
          } else {
            if (result.response) {
              console.log(result.response);
            }
          }
        });
      });
    });
  });
 
}, false);

Note about version identifiers

The version information returned by nabto.versionString is the core Nabto Client SDK version - not the version of the Cordova wrapper (the component described in this document). See the release notes for the individual Cordova wrapper version to see the Nabto Client SDK core version wrapped.

Note about older Android devices

On Android 4.4 and older, please pass the --browserify option to the cordova CLI (not necessary to worry about if invoking through Ionic), e.g. cordova build android --browserify, this fixes a problem with require not being available.

Nabto API

See www/nabto.js for API implementation details.

All callbacks are invoked with an error object as the first argument if something went wrong, otherwise the first argument is set to undefined.

nabto.startupAndOpenProfile

Starts Nabto and establish a client session using specified username and password (locates an installed keypair associated with username and decrypts the private key with password).

nabto.startupAndOpenProfile(username, password, callback)

nabto.startup

Starts Nabto without an associated client session (so cannot invoke remote devices).

nabto.startup(callback)

nabto.shutdown

Shuts down Nabto.

nabto.shutdown(callback)

nabto.rpcInvoke

Makes a Nabto RPC request to a uNabto device:

nabto.invokeRpc(url, callback)

For example:

nabto.invokeRpc('nabto://demo.nabto.net/wind_speed.json?', function(err, res) {
  console.log(res);
})`

Prior to invoking, the following must have been done (after startup):

  • RPC interface must have been set with nabto.rpcSetInterface(host, unabto_queries_xml) or nabto.rpcSetDefaultInterface(unabto_queries_xml). The interface file is the file formerly distributed centrally through HTML DD bundles in the nabto subdir.
  • The function nabto.prepareInvoke(hosts) where hosts is an array of hostnames.

nabto.invokeRpc() is equivalent to nabto.fetchUrl() on JSON URLs in earlier versions of the SDK; devices invoked earlier with nabto.fetchUrl() can be invoked in exactly the same way and the resulting response objects are identical. It is only a matter of simpler management, cf. the description above.

nabto.rpcSetDefaultInterface

Set Nabto RPC interface for specific host. See section 6.2 in TEN024 for format (note that the key HTML DD concept in that document is deprecated, the mentioned section will soon be available in a new location).

nabto.rpcSetInterface(host, unabto_queries_xml, callback)

nabto.rpcSetDefaultInterface

Set default Nabto RPC interface to use if not overriden with host specific version (rpcSetInterface). See section 6.2 in TEN024 for format (note that the key HTML DD concept in that document is deprecated, the mentioned section will soon be available in a new location).

nabto.rpcSetDefaultInterface(host, unabto_queries_xml, callback)

nabto.prepareInvoke

Mandatory to invoke prior to nabto.invokeRpc after each nabto.startup invocation. This function may show a fullscreen ad if hosts contains a device associated with an AMP free tier product. An ad may also be shown if a previous invocation since last nabto.startup contained such free tier device.

nabto.prepareInvoke(hosts, callback)

nabto.getLocalDevices

Get local Nabto devices. Callback is invoked with an array of device strings.

nabto.getLocalDevices(callback)

nabto.versionString

Get Nabto client version. Callback is invoked with a string.

nabto.versionString(callback)

nabto.createKeyPair

Create selfsigned keypair to be used for RSA fingerprint based authentication in uNabto devices.

nabto.createKeyPair(name, private_key_encryption_password, callback)

nabto.getFingerprint

Get RSA fingerprint for public key in specified keypair.

nabto.getFingerprint(name, callback)

nabto.removeKeyPair

Remove keypair from local store.

nabto.removeKeyPair(id, callback)

nabto.createSignedKeyPair (deprecated)

Create CA signed keypair to be used for uNabto device and basestation based authentication. Specified email address and password are used for authenticating towards the central user management services used by the CA to verify the user's identity. The password is also used for encrypting the local private key.

nabto.createSignedKeyPair(email, password, callback)

Note: In the current (deprecated) implementation the encryption of the local key using the same password as for the CA services causes a poor user experience if user has a profile on multiple devices and resets password on a single device: When the user starts the app and enters a password, the private key is decrypted meaning that in all other app instances than the one through which the password was reset, the old password must be used.

The app developer must implement a mechanism to detect such reset and re-create keypairs on all devices to set the same password for all key pairs. If this feature was not deprecated in the first place (see below), a new behavior would indeed have been considered (e.g., when possible, skip private key encryption and use platform specific certificate store).

Deprecation notice: The Nabto CA services are no longer part of the standard platform and requires a customer specific setup. New solutions must base their security design on PPKA approach (see section 8.2 in TEN036 Security in Nabto Solutions) or the authentication token approach using setBaseStationAuthJson.

nabto.signup (deprecated)

Signup for a user profile through the central user management services.

nabto.signup(email, password, callback)

Deprecation notice: The Nabto CA services are no longer part of the standard platform and requires a customer specific setup. New solutions must base their security design on PPKA approach (see section 8.2 in TEN036 Security in Nabto Solutions) or the authentication token approach using setBaseStationAuthJson.

nabto.resetAccountPassword (deprecated)

Reset user's account password in the central user management services. See note on createSignedKeyPair preventing a poor user experience.

nabto.resetAccountPassword(email, callback)

Deprecation notice: The Nabto CA services are no longer part of the standard platform and requires a customer specific setup. New solutions must base their security design on PPKA approach (see section 8.2 in TEN036 Security in Nabto Solutions) or the authentication token approach using setBaseStationAuthJson.

nabto.tunnelOpenTcp

Open a tunnel to specified nabto host, connecting to specified TCP port on the remote host. When a connection is established, a callback is invoked with a tunnel handle used for later operations. If success, TCP clients can now connect to the local port that can be queried with tunnelPort.

nabto.tunnelOpenTcp("streamdemo.nabto.net", 80, callback)

nabto.tunnelPort

Retrieve the local TCP port number of the specified tunnel handle (tunnel opened with tunnelOpenTcp).

nabto.tunnelClose

Close tunnel associated with the specified tunnel handle to free up resources on the target device.

nabto.tunnelState

Get the tunnel state, an integer from the following enum - see nabto_client_api.h for details:

enum nabto_tunnel_state {
    NTCS_CLOSED = -1,
    NTCS_CONNECTING = 0,
    NTCS_READY_FOR_RECONNECT = 1,
    NTCS_UNKNOWN = 2,
    NTCS_LOCAL = 3,
    NTCS_REMOTE_P2P = 4,
    NTCS_REMOTE_RELAY = 5,
    NTCS_REMOTE_RELAY_MICRO = 6
};

nabto.setOption

Set a configuration option supported by nabtoSetOption in the native SDK.

nabto.setOption("urlPortalHostName", "webservice.nabto", callback)

nabto.setStaticResourceDir

Set the directory where static resources are read from. Use with cordova-plugin-file to get absolute path (ok to include file:// prefix).

nabto.setStaticResourceDir(cordova.file.dataDirectory, callback)

nabto.setBaseStationAuthJson

Set JSON document with basestation authentication info to use on the active session for next connect attempt. Requires configuration of authentication webhook in basestation. Use empty string to reset. See nabto_client_api.h for more details.

nabto.setBaseStationAuthJson(jsonString, callback)

Source File Structure

Install from npm to get all necessary libraries and resources installed in the right location.

For development of the plugin itself, install with a reference to this git repo. The Nabto Android wrapper and dependencies is installed automatically from bintray. For iOS, Cordova does not support dynamic frameworks in Cocoapods.

So for iOS, do the following:

  1. Download the iOS wrapper source (Libraries > Source > [iOS link in table]) - unpack and put the source files in ./src/ios.
  2. Download the static Nabto Client SDK core libraries - unpack and put .a files in ./src/nabto/ios/lib and header files in ./src/nabto/ios/include.

That is, make sure you have the following directory structure:

src
├── ios
│   ├── CDVNabto.m
│   ├── ...
│   ├── NabtoClient.mm
│   ├── NabtoClient.h
└── nabto
    └── ios
        ├── include
        │   └── nabto_client_api.h
        ├── lib
        │   ├── libnabto_client_api_static.a
        │   └── libnabto_static_external.a

Run Tests

The development lifecycle for Cordova plugins is not very smooth; in our experience it is simplest to completely remove all traces of the plugin and install again for every change/test cycle. As the Nabto libs are quite big, a lot of time goes copying these files around, you might optimize the cycle this by just using libraries for the exact platform you are working on.

  1. Create a new Cordova project
  2. Add <content src="cdvtests/index.html" /> to the project's config.xml
  3. Install the Cordova test framework plugin: cordova plugin add https://github.com/maverickmishra/cordova-plugin-test-framework.git
  4. Install cordova-plugin-nabto: cordova plugin add ~/git/cordova-plugin-nabto (see note about optimization)
  5. Install cordova-plugin-nabto-test: cordova plugin add ~/git/cordova-plugin-nabto-tests
  6. Patch build.xcconfig as outlined above if using iOS
  7. Build and run on the intended platform

For every change, clean up and run from step 4 - e.g. put the following in a script:

rm -rf  ~/.npm/cordova-plugin-nabto*
npm uninstall cordova-plugin-nabto
cordova plugin rm cordova-plugin-nabto-tests
cordova plugin rm cordova-plugin-nabto

cordova plugin add ~/git/cordova-plugin-nabto
cordova plugin add ~/git/cordova-plugin-nabto-tests

echo 'OTHER_LDFLAGS = -force_load $(BUILT_PRODUCTS_DIR)/libCordova.a -lstdc++' >> platforms/ios/cordova/build.xcconfig

cordova build ios
cordova emulate ios