# Overview   This repository contains a usage example of MICROEJ AWS IoT SDK. It shows the following features: - AWS Just In Time Provisioning of an IoT device - AWS MQTT TLS Connection Configuration - AWS MQTT Publish/Subscribe to a topic - AWS Device Shadow management (CRUD) MICROEJ AWS IoT SDK documentation can be found [here](https://repository.microej.com/modules/ej/library/iot/aws-iot/2.0.0/README-2.0.0.md) # Requirements This example requires the following: * An AWS account. It can be created from [AWS console](https://aws.amazon.com/console/) * MICROEJ SDK Dist `20.12` or higher. It can be downloaded from [MicroEJ Developer Portal](http://developer.microej.com/getting-started-sdk.html) * A Platform providing the following Foundation Libraries: * EDC-1.2 * BON-1.3 * NET-1.1 * SSL-2.1 * ECOM-WIFI-2.1 * ECOM-NETWORK-2.0 This example has been tested on the [Platform for Espressif ESP-WROVER-KIT V4.1 v2.0.0](https://github.com/MicroEJ/Platform-Espressif-ESP-WROVER-KIT-V4.1/tree/2.0.0). # Usage ## Import project & Platform to SDK * Clone this repository * Start the SDK and import the Git repository into it: * From top menu, Go to `File` > `Import...` * Then `General` > `Existing Project into Workspace` * Select root directory where the project was cloned * Click `Finish` button * Import the Platform into the SDK. See Requirements Section. * Clone the Platform Git project * From top menu, Go to `File` > `Import...` * `General` > `Existing Project into Workspace` * Select root directory where the project was cloned * Click `Finish` button * Build the Platform * Right Click on the `ESP32-WROVER-Xtensa-FreeRTOS-configuration` * Select `Build Module` * Wait for the build to finish and import the result to the workspace. Note that the project may be already imported. If it's the case just refresh it. ## Launching the AWS IoT Demo ### Getting ready with AWS IoT * Set up your AWS account by following [this AWS guide](https://docs.aws.amazon.com/iot/latest/developerguide/setting-up.html) * Generate the authority and device certificates, and the provisioning template. Then, register the authority certificate in AWS IoT Core Service by following [this AWS guide](https://aws.amazon.com/blogs/iot/setting-up-just-in-time-provisioning-with-aws-iot-core/). * **Important notes** * In the section `Create a provisioning template`, allow the necessary actions for this example to work. You can put `[iot:*]` in the `Action:` field of the template instead of `[iot:Connect,iot:Publish]` (escape characters omitted) to allow all the actions. The full list of AWS IoT policy actions can be found [here](https://docs.aws.amazon.com/iot/latest/developerguide/iot-policy-actions.html) * The last part using `mosquitto_pub` to test the connection and the JIT provisioning at the first connection can be skipped as it will be covered by this example. ### Getting ready with the certificates At this step you should have the following files: * `rootCA.pem`: Root CA certificate in PEM format * `deviceCert.crt`: Device X509 certificate in PEM format * `deviceCert.key`: Device private key in PEM format. `deviceCert.key` needs to be converted to DER format, as this is the format supported by the Platform today. * Convert `deviceCert.key` to DER format using [OpenSSL](https://www.openssl.org/source/) by running the following command: ```powershell openssl.exe pkcs8 -inform PEM -in deviceCert.key -topk8 -outform DER -out deviceCert.der -v1 PBE-SHA1-3DES -passout pass:awsdemo ``` * Place the 3 files into `src\main\resources\certificates\device` folder. #### Note If the files naming doesn't match this documentation, it can be adapted by changing `com.microej.demo.aws.iot.constants.list` and `com.microej.demo.aws.iot.resources.list` files ### Getting ready with the application configuration * Get the AWS IoT server `hostname` (endpoint), For that go to: * Connect to `AWS Console` * Go to `Iot Core` Service * From the left menu, go to `Settings` * Copy the endpoint from the setting page. It looks something like `*.iot.eu-west-3.amazonaws.com` * Configure the application by changing the following values in `src\main\resources\com.microej.demo.aws.iot.constants.list` ```properties ################################################### # AWS IoT Broker Configuration ################################################### aws.url=<AWS IoT Server Host Name> ``` ### Launching the demo on Simulator * Right click on the project and select `Run As` > `MicroEJ Application` * Select `com.microej.demo.aws.iot.Main` class in the `Select Java Application` wizard * Select a compatible Platform from the `Select a Platform` wizard * Follow the instructions from the application logs to configure the WIFI network The traces should look like this : ```java =============== [ Initialization Stage ] =============== Using default Platform kernel.kf =============== [ Launching on Simulator ] =============== com.microej.demo.aws.iot.main INFO: Starting WIFI Setup com.microej.demo.aws.iot.main INFO: Please connect to the board SOFT Access Point WIFI network com.microej.demo.aws.iot.wifi INFO: Scan: com.microej.demo.aws.iot.wifi INFO: -myFirstSSid com.microej.demo.aws.iot.wifi INFO: -mySecondSSid com.microej.demo.aws.iot.main INFO: Loading Stored AP config com.microej.demo.aws.iot.wifi INFO: ############ WIFI CONFIG INSTRUCTIONS ################### Please connect to the WIFI network with SSID=AWS_IOT_SAMPLE, password=qwertyuiop, and security=WPA2 from a mobile phone or a computer. Then, open http://192.168.56.1:80 in a browser to configure a WIFI network with internet access. The demo will start automatically when a WIFI network is configured successfully. ############################################################# ``` * Connect to the IP address showed in the log. Note that the IP address will be different on your machine * Select and connect to a WIFI network with internet access   * When the WIFI network is connected the demo will start as the following. ```json com.microej.demo.aws.iot.wifi INFO: Trying Join:myFirstSSid com.microej.demo.aws.iot.wifi INFO: successfully joined WIFI: myFirstSSid com.microej.demo.aws.iot.wifi INFO: Updating local time from NTP server pool.ntp.org:123 com.microej.demo.aws.iot.aws INFO: Connecting to AWS IoT Core Server. JIT provisioning will be done if necessary. com.microej.demo.aws.iot.aws INFO: Device connected to the broker. com.microej.demo.aws.iot.aws INFO: Update listener added, we're now subscribed to the topic awsiot/demo/sample com.microej.demo.aws.iot.aws INFO: Sample data publishing timer task initialized. com.microej.demo.aws.iot.aws INFO: Create or Update Device Shadow by reporting the device state com.microej.demo.aws.iot.main INFO: Storing AP config for reuse com.microej.demo.aws.iot.wifi INFO: Soft AP Unmount com.microej.demo.aws.iot.shadow.updatedelta INFO: Message received on topic='$aws/things/Thermostat-1/shadow/update/documents, payload='{"previous":{"state":{"reported":{"unit":"°C","temperature":16,"target-time":"2022-04-14 08:33","target":16,"state":"ready","location":{"country":"FR","city":"Nantes"},"timestamp":1654603200094,"firmware-version":"1.8.3","capabilities":{"ble":true,"ota":true,"network":"WIFI"}}},"metadata":{"reported":{"unit":{"timestamp":1649925184},"temperature":{"timestamp":1649925184},"target-time":{"timestamp":1649925184},"target":{"timestamp":1649925184},"state":{"timestamp":1654603200},"location":{"country":{"timestamp":1654603200},"city":{"timestamp":1654603200}},"timestamp":{"timestamp":1654603200},"firmware-version":{"timestamp":1654603200},"capabilities":{"ble":{"timestamp":1654603200},"ota":{"timestamp":1654603200},"network":{"timestamp":1654603200}}}},"version":20},"current":{"state":{"reported":{"unit":"°C","temperature":16,"target-time":"2022-04-14 08:33","target":16,"state":"ready","location":{"country":"FR","city":"Nantes"},"timestamp":1654604502398,"firmware-version":"1.8.3","capabilities":{"ble":true,"ota":true,"network":"WIFI"}}},"metadata":{"reported":{"unit":{"timestamp":1649925184},"temperature":{"timestamp":1649925184},"target-time":{"timestamp":1649925184},"target":{"timestamp":1649925184},"state":{"timestamp":1654604502},"location":{"country":{"timestamp":1654604502},"city":{"timestamp":1654604502}},"timestamp":{"timestamp":1654604502},"firmware-version":{"timestamp":1654604502},"capabilities":{"ble":{"timestamp":1654604502},"ota":{"timestamp":1654604502},"network":{"timestamp":1654604502}}}},"version":21},"timestamp":1654604502}' com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"MicroEJ"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"is"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"a"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"unique"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"solution"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"for"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"building"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"Internet"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"of"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"Things"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"and"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"embedded"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"software"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"and"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"can"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"now"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"communicate"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"with"} com.microej.demo.aws.iot.topicsubscriber INFO: Message received on topic awsiot/demo/sample => {"message":"AWS IoT"} ``` ### Launching the demo on a Wi-Fi board (ESP32 WROVER KIT 4.1) * Compile & Link the application with the BSP * From the SDK top menu, go to `Run` > `Run Configurations...` * From the left menu, Right click on `MicroEJ Application` and select `New Configuration` * Enter a Configuration Name. for example `AWS Demo Build` * From the `Main` tab * Select the demo project `aws-iot-sample` * Enter the main class `com.microej.demo.aws.iot.Main` in the Main type field * From the `Execution` tab * Select a compatible MICROEJ Platform * Select `Execute On Device` and keep the default options (Core Engine Mode: Default, Settings: Build & Deploy) * From the `Configuration` tab * Go to `Device` > `Deploy` and check the option `Execute the MicroEJ build script (build.bat)` * Click `Run` button * **Note:** that the first compilation may take some time as It will compile the ESP-IDF BSP * Flash the demo to your ESP32 WROVER KIT 4.1 evaluation Board by * Ensure the ESP32 Board is plugged in to your computer over USB and the COM port is mounted * Set the COM port of the ESP32 by setting the property `ESPPORT` in the file located in the Platform project `ESP32-WROVER-Xtensa-FreeRTOS-bsp/Projects/microej/scripts/set_project_env.(bat|sh)`. You can check the template file `ESP32-WROVER-Xtensa-FreeRTOS-bsp/Projects/microej/scripts/set_local_env.(bat|sh).tpl` for an example on how to set this property. * From the SDK top menu, go to `Run` > `Run Configurations...` * From the left menu, Right click on `MicroEJ Tool` and select `New Configuration` * Enter a Configuration Name. for example `AWS Demo Flash ESP32` * From the `Execution` tab * Select a compatible MICROEJ Platform * Select `Deploy with the BSP run script` for the `Execution` > `Settings` field * From the `Configuration` tab * Select the binary file to flash. The `application.out` file was generated during the Compile & Link step into `com.microej.demo.aws.iot.Main` folder in the demo project `aws-iot-sample` * Click `Run Button` * Follow the instructions from the application logs to configure the WIFI network (same as for the Simulator) # AWS IoT dashboard The AWS IoT console provides some tools to monitor the activity on the broker. * Go to `Monitor` section of the console to see graphs of successful connections to the broker and statistics on the messaging. * You can also subscribe on a topic through the console in order to see arriving messages from your device: * go to `Test` * in the `Subscription topic` section, indicate the topic to subscribe to, here `awsiot/demo/sample` * Click on `Subscribe to topic` * When the application is running, you should see messages displayed in the AWS IoT console # Troubleshooting ### ERROR javax.net.ssl.SSLHandshakeException: SSL-2.1:E=-129 **-129**: Verify problem on certificate and check date/time on your device. This SSL ERROR means that the time is not correctly set on the device. This example automatically set the device time from an NTP server. Please ensure you're using a valid one. It can be configured in `src/main/resources/com.microej.demo.aws.iot.properties.list` file ```properties ntp.url=pool.ntp.org ntp.port=123 ntp.timeout=1000 ``` ### Error : problem while parsing Ivy module file: Cause : Can't parse module descriptor This is a known issue with SDK 5.5.0 please update your SDK to the latest version. For that, please check for updates from the SDK top menu `Help` > `Check for updates` # References * [MicroEJ Developer Portal](https://developer.microej.com) * [Apache Ivy](https://ant.apache.org/ivy/) * [AWS Console](https://aws.amazon.com/console/) * [AWS IoT Documentation](https://docs.aws.amazon.com/iot/latest/developerguide/iot-console-signin.html) * [OpenSSL](https://www.openssl.org/source/) # Dependencies _All dependencies are retrieved transitively by MicroEJ Module Manager_. # Source N/A. # Restrictions None. --- _Markdown_ _Copyright 2018-2022 MicroEJ Corp. All rights reserved._ _Use of this source code is governed by a BSD-style license that can be found with this software._
# Overview MicroEJ Java library: websocket-secure. Implementation for the client side of the WebSocket protocol as described in RFC 6455. This implementation does not support very extended Length and masked frames. Secure version of WebSocket library, see [WebSocket README](../ej.websocket/README.md) # Usage Add the following line to your `module.ivy`: <dependency org="ej.library.iot" name="websocket-secure" rev="2.0.1"/> # Requirements This library requires the following Foundation Libraries: BON-1.3, EDC-1.2, NET-1.1-API-1.1, SSL-2.0 # Dependencies _All dependencies are retrieved transitively by Ivy resolver_. # Source N/A # Restrictions None. --- _Copyright 2019-2021 MicroEJ Corp. All rights reserved._ _This library is provided in source code for use, modification and test, subject to license terms._ _Any modification of the source code will break MicroEJ Corp. warranties on the whole library._
# Overview AWS IoT Java SDK is a set of Java APIs enabling MicroEJ developers to securely access and interact with [AWS IoT platform](https://docs.aws.amazon.com/iot/latest/developerguide/what-is-aws-iot.html) from an embedded device. It can be used to create embedded applications that runs on MicroEJ VEE. It provides the following functionalities: - AWS MQTT connection over TLS - AWS MQTT Topics Pub/Sub - AWS Device Shadow management (CRUD) # Usage Add the following line to your `module.ivy`: <dependency org="ej.library.iot" name="aws-iot" rev="2.0.0"/> # Requirements This library requires the following Foundation Libraries to be provided by the MicroEJ VEE: BON-1.4, EDC-1.3, NET-1.1, SECURITY-1.3, SSL-2.2, TRACE-1.1 # Dependencies All dependencies are retrieved transitively by MicroEJ Module Manager. # Source N/A ## Code Memory Consumption AWS IoT Java SDK code memory consumption is approximately ``3.1KB`` It has been measured using the [Memory Map Analyzer](https://docs.microej.com/en/latest/ApplicationDeveloperGuide/memoryMapAnalyzer.html) on the [WROVER 4.1 Platform](https://github.com/MicroEJ/Platform-Espressif-ESP-WROVER-KIT-V4.1) based on Xtensa LX6 Architecture version ``7.16.0``. The original ``SOAR.map`` file can be found [here](./memoryrequirements/SOAR.map) and can be browsed using the Memory Map Analyzer in the MicroEJ SDK. This library relies on MicroPaho (MicroEJ lightweight MQTT client implementation). MicroPaho is about ``5.5KB``. # Documentation ## Client options & connection The MQTT connections options are provided by the class ``AwsIotClientOptions``. ```java // Build the client connection options using the AwsIotClientOptions.Builder AwsIotClientOptions options = AwsIotClientOptions.Builder .builder() .host("<AWS IoT server URL>") .port(8883)// AWS IoT server port .clientID("<MQTT client id>")// MQTT client id .thingName("<AWS IoT thing name>") .timeout(30) //Optional, client connection timeout in seconds. default is 30 .keepAlive(60) //Optional, client connection keep alive in seconds. default is 60 .secure(socketFactory)// Optional, an SSL Socket Factory for TLS connection .username("username") // Optional, User name to use in MQTT CONNECT .password("changeit") // Optional, Password to use in MQTT CONNECT .build(); // Create an instance of AwsIotClient using the connection options AwsIotClient client = new AwsIotClient(options); client.connect(); // connect ``` **Host** To get your AWS IoT ``host`` address (endpoint): - Connect to ``AWS Console`` - Go to ``Iot Core`` Service - From the left menu, go to ``Setting`` - Copy the endpoint from the setting page. It looks something like ``*.iot.eu-west-3.amazonaws.com`` **Port** The MQTT server port. default is ``8883`` for a connection over TLS. **Client ID** MQTT client id. >MQTT client IDs uniquely identify MQTT connections. If a new connection is established using a client ID that is already claimed for another connection, the AWS IoT message broker drops the old connection to allow the new connection. Client IDs must be unique within each AWS account and each AWS Region. This means that you don't need to enforce global uniqueness of client IDs outside of your AWS account or across Regions within your AWS account. >Source: [AWS IoT Security Best-Practices](https://docs.aws.amazon.com/iot/latest/developerguide/security-best-practices.html) For Test Only: ``AwsIotClientOptions#generateClientId()`` method can be used to generate a random client id. The id will have the following format ``MicroEJ<platformTimeNanos>`` where *<platformTimeNanos>* is the current platform time in nanoseconds. **Thing Name** The device thing name that was used to register or provision the device in the AWS Iot platform. **Timeout** MQTT connection timeout value. This value, measured in seconds, defines the maximum time interval the client will wait for the network connection to the MQTT server to be established. The default timeout is 30 seconds. A value of 0 disables timeout processing meaning the client will wait until the network connection is made successfully or fails. **Keep Alive** This value, measured in seconds, defines the maximum time interval between messages sent or received. It enables the client to detect if the server is no longer available, without having to wait for the TCP/IP timeout. The client will ensure that at least one message travels across the network within each keep alive period. In the absence of a data-related message during the time period, the client sends a very small "ping" message, which the server will acknowledge. A value of 0 disables keep alive processing in the client. The default value is 60 seconds **Secure (Socket Factory)** This options let you configure the underlying socket factory to setup a TLS connection for example. **Username & Password** MQTT credentials to be used in CONNECT. ## Client Disconnect ---------- Use ``AwsIotClient#disconnect()`` method on a connected client to disconnect the client. This will close the underlying connection socket. The same client instance can be reused to connect the device again. ```java client.disconnect(); ``` ## Client Close Use ``AwsIotClient#close()`` after disconnecting the clients to clear all the registered subscribers callbacks and stop the executor service responsible of executing the callbacks when a message is received. ```java client.close(); ``` # AWS MQTT Pub/Sub ## Publish Message can be published using QOS 0 or 1 to a specific topic using the following APIs: * ``publish(AwsIotMessage message)`` * ``publish(String topic, byte[] data)`` * ``publish(String topic, byte[] data, int qos)`` * ``publish(String topic, byte[] data, int qos, boolean retained)`` ### Publish Example ```java String message = "{\"message\" : \"Hello world\"}"; client.publish("foo/bar", message.getBytes()); ``` ## Subscribe Topic subscriptions are managed using a callback mechanism. A callback can be registered on a topic and will be executed when a message is received on that specific topic. Callbacks are executed on a separated thread. ### Subscribe Example ```java AwsIotMessageCallback callback = new AwsIotMessageCallback() { @Override public void onMessageReceived(AwsIotMessage message) { // message received.. System.out.println(message.getTopic()); System.out.println(message.getQos()); System.out.println(message.isRetained()); System.out.println(new String(message.getPayload())); } }; // Subscribe to topic client.subscribe("foo/bar", callback); ``` # AWS Device Shadow The AWS IoT Device Shadow service adds shadows to AWS IoT thing objects. Shadows can make a device’s state available to apps and other services whether the device is connected to AWS IoT or not. AWS IoT thing objects can have multiple named shadows so that your IoT solution has more options for connecting your devices to other apps and services. [Read more about Device Shadow](https://docs.aws.amazon.com/iot/latest/developerguide/iot-device-shadows.html) The SDK provides the following API to manage Device Shadow. **Subscribe to shadow results before performing an action to get the result.** You can subscribe to none, one or all the possible results ACCEPTED, REJECTED, DELTA, and DOCUMENTS. ## Classic Shadow: * ``getShadow()`` * ``getShadow(int qos)`` * ``deleteShadow()`` * ``deleteShadow(int qos)`` * ``updateShadow(byte[] message)`` * ``updateShadow(byte[] message, int qos)`` * ``subscribeToShadow(ShadowAction action, ShadowResult result, AwsIotMessageCallback callback)`` * ``subscribeToShadow(ShadowAction action, ShadowResult result, AwsIotMessageCallback callback, int qos)`` * ``unsubscribeFromShadow(ShadowAction action, ShadowResult result)`` ## Named Shadow: * ``getShadow(String shadowName)`` * ``getShadow(String shadowName, int qos)`` * ``deleteShadow(String shadowName)`` * ``deleteShadow(String shadowName, int qos)`` * ``updateShadow(String shadowName, byte[] message)`` * ``updateShadow(String shadowName, byte[] message, int qos)`` * ``subscribeToShadow(String shadowName, ShadowAction action, ShadowResult result, AwsIotMessageCallback callback)`` * ``subscribeToShadow(String shadowName, ShadowAction action, ShadowResult result, AwsIotMessageCallback callback, int qos)`` * ``unsubscribeFromShadow(String shadowName, ShadowAction action, ShadowResult result)`` ## Get Shadow Example ``` java AwsIotMessageCallback onSuccess = new AwsIotMessageCallback() { @Override public void onMessageReceived(AwsIotMessage message) { System.out.println("accepted"); System.out.println(new String(message.getPayload())); } } AwsIotMessageCallback onError = new AwsIotMessageCallback() { @Override public void onMessageReceived(AwsIotMessage message) { System.out.println("rejected"); System.out.println(new String(message.getPayload())); } } // subscribe to get results client.subscribeToShadow(ShadowAction.get, ShadowResult.accepted, onSuccess); client.subscribeToShadow(ShadowAction.get, ShadowResult.rejected, onError); // Get for the shadow data client.getShadow(); ``` ## Delete Shadow Example ```java AwsIotMessageCallback onSuccess = new AwsIotMessageCallback() { @Override public void onMessageReceived(AwsIotMessage message) { System.out.println("accepted"); System.out.println(new String(message.getPayload())); } } AwsIotMessageCallback onError = new AwsIotMessageCallback() { @Override public void onMessageReceived(AwsIotMessage message) { System.out.println("rejected"); System.out.println(new String(message.getPayload())); } } //subscribe to delete shadow events client.subscribeToShadow(ShadowAction.delete, ShadowResult.accepted, onSuccess); client.subscribeToShadow(ShadowAction.delete, ShadowResult.rejected, onError); // delete shadow client.deleteShadow() ``` ## Create/Update Shadow Example ```java String AWS_SHADOW_NAME = "shadowName"; String message = "{\"state\": {\"reported\": {\"welcome\": \"AWS updated\"}}}"; AwsIotMessageCallback onSuccess = new AwsIotMessageCallback() { @Override public void onMessageReceived(AwsIotMessage message) { System.out.println("accepted"); System.out.println(new String(message.getPayload())); } } AwsIotMessageCallback onError = new AwsIotMessageCallback() { @Override public void onMessageReceived(AwsIotMessage message) { System.out.println("rejected"); System.out.println(new String(message.getPayload())); } } AwsIotMessageCallback delta = new AwsIotMessageCallback() { @Override public void onMessageReceived(AwsIotMessage message) { System.out.println("delta"); System.out.println(new String(message.getPayload())); } } AwsIotMessageCallback documents = new AwsIotMessageCallback() { @Override public void onMessageReceived(AwsIotMessage message) { System.out.println("documents"); System.out.println(new String(message.getPayload())); } } // Subscribe update shadow results client.subscribeToShadow(ShadowAction.update, ShadowResult.accepted, onSuccess); client.subscribeToShadow(ShadowAction.update, ShadowResult.rejected, onError); client.subscribeToShadow(ShadowAction.update, ShadowResult.delta, delta); client.subscribeToShadow(ShadowAction.update, ShadowResult.documents, documents); // Create or Update a shadow and client.updateShadow(message.getBytes()); ``` # Restrictions The following features specified by MQTT ``3.1.1`` are not supported by this client: * Other MQTT versions than ``3.1.1`` * Clean Session 0 * QoS 2 * Will messages * Multiple in-flight messages * When QoS is 1, the message acknowledgment is sent before the callback method is executed, thus the message is acknowledged even if an exception is thrown by the callback * Within an implementation of ``AwsIotMessageCallback`` callback, it is not possible to send a new message. Only the following methods are allowed to be called: * ``ej.aws.iot.AwsIotClient.getClientOptions()`` * ``ej.aws.iot.AwsIotClient.isConnected()`` * [AWS IoT differences from MQTT version 3.1.1 specification](https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html#mqtt-differences) * Topic filters are not supported when registering a callback during subscribe. The full topic name should be provided. [Read more about AWS Topic filters](https://docs.aws.amazon.com/iot/latest/developerguide/topics.html#topicfilters). --- _Copyright 2019-2021 MicroEJ Corp. All rights reserved._ _This library is provided in source code for use, modification and test, subject to license terms._ _Any modification of the source code will break MicroEJ Corp. warranties on the whole library._
# Overview MicroPaho - MQTT Client is MicroEJ Add-on Library for MQTT protocol communication. MicroPaho is a tiny MQTT client running on MicroEJ, inspired from Eclipse Paho Java & Embedded C implementations. This library has been designed with the following key points in mind: * Keep well known APIs defined by the Paho Java implementation. Most of the existing Java applications using Paho Java implementation can be migrated in few minutes with minor updates. * Simple, efficient and tiny code inspired by the Paho Embedded C implementation: * At least one action at a time (connect, publish, subscribe, disconnect) so that there is at most one pending acknowledgment to wait for. * Minimum dependencies to external libraries * Implements only features of the MQTT specification required to connect production grade MQTT servers. The most noticeable feature which is not supported by this library is QoS 2. # Usage Add the following line to your `module.ivy`: <dependency org="ej.library.iot" name="micropaho" rev="1.0.0"/> # Requirements This library requires the following Foundation Libraries to be provided by the MicroEJ VEE: BON-1.4, EDC-1.3, NET-1.1, TRACE-1.1 # Dependencies All dependencies are retrieved transitively by MicroEJ Module Manager. # Source This software has been derived from: - Eclipse Paho Java, commit ID ``5af7b53499e7dbe45b7227b3d41fc870089c0033`` - Eclipse Paho Embedded C, commit ID ``07bf54a3f4a93121a018edb6981facc85e566f27`` # Tests * To Run the tests, a running docker process is required on the test host. * Docker version >= ``20.10.8`` MicroPaho is tested at build time against a local ``Mosquitto`` server. The project is configured to start/stop an ``eclipse-mosquitto:1.6.15`` docker container before running/terminating the tests execution. The docker image is automatically pulled from [docker hub](https://hub.docker.com/_/eclipse-mosquitto). MicroPaho has been successfully tested to connect [AWS IoT Core server](https://aws.amazon.com/fr/iot-core/). # Memory Requirements This section provides some measurements giving a good idea of the library memory requirements. The values are given as an indication and are subject to slightly change from versions to versions. ## Code Memory Consumption MicroPaho code memory consumption is approximately ``5.5KB``. It has been measured using the [Memory Map Analyzer](https://docs.microej.com/en/latest/ApplicationDeveloperGuide/memoryMapAnalyzer.html) on the [WROVER 4.1 Platform](https://github.com/MicroEJ/Platform-Espressif-ESP-WROVER-KIT-V4.1) based on Xtensa LX6 Architecture version ``7.16.0``. The original ``SOAR.map`` file can be found [here](./memoryrequirements/SOAR.map) and can be browsed using the Memory Map Analyzer in the MicroEJ SDK. ## Heap Memory Consumption MicroPaho heap memory consumption is approximately ``2KB`` (from the ``MqttConnectOptions`` object creation to a message received in the ``MqttCallback.messageArrived`` callback). It has been measured to 1.9KB using the MicroEJ Simulator on a Platform based on CM4/GCC Architecture version ``7.11.0`` and NET Pack version ``8.1.6``. ## Thread and Stack Consumption MicroPaho requires one thread to dispatch incoming events and to regularly send the ``Keep Alive`` message when it is enabled. The thread requires less than ``1`` stack block of ``512`` bytes for its internal execution. Obviously, the thread may require more than one stack block depending on the depth of the application callback call stack. ## External Dependencies MicroPaho depends on approximately ``25`` types and ``60`` methods. At the time this file has been wrote, here is the list of the required types: ``` ej/bon/Constants ej/bon/Immutables ej/bon/Util ej/trace/Tracer java/io/EOFException java/io/InputStream java/io/OutputStream java/lang/AssertionError java/lang/AutoCloseable java/lang/Class java/lang/IllegalArgumentException java/lang/Integer java/lang/Object java/lang/Runnable java/lang/RuntimeException java/lang/String java/lang/StringBuilder java/lang/Thread java/lang/Throwable java/net/InetSocketAddress java/net/Socket javax/net/SocketFactory ``` # Restrictions The following features specified by MQTT ``3.1.1`` are not supported by this client: * Other MQTT versions than ``3.1.1`` * Clean Session 0 * QoS 2 * Will messages * Multiple in-flight messages The following features specified by the Eclipse Paho Java API are not supported by this client: * The callback method ``org.eclipse.paho.client.mqttv3.MqttCallback.messageArrive`` specification has been modified: * when QoS is 1, the message acknowledgment is sent before the callback method is executed, thus the message is acknowledged even if an exception is thrown by the callback * within an implementation of this callback, it is not possible to send a new message. Only the following methods are allowed to be called: - ``org.eclipse.paho.client.mqttv3.IMqttClient.getClientId()`` - ``org.eclipse.paho.client.mqttv3.IMqttClient.getServerURI()`` - ``org.eclipse.paho.client.mqttv3.IMqttClient.isConnected()`` * The method ``org.eclipse.paho.client.mqttv3.MqttCallback.deliveryComplete(IMqttDeliveryToken)`` has been removed. * No topic format validation in ``publish`` and ``subscribe`` methods # Constants * ``micropaho.server.check`` enable additional consistency checks on the data received from the MQTT server. default is `true` * ``micropaho.thread.priority`` allow to customize the MQTT receiver thread priority. default is ``5`` * ``micropaho.debug`` enable debug mode and activate traces. default is ``false`` [see B-ON constants documentation](https://docs.microej.com/en/latest/ApplicationDeveloperGuide/classpath.html#constants) --- _Copyright 2019-2021 MicroEJ Corp. All rights reserved._ _This library is provided in source code for use, modification and test, subject to license terms._ _Any modification of the source code will break MicroEJ Corp. warranties on the whole library._
# Overview ej.rest is a tiny RESTful services client. ## Features - GET, POST, PUT, DELETE for text, JSON, binary - Fluent-style API to follow hyperlinks easily - Complex path queries for JSON (simple tests on fields with operators >,=,< and full boolean expressions (&&,||,!)) - Full support for multipart/form-data # Usage Add the following line to your `module.ivy`: <dependency org="ej.library.iot" name="restclient" rev="1.1.0"/> # Requirements This library requires the following Foundation Libraries: BON-1.3, EDC-1.2, NET-1.0-API-1.0 # Dependencies _All dependencies are retrieved transitively by Ivy resolver_. # Source - Derived from http://beders.github.com/Resty # Restrictions None. # Embedded constraints Embedded execution environment has a limited amount of memory (RAM, Flash, etc.). Using Resty library in a such environment encourages the developer to precisely manage resources like sockets, files, etc. Since HTTP 2.0, server defines keep-alive connections for every HTTP connection. When using Resty, developer has to take care of the number of opened sockets. In fact, many sockets can be opened at the same time and stay alive for a long time (keep-alive). To prevent having too much sockets opened, developers have to close the underlying HTTP connection of each REST call. The following code snippet shows how to correctly close such connection: Resty allows to create access paths into a JSON object with a JSON query path. The parser of these expressions needs RAM buffers. Two different sizes can be configured: - The size of the buffers, through the property `ej.rest.jsonquerypath.buffersize`. - The expand size of the buffers, through the property `ej.rest.jsonquerypath.expandbuffersize`. ```java Resty rest = new Resty(); try { // Do a REST call RawResource raw = this.rest.raw("http://my.url/data"); // Close the underlying http connection raw.http().disconnect(); } catch (IOException e) { // something went horribly wrong e.printStackTrace(); } ``` --- _Copyright 2016-2019 MicroEJ Corp. All rights reserved._ _This library is provided in source code for use, modification and test, subject to license terms._ _Any modification of the source code will break MicroEJ Corp. warranties on the whole library._
# Overview This addon library provides a tiny footprint yet extensible web server. It also includes tools for REST services and for authentication. # Usage The technical documentation on the usage of the Hoka library is in the [User Manual](user-manual.rst). # Requirements This library requires the following Foundation Libraries: BON-1.4, EDC-1.3, NET-1.1 # Dependencies *All dependencies are retrieved transitively by Ivy resolver*. # Source N.A. # Restrictions None. --- _Copyright 2017-2019 MicroEJ Corp. All rights reserved._ _This library is provided in source code for use, modification and test, subject to license terms._ _Any modification of the source code will break MicroEJ Corp. warranties on the whole library._
# Overview This project contains examples using the Hoka HTTP Server : - [SimpleExample](SimpleExample/README.md) : a minimal example of the Hoka webserver. - [HttpsExample](HttpsExample/README.md) : similar to **SimpleExample** but using HTTPS. - [RestExample](RestExample/README.md) : an example with a REST service. - [AccessControlExample](AccessControlExample/README.md) : an example with REST services to setup a minimal application with authentication and authorization. - [SlowNetworkExample](SlowNetworkExample/README.md) : an example to setup a webserver optimized for slow networks using compression and caching techniques. # Usage The examples can be run either on the simulator or on the device using following procedures. ## Run on MicroEJ Simulator 1. Right Click on the project to run 2. Select **Run as -> MicroEJ Application** 3. Select your platform 4. Press **Ok** ## Run on device ### Build 1. Right Click on the example to build 2. Select **Run as -> Run Configuration** 3. Select **MicroEJ Application** configuration kind 4. Click on **New launch configuration** icon 5. In **Execution** tab 1. In **Target** frame, in **Platform** field, select a relevant platform (but not a virtual device) 2. In **Execution** frame 1. Select **Execute on Device** 2. In **Settings** field, select **Build & Deploy** 6. Press **Apply** 7. Press **Run** 8. Copy the generated ``.out`` file path ### Flash 1. Use the appropriate flashing tool. # Requirements This library requires the following Foundation Libraries: @FOUNDATION_LIBRARIES_LIST@ # Dependencies *All dependencies are retrieved transitively by Ivy resolver*. # Source N.A. # Restrictions None. --- _Copyright 2019 MicroEJ Corp. All rights reserved._ _Use of this source code is governed by a BSD-style license that can be found with this software._
# Overview Demonstration of MQTT Publish / Subscribe functionalities for AWS IoT. It contains two projects : - com.microej.demo.aws.iot : The demonstration code is located here, the entry point class is `com.microej.demo.aws.iot.Main`. It contains the launcher for the embedded mode (currently working on Wi-Fi boards). - com.microej.demo.aws.iot-sim : Mock and launcher for the demonstration to work correctly in Simulator mode. This example has been tested on Murata 1LD eval board with a MurataType1LD 1.0.0 MicroEJ platform. # Requirements - Install the MicroEJ SDK which can be found [here](http://developer.microej.com/getting-started-sdk.html) - section 1 - Add a platform with NET-1.1, SSL-2.1 and Wi-Fi support ECOM-WIFI-2.1 # Setup You should already have cloned this repository in `[git.repo.dir]`. First start the MicroEJ SDK on a new workspace `[workspace.dir]`. Importing the Git repository in a MicroEJ SDK: - once started, import the Eclipse projects: `File` > `Import` > in `Projects from Git`, type and select `Existing local repository` > `Next` > `Add` > `Browse` and select the `[git.repo.dir]`> `Finish` > select your repo `Next` > `Import existing Eclipse projects` > import all the projects. - enable the Ivy Resolving in workspace `Window` > `Preferences` > `Ivy` > `Classpath Container` > check `Resolve dependencies in workspace` - after an Ivy Resolving, may take a while, the projects should compile (no red markers on the projects) # Launching the AWS IoT Demo ## Getting ready with AWS IoT - create AWS account through [AWS console](https://aws.amazon.com/console/) - go to `IoT Core` - go to `Secure` > `Policies` - create a policy (it describes what your device will be able to do like subscribing and publishing) - name it and configure it like this (copy/paste is available by clicking on `Advanced mode` of the `Add statements` section) : ``` { "Version": "2012-10-17", "Statement": [ { "Action": [ "iot:Publish", "iot:Subscribe", "iot:Connect", "iot:Receive" ], "Effect": "Allow", "Resource": [ "*" ] } ] } ``` - click on create - go to `Manage` - click on `Create` - click on `Create a single thing` - name your thing and click on `Next` - choose the `One-click certificate creation (recommended)` option by clicking on `Create certificate` - on the `Certificate created` page, download every certificates and keys - click on the `Activate` button to enable the certificate authentication of your thing - click on `Attach a policy` - select the previously created policy If you have any trouble, the AWS IoT full documentation can be found [here](https://docs.aws.amazon.com/iot/latest/developerguide/iot-console-signin.html) ## Getting ready with the certificates - transform the private key like this using [OpenSSL](https://www.openssl.org/source/): `openssl.exe pkcs8 -inform PEM -in myprivate.pem.key -topk8 -outform DER -out myprivate.der -v1 PBE-SHA1-3DES -passout pass:awsdemo` - add your private key and certificate in the folder `[worspace.dir]/com.microej.demo.aws.iot/src/main/resources/certificates/device` - add the paths to your private key and certificate in `[worspace.dir]/com.microej.demo.aws.iot/src/main/resources/aws.iot.demo.resources.list` ``` certificates/device/myprivate.der certificates/device/mycertificate.pem.crt ``` - modify the properties file that will be used to initialize the SSL context, located at `[worspace.dir]/com.microej.demo.aws.iot/src/main/resources/certificates/aws.iot.demo.device.certificates.properties` ``` # the path of the device certificate certificate.file.name=/certificates/device/mycertificate.pem.crt # the path of the device private key (encoded with the previous openssl command) private.key.file.name=/certificates/device/myprivate.der # the password used in the previous openssl command (the part afer pass:) -passout pass:awsdemo keystore.password=awsdemo ``` ## Getting ready with the application configuration - in order to find your broker host, go to your AWS IoT Console, click on `Manage` > `Things` and select your Thing previously created. Then click on `Interact` and the broker host is shown under the HTTPS section and should look like this : `{myowndomainid}.amazonaws.com` - configure your information in `[worspace.dir]/com.microej.demo.aws.iot/src/main/java/com/microej/demo/aws/iot/Config.java` : - your MQTT AWS broker host and port : ``` public static final String AWS_BROKER_HOST = "myowndomainid.amazonaws.com"; public static final int AWS_BROKER_PORT = 8883; ``` - your AWS thing id : ``` public static final String AWS_THING_ID = "myThing"; ``` - your Wi-Fi credentials : ``` public static final String SSID = "my_wifi"; public static final String PASSWORD = "passphrase"; ``` ## Launching the demo in simulator mode - Launch the Run Configuration `AWS IoT PubSub Demo [SIM]` to run it in our simulator - Take a look at the console to see the traces of the running application ## Launching the demo on a Wi-Fi board - Launch the Run Configuration `AWS IoT PubSub Demo [SIM]` to generate the binary `microejapp.o` - Use the generated binary to flash your Wi-Fi board and use a serial console of your choice to see the traces of the running application The traces should look like this : ``` [INFO] Device connected to the broker. [INFO] Update listener added, we're now subscribed to the topic awsiot/demo/sample [INFO] Sample data publishing timer task initialized. [INFO] Message received on topic awsiot/demo/sample => MicroEJ [INFO] Message received on topic awsiot/demo/sample => is [INFO] Message received on topic awsiot/demo/sample => a [INFO] Message received on topic awsiot/demo/sample => unique [INFO] Message received on topic awsiot/demo/sample => solution [INFO] Message received on topic awsiot/demo/sample => for [INFO] Message received on topic awsiot/demo/sample => building [INFO] Message received on topic awsiot/demo/sample => Internet [INFO] Message received on topic awsiot/demo/sample => of [INFO] Message received on topic awsiot/demo/sample => Things [INFO] Message received on topic awsiot/demo/sample => and [INFO] Message received on topic awsiot/demo/sample => embedded [INFO] Message received on topic awsiot/demo/sample => software [INFO] Message received on topic awsiot/demo/sample => and [INFO] Message received on topic awsiot/demo/sample => can [INFO] Message received on topic awsiot/demo/sample => now [INFO] Message received on topic awsiot/demo/sample => communicate [INFO] Message received on topic awsiot/demo/sample => with [INFO] Message received on topic awsiot/demo/sample => AWS IoT ``` ## AWS IoT dashboard The AWS IoT console provides some tools to monitor the activity on the broker. - go in the `Monitor` section of the console to see graphs of successful connections to the broker and statistics on the messaging. You can also subscribe on a topic through the console in order to see arriving messages from your device: - go to `Test` - in the `Subscription topic` section, indicate the topic to subscribe to, here `awsiot/demo/sample` - click on `Subscribe to topic` - when the application is running, you should see messages displayed in the AWS IoT console # References - [MicroEJ Developer](https://developer.microej.com) - [Ivy](https://ant.apache.org/ivy/) - [AWS console](https://aws.amazon.com/console/) - [AWS IoT documentation](https://docs.aws.amazon.com/iot/latest/developerguide/iot-console-signin.html) - [OpenSSL](https://www.openssl.org/source/) --- _Markdown_ _Copyright 2018-2019 MicroEJ Corp. All rights reserved._ _Use of this source code is governed by a BSD-style license that can be found with this software._
# Overview This repository contains the projects to setup a Wi-Fi connection using the SoftAP mode a Wi-Fi chip. # Usage Setup ivy to resolve its dependencies in workspace: 1. Click on **Window -> Preferences** 2. Go to **Ivy -> Classpath Container** 3. Check **Resolve dependencies in Workspace** 4. Press **Apply and Close** Import the projects: * [com.microej.example.wifi.setup](com.microej.example.wifi.setup): this project provides abstraction classes to setup the Wi-Fi AP credential using a Soft AP. * [com.microej.example.wifi.setup.rest](com.microej.example.wifi.setup.rest): this project mounts a rest server to provide the Access Point credential to join a Wi-Fi. * [com.microej.example.wifi.setup.web](com.microej.example.wifi.setup.web): this project presents a HTTP page in addition of a rest server to provide the Access Point credential to join a Wi-Fi. Both `com.microej.example.wifi.setup.rest` and `com.microej.example.wifi.setup.web` contain an Entry point to execute the project. The full demo will be using `com.microej.example.wifi.setup.web`, how to run it is explained in the project's [README.md](com.microej.example.wifi.setup.web/README.md). # Requirements - EDC-1.2 or higher - SSL-2.1 or higher - NET-1.0 or higher - ECOM-WIFI-2.1 or higher - ECOM-NETWORK-2.0 or higher # Dependencies _All dependencies are retrieved transitively by Ivy resolver_. # Source N/A # Restrictions None. <!-- Markdown Copyright 2018 IS2T. All rights reserved. This library is provided in source code for use, modification and test, subject to license terms. Any modification of the source code will break IS2T warranties on the whole library. -->
# Overview This project gathers simple sandboxed applications using net libraries. ## Requirements * MicroEJ Studio or SDK 5.1 or later # Usage Each subfolder contains a distinct IOT application. # Changes - See the change log file [CHANGELOG.md](CHANGELOG.md) located at the root of this repository. # License - See the license file [LICENSE.md](LICENSE.md) located at the root of this repository. --- _Markdown_ _Copyright 2019-2020 MicroEJ Corp. All rights reserved._ _Use of this source code is governed by a BSD-style license that can be found with this software._