In order for Bluetooth Low Energy (BLE) devices to connect to AWS IoT, AWS has provided the FreeRTOS BLE Library for BLE devices to use MQTT, and Mobile SDKs for Android and iOS for mobile devices to act as connecting agents to AWS IoT.
In order to use those technologies, developers need to integrate the FreeRTOS BLE Library into the BLE device. The integration is difficult for some BLE devices especially for brown-field devices that are already running in the field. For new BLE devices, some developers choose not do add additional components into the firmware.
To address the need of such applications, this repository provides reference implementation of an Android app that can interact with BLE devices without requiring the device to run the FreeRTOS BLE Library. As long as the device runs a GATT server, this app can connect to it, convert the information sent by the BLE device into MQTT messages and publish them to AWS IoT. This app can be customized to subscribe to MQTT topics, convert messages into proprietary format then send them over to the BLE device. The diagram below illustrate this architecture.
This proxy using AWS Cognito as credential provider. Refer to the “Set up AWS IoT and Amazon Cognito” section in this document for how to set it up to work with this application.
- git clone this project.
- Update Thing ID, Broker Endpoint, IoT Policy name, AWS Region in com/amazonaws/awsiotproxy/ProxyConfig.java. Refer to this document (https://docs.aws.amazon.com/freertos/latest/userguide/ble-demo.html#ble-sdk-app) and follow the instructions under “To configure the Android SDK demo application” to create the IoT Policy.
- Update Cognito Identity PoolId/Region, Cognito User PoolId/Region/AppClientId/AppClientSecret in raw/awsconfiguration.json. Refer to this document (https://docs.aws.amazon.com/freertos/latest/userguide/ble-demo.html) and follow the instructions under “Set up AWS IoT and Amazon Cognito” to set up and get the values for those configurations.
- Build the mobile app, install it on an Android device, launch it.
- A sign in/sign up page will show up. User can sign in with Cognito user name/password, or choose to create a new account via sign up:
- On the DEVICES tab, a dummy device will be created base on the info in com/amazonaws/awsiotproxy/ProxyConfig.java. Click it to create connection with AWS IoT core.
- After connected to AWS IoT core, dummy device will publish to topic "proxy/test" with a json format payload every 5 secs.
- After connected to AWS IoT core, use PUBLISH and SUBSCRIBE tabs to publish/subscribe/unsubscribe to/from specific topic.
- User can check MQTT messages on AWS IoT console. For more details, refer to this document;
Use with ESP32 gatt_server demo
The Android application built in the previous step can work with an ESP32 device running with its gatt_server demo after you apply a patch contained in this project.
- Install the ESP IDF (https://github.com/espressif/esp-idf).
- Apply patch from this project. Assuming you have installed this project under <install_dir> and ESP IDF has been installed under <esp_idf_dir>:
cp <intall_dir>/esp32_patch/0001-aws-iot-proxy-adding-dummy-message-for-aws-iot-proxy.patch <esp_idf_dir>/examples/bluetooth/bluedroid/ble/gatt_server
cd <esp_idf_dir>/examples/bluetooth/bluedroid/ble/gatt_server
git apply 0001-aws-iot-proxy-adding-dummy-message-for-aws-iot-proxy.patch
- Build and flash ESP32:
idf.py build
idf.py -p /dev/ttyUSB0 flash
- Boot up the ESP32 device. Go to the mobile app, swipe down to scan new devices. The ESP32 should appear on the screen.
- Click device in devices list to connect.
- ESP32 will send dummy data to the mobile app, then the app will convert the data into JSON payload and publish to AWS IoT Core.
In this reference implementation, a CustomizedThing is abstracted as a java class to provide the following functionalities:
- Connect to IoT: Connect to AWS IoT cloud as a Cognito user.
- Publish to IoT: Publish message to specific topic.
- Subscribe to IoT: Subscribe to specific topic.
- Unsubscribe to IoT: Unsubscribe to specific topic.
- Publish to Thing: When received message from subscribed topic, send it back to local devices.
- Send ACK to Thing: Send ACK to device when publish/subscribe/unsubscribe successfully.
To adapt it with private local protocol:
- Extend from
class CustomizedThing
. - Create coder/decoder similar to
class MyTLV
, which supports decode messages from device to connect/publish/subscribe/unsubscribe behaviors and encode ACK/publish messages from Cloud/App to device.
Since the data type of GATT characteristics operation is bytes array, user need to define several methods takes bytes array and CustomizedMqttEnvelope
as parameters. Take class MyTLV
as an example, which defines a simple TLV(Type-Length-Value) protocol:
In this example protocol, we defined 7 types as blow:
public enum TLVType {
INVALID,
PUBACK,
SUBACK,
UNSUBACK,
PUB,
SUB,
UNSUB,
}
To make it adapt with Proxy, we defines constructor:
MyTLV(CustomizedMqttEnvelope envelope)
: Create aMyTLV
object withCustomizedMqttEnvelope
. It will callMyTLV.encode()
method inside to generate encoded bytes array write to device characteristics base on input envelope.MyTLV(@NonNull byte[] encodedBytesStream)
: Create aMyTLV
object with encoded bytes array read from device characteristics . It will callMyTLV.decode()
method to get type, length, and values from encoded bytes. After that, user can callCustomizedMqttEnvelope.toCustomizedMqttEnvelope()
to get aCustomizedMqttEnvelope
object.
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.