Wednesday, May 24, 2017
Android Things Developers' Preview 4
One of the biggest improvement is the availability of Google Assistant SDK on all HW supported platforms. Previoulsy, in Dev. Preview 3.1 it was itroduced only on RPI3.
"Earlier this month, we announced a partnership with AIY Projects, enabling Android Things support for the Raspberry Pi-based Voice Kit. And now with DP4, the necessary drivers are provided to support the Google Assistant SDK on all Android Things certified development boards."
Therefore, it is also available on Intel Edison.
As soon as I have some spare time, I'll test it.
Friday, April 28, 2017
My AndroidThings 2
Obviously it is only a starting point: you'll only drivers for few sensors.
As soon as I have time, I'll try with my LCD display, coming from my Grove kit.
Thursday, April 27, 2017
My Android Things
![]() |
AndroidThings |
Android Things is the new name that Google has adopted for its OS for Internet of Things. Before, the code name was “Brillo”.
At the beginning of April 2017 (06/04), Google has released the DP3, adding for example BLE support, and it has been generally made available.
See the announcement here:
Saturday, November 5, 2016
Intricacies and fallacies of Embedded Development
Porting some code developed for the Arduino MKR1000 on an Arduino One (a clone) board, I hit a strange problem: the sprintf function was not working as expected.
Strange, at the beginning I thought. Unbelievable.
I made resort to the skills in C development built 25 years ago. A step-by-step debugging of few lines of code.
Then, after some googling, I discovered what the problem is:
MKR1000 is a board with a chip from ATMEL that is 32bit. Arduino Uno is NOT.
On many "so-constrained boards" the C standard library has limitations introduced to reduce the memory footprint. Especially regarding floating point numbers.
sprintf has one of these limitations.
Resorting to another function provided by ATMEL I resolved.
But the important point is: if it is embedded it has constraints. Limitation.
It is not a smaller version of an Intel chip (the one that you have on your MacBook).
And we must be aware of this.
Tuesday, August 30, 2016
Bluetooth and Bluetooth Low Energy
Introduction.
In this blog post I want to highlight the main features of Bluetooth Low Energy and to show how it can be used on Intel Edison as a communication protocol.
Bluetooth is born, now almost twenty years ago, as a wireless communication technology, short-range: a technology to implement at low cost a Wireless Personal Area Network (WPAN).
Historically, the first and principal use of Bluetooth was voice and audio streaming, for example from a mobile phone or Smartphone, to a headset or a wireless loudspeaker. Today, all the cars provide connectivity from a smartphone or other devices to the speaker using Bluetooth.
In addition, many runner, like me, use Bluetooth wireless headset to listen to music stored on their Smartphone, when they run.
But the advent of Bluetooth Low-Energy (BLE) or Bluetooth Smart has broadened the range of possible solutions and enabled realization of low-power wireless connectivity between devices with limited resources (e.g. powered by a tiny "cell-coin " battery), fitted with sensors (heart rate, temperature) and a central device that receives, processes and displays data.
The center device often is a Smartphone or better today a Smart-watch.
In fact, today the BLE technology is the simplest wireless communication technology short-range that can be used to communicate with a smartphone (iOS, Android, Windows Phone).
BLE is a communication protocol that rightfully can be considered very important in the context of the Internet of Things. For this reason, it is increasingly supported, for example in boards used by so-called Makers: we find an out-of-the-box support for Intel Edison and even in the latest version of the Raspberry PI, version 3.
Main use cases for BLE.
BLE is a low-power wireless communication technology (low power).
It has a very low energy consumption compared to the WI-FI. In fact it is possible to fabricate devices (see the so-called iBeacons) that by using a "coin-cell battery" broadcast for years without having to change the battery.
It has a limited communication range (tens of meters) and the amount of data to be transmitted per second can not be high (say of the order of tens of bytes per second).
There are many scenarios in which you can think of adopting BLE.
Think of the case of use of the "Connected Car": we want to collect a lot of data, produced by the various car components in real-time, allowing you to analyze the behavior, for example to predict the need for maintenance (Predictive Maintenance).
In this case an effective topology provides a " field gateway", a central device that connects via 4G network (for example) with an IoT Cloud Service, and a series of "resource constrained" devices acquiring data from sensors and communicating with the gateway via BLE. The gateway performs local analysis of the data, aggregates the individual readings and sends messages to the Cloud Service.
Another use case is in medical applications. You may think to measure vital signs such as heart rate (Heart Rate, HR) using a device with a sensor that transmits via BLE to a central monitoring.
iBeacon.
An iBeacon is a small low-power device, battery powered (e.g. CR2032), , which transmits periodically, every fraction of a second, a message that allows a detector (eg: an App on iPhone) to identify its presence and read the distance.
The specification of iBeacons was defined by Apple. An iBeacon transmits using BLE, using the advertising messages, with a custom usage of the optional data area advertising packet.
Each message contains a UUID, a Major and a Minor number, which allow you to uniquely distinguish the Beacon.
They are typically used as proximity indicators: to indicate that the detector is close to an iBeacon, and somehow identify the environment where it is located (example: I enter into a shop XXX and I’m in the section YYY of the shop).
Another example: we can assign a distinct beacon to each member of our family and place a detector at the entrance of the House, near the door. Thus, as soon as a person of the family enters in the House the Beacon assigned is detected and person recognized.
The main benefit from Beacons comes from their simplicity. The power consumption is extremely low (in the order of micro-amperes) and then the battery can last a year without having to be replaced.
A very well-made guide that explains how the technology of iBeacon works and how it can be used to add "Indoor Location Awareness" to applications is available on the Apple Developer website:
https://developer.apple.com/ibeacon/Getting-Started-with-iBeacon.pdf
It is interesting that even an Apple iPhone can behave as an iBeacon. Activating an application on your iPhone, you can enable its recognition as soon as you get into an environment that "reveals" the close iBeacon.
Standard.
BLE from the point of view of standardization is a "lightweight" subset of the Bluetooth Core 4.0 specification.
For the specifications, see, for example, the site:
According to the specification, the main characteristics of BLE are:
- Ultra-low peak, average and idle mode power consumption
- Ability to run for years on standard coin-cell batteries
- low cost
- Multi-vendor interoperability
- Enhanced range
Bluetooth Low Energy (BLE).
A device that uses the BLE makes its presence known through an "advertising" mechanism.
As for the advertising and the connection to a central device, roles and actions are defined by the GAP (Generic Access Profile).
The GAP briefly defines how a BLE device can communicate broadcast to the rest of the world its presence, the services it offers and how you can establish a connection between the BLE device and a central device.
GAP defines two main roles:
- Peripheral: a low-power device, resource constrained, which transmits data via BLE;
- A Device Central, which collects data, for example from multiple devices.
The peripheral initially transmits in broadcast mode, by periodically sending an "advertising packet" that provides information on the device itself and can also carry data, if you want to transmit in broadcast mode, "connection-less."
The central device typically performs a scan of devices, capturing the "advertising packets", in order to identify devices with which to connect.
When the device is identified, the central device can establish a connection, thus enabling a bi-directional communication between the peripheral and the central device itself.
The specification defines a few simple rules:
- A device can be connected only to a single central device;
- Generally, after establishing a connection, the device ceases to send advertising packets.
The GAP defines an additional mechanism: a central device can send a BLE Scan Request to a device, to which the device responds with a Scan Response: it is a mechanism that allows an additional sending of descriptive information on the peripheral, required from Device Central.
After having implemented the connection, the communication is ruled by GATT mechanisms (Generic Attribute Profile).
GATT defines how should be the communication between two devices where a connection has been made. It defines how a client can identify the services offered by a server (discovery), how information offered can be read and write, and how receive notifications about state’s changes.
GATT defines two roles:
- Client Device; the device requesting the connection and performing Read and Write Request;
- Server Device: the device that responds to requests.
The communication between the two devices is governed by GATT Transactions’ mechanism.
The exchange of data takes place using logical data structures. It is based on the concepts of:
- Profile;
- Service;
- Characteristics.
Typically, a device defines (or supports) one or more profiles. A profile includes N services and each service provides M characteristics.
An example of profile.
The specification defines, to ensure the maximum possible interoperability between devices and device, a whole set of profiles.
An example of a profile is the Heart Rate Profile (HRP) that is the recommended profile, for example, for the heart rate monitors that use BLE. As indicated in the specification, this profile "enables a Collector Device to connect and interact with Cardio sensors for use in fitness applications."
The profile defines two services, as shown below:
- Heart Rate Service;
- Device Information Service.
BLE and NodeJS.
If you have hardware that can communicate using BLE, you can quickly build applications that exchange information through BLE using the NodeJS platform and the programming language JavaScript.
As previously mentioned, in general (see GAP) BLE will provide for two distinct roles: in other words, our device can be a peripheral device or a central device.
NodeJS provides a modular extension mechanism, based on modules. There is a very broad set of modules, many OpenSource, which can be downloaded from the Internet and installed.
Modules supporting BLE are all "wrapper" of C libraries provided by the underlying hardware platform.
Two Open Source modules can be usefully employed to carry out experiments based on BLE:
- BLENO, which can be used to implement a Device; https://github.com/sandeepmistry/bleno
- NOBLE, to implement a central device; https://github.com/sandeepmistry/noble
Both modules can be installed using NPM.
As we will see below, the code that uses the two modules can be tested on a device like the Intel Edison board and a MacBook.
An experiment: the environment.
To get a better feeling of BLE and how to set up communication with devices based on this protocol we will use the following working environment:
- Intel Edison board, connected to the sensors, which will act as peripheral device;
- A PC that will act as a central device; in my case I used a MacBook Pro (I’m a proud Mac user for years now).
On Mac you can easily install tools that allow you to connect with BLE devices and to analyze and diagnose what is happening during the communication.
In our case we use Developer Tools (Bluetooth Explorer, etc) that are integrated into Xcode.
These tools must be pre-installed by downloading from the Apple website.
In the illustration below, the Bluetooth Explorer is shown, after he has discovered my Intel Edison with BLE activated and initiated a connection (the hostname is thunder10 card and exposes a service of UUID AAA1):
Bluetooth and Intel Edison.
In our experiments we will use as a Peripheral Device an Intel Edison board. It natively supports the BLE protocol and requires no additional hardware. Bluetooth management is implemented at hardware level by the chipset Broadcom BCM43340.
A very complete and updated guide on these subjects has been published by Intel and is available at the following URL:
http://www.intel.com/content/www/us/en/support/boards-and-kits/000005743.html
For further details regarding the use of Bluetooth BLE with Edison the reading of the guide is definitely to be recommended.
Intel Edison is a powerful card and probably its best use is in the role of central device, but being small size and with low-power consumption it can be also effectively used in the role of peripheral device.
The stack of Bluetooth protocol in Edison is implemented using BlueZ, the official "protocol stack" of Linux 1 . BlueZ is an OpenSource project.
For more details on BlueZ you can visit their site:
Intel in the article linked above lists all the commands available at O.S. level, to enable/disable BT and perform most common Bluetooth operations (e.g. scan of visible devices).
The main command-line utility is bluetoothctl.
For example, the following sequence of commands shows how you can make "discoverable" by a Smartphone an Intel Edison board, as seen from the output of the console (obtained through an SSH connection via WIFI to Edison board):
bluetoothctl
[NEW] Controller 58: A8: 39: 00: 18: 94 thunder10 [default]
[Bluetooth] # discoverable on
Changing discoverable on succeeded
[CHG] Controller 58: A8: 39: 00: 18: 94 Discoverable: yes
[NEW] Device F0: DB: F8: 8B: BE: 28 iPhone Louis
[CHG] Device F0: DB: F8: 8B: BE: 28 Connected: no
[DEL] Device F0: DB: F8: 8B: BE: 28 iPhone Louis
[NEW] Device F0: DB: F8: 8B: BE: 28 iPhone Louis
In the second part of the log you see the interaction with a Smartphone (iPhone) who made the discovery of the device and attempted to connect.
Sample code to implement a BLE device.
We are going to explore the JavaScript code, based on BLENO, to implement a simple BLE peripheral device.
The total HW is made by an Intel Edison board, with an Arduino Breakout Board kit. The board is equipped with a Grove Shield to which a Grove Temperature Sensor is connected.
First, to handle a bug in BLENO, tied to a conflict with the daemon bluetoothd, before executing the JavaScript code you must run the following sequence of commands:
# Command needed to solve problems with bluez on Linux
# To enable Bluetooth
rfkill unblock bluetooth
killall bluetoothd
hciconfig hci0 up
Now let's see together the key elements of Javascript code.
To manage in a simple manner sensors you can use the UPM library and UPM_GROVE module (JSUPM_GROVE).
In order to use the modules (BLENO, JSUPM_GROVE) and the temperature sensor:
// Using the bleno BLE module for communication
var bleno = require ( 'bleno');
// Using UPM for Grove Temp Sensor
var groveSensor = require ( 'jsupm_grove');
var tempSensor = new groveSensor.GroveTemp(0);
The sensor is connected to the pin A0.
The first operation the code must carry on is to start the Advertising process, with the periodic emission of the relevant packet, as soon as the BLE module is poweredOn
// When BLENO starts, begin the advertising
bleno.on ( 'stateChange', function (state)
{
console.log ( 'State change:' + state);
if (state === 'poweredOn')
{
// What I want to advertise
bleno.startAdvertising ( 'Thunder10', [ 'FFF1']);
isAdvertising = true;
} else
{
bleno.stopAdvertising ();
isAdvertising = false;
}
});
At this point the events that the JS code must manage are:
- ACCEPT of a connection;
- DISCONNECT, by the Central Device;
- STOP ADVERTISING of the process;
- START of the ADVERTISING process;
- READ request, by the Central Device.
ACCEPT:
// Accepted a connection from a central device
bleno.on ('accept', function (clientAddress)
{
console.log ( "Connection ACCEPTED from address:" + clientAddress);
// Stop advertising
bleno.stopAdvertising ();
isAdvertising = false;
console.log ( 'Stop advertising ...');
});
DISCONNECT:
// Disconnected from a client
bleno.on ('disconnect', function (clientAddress)
{
console.log ( "Disconnected from address:" + clientAddress);
// restart advertising ...
bleno.startAdvertising ();
isAdvertising = true;
console.log ( 'Start advertising ...');
});
In our case we decided to implement the rule that when a connection is established with a Device Central, our device (Edison) stops sending the Advertising Package (thus, it is no longer discoverable).
STOP ADVERTISING:
bleno.on ( 'advertisingStop', function (error)
{
console.log ( 'Advertising Stopped ...');
});
The most complex part of the code is the following:
bleno.on('advertisingStart', function(error)
{
if (error)
{
console.log("Advertising start error:" + error);
} else
{
console.log("Advertising start success");
bleno.setServices([
// Define a new service
new bleno.PrimaryService({
uuid : 'aaa1',
characteristics : [
// Define a new characteristic within that service
new bleno.Characteristic({
value : null,
uuid : 'ccc1',
// the value can ONLY be READ
properties : ['read'],
// Send a message back to the client with the
//characteristic's value
onReadRequest : function(offset, callback)
{
console.log("READ request received");
// read the temperature value from the sensor
this.value = tempSensor.value();
console.log('Temperature Value: ' + this.value);
callback(this.RESULT_SUCCESS, new Buffer(
(this.value ? this.value.toString() : "")));
}
})
]
})
]);
}
});
The choice made here, that is not the only one possible, is to define the service at the time of the start of advertising.
The code defines a service, identified by the UUID AAA1. Within this service you define a single characteristic, with UUID CCC 1. The feature has a value that can only be read (Read) and it is associated with the onReadRequest callback which is invoked by BLENO stack when it receives the READ request. The onReadRequest invokes the code to read the current value of temperature, which is returned by BLE.
In the code we only manage the events (1 to 5) listed above. In general, it should also provide for other events, such as: WRITE Request, Notify. But in our case the value exposed by the service (room temperature) can only be read and we assume that you do not want to provide notification of value changes, from the device to the Device Central.
Each event is run by a suitable callback, as usual in NodeJS.
Using the NOBLE module for the implementation of a BLE Central Device.
Another module that can be used to implement in NodeJS the other side of the connection (the Central Device) is Noble.
I have personally tested Noble on my MacBook, but it also runs on Intel Edison (which can then act as Device Central, as aggregator node).
If you install Noble, in the directory
node_modules / examples
There are three useful sample programs that show how to use the module API:
- enter_exit.js, who simply writes a line each time a visible BLE device connects or disconnects;
- advertisement_discovery.js, performing a scan of the visible devices and displays the list of advertised services.
- Finally peripheral_explorer, to be launched with the <device address> parameter, which shows the services and features exposed by the specified device address.
Finally, a last module that can be used to implement a Beacon is:
Node-bleacon
Some final thoughts.
Writing JavaScript code based on the two mentioned modules is not complex and, starting from the examples, with adequate experience, it is possible to create in a short time applications.
However, in tests carried out by me not always everything worked. In some cases I had to reboot the Edison board to resume the tests correctly, which shows that the two modules and the underlying stack have not, yet, totally free of bugs.
Moreover, the daily experience with the Bluetooth protocol, by users, showed us situations where, for example, the coupling between the two devices is not successful end and attempts must be repeated.
Suggestions for further reading.
A collection of short but very clear and useful pages on BLE is available on the Adafruit website:
https://learn.adafruit.com/introduction-to-bluetooth-low-energy
To learn more about using the iBeacon technology a very useful site is Apple site:
https://developer.apple.com/ibeacon/
Friday, August 19, 2016
Intel Edison and BLE
BLE stands for Bluetooth Low Energy.
Intel Edison supports out-of-the-box (no additional shields required) two communication ways:
- WIFI
- BLE
One scenario where you can think to adopt an Intel Edison board is where you want to use Edison as a Field Gateway. Sensors are connected to small, low-power, resource constrained boards like Arduino 101 (https://www.arduino.cc/en/Main/ArduinoBoard101).
They read the data from sensors and communicate these data to the Edison Gateway using BLE.
Then Edison aggregates and sends out these data using WIFI. For example using MQTT messages to an IoT Cloud Service.
BLE is low power, is easily supported by constrained resources boards, but can be employed only for short range communications (for example in the use case of the “Connected Car”).
I’ll cover BLE and BLE on Edison in next blog posts. Stay tuned.
Wednesday, June 8, 2016
Oracle IoT Cloud Service: concepts and introduction.
Probably this will become a rather long blog post. I hope interesting too.
First of all, let’s recall what we commonly mean with the name “Thing”.
A “Thing” is a real-world (physical) object, that has attached a device, with:
- computing capability
- sensors
- actuators
- connectivity to the network
The last capability probably is considered the most important. Without network connectivity we can call it “an embedded device”, but we don’t use the term “Thing”, in the sense of IoT.
Now, with more and more “devices” capable of computing capabilities and connectivity, the set of solutions available in the industrial and “Makers” world is rapidly increasing.
One example? The first one that comes to my mind: imagine a fleet of trucks transporting food that needs to be kept at low temperature. Or maybe medicines.
You want to be able to:
- control the temperature inside the truck (the fridge)
- control the location of the truck (Is the driver taking a too long nap?)
- verify if the fridge is open and for how long
- A “computing board"
- A GPS sensor
- A temperature sensor
- A 4G shield, to connect through 4G network and send messages.
Well, you may have many different requirements.
I’ll try to list some:
- Security is important
- You want to register “devices” in order to avoid that “a fake” truck drive you mad
- Receive in a reliable way messages from devices with data
- Analyze in real time these data, in order to identify quickly that something wrong is happening (temperature is rising above threshold) and send a SMS alert to the driver
- reset a board.
You can use Oracle IoT Cloud Service.
It is a Cloud Service provided by Oracle, as part of its PaaS platform, with many interesting functionalities for IoT.
With Oracle IoT CS you can develop applications, running on the device, in Java, C, NodeJS. In the rest of the post I’ll consider Java development.
First of all, with Oracle IoT CS, you can register a device. Only registered (and activated devices) can send messages to the IoT CS.
You can register a single device, using the Web UI, or register many devices with a batch, using a csv file.
When you register a device, you associate an ID and a “secret” to the device. These will be used to uniquely identify a device and secure the communication.
Next step is to install, on the device, the Device Client Library, provided by Oracle. You can download it from the Oracle site. At the end, you will need to put in the classpath a single JAR file ( device-library.jar).
Afterwards you will need to generate “a trusted assets store”, that will contain the keys and certificates needed to protect, with TLS, the communication between the device and IoT CS. The trusted assets store (a keystore generated with a provided Oracle tool) is private to the single device.
After having registered the device (or the set of devices) you will need to define a “Device Model”. A Device Model defines the interface between your “Things” and Oracle IoT CS. Again, you do this using Oracle IoT Cs Web UI (or, as we will see in another post, calling a REST API).
The Device Model defines: format of messages exchanged, actions (methods) that you can call on the “Thing”, format of Alert messages.
A Device can have more than one Device Model attached.
Next step is to give a name to the IoT application you’re creating. You will associate the Device Model to the application and in this way you will be able to monitor the flow of messages from the IoT CS console.
Another step is to develop, compile and test the Java application that will run on the board. It will use a set of classes provided by the Device Client Library. For example the “Device Virtualization API”, that abstracts and simplifies the interactions between the devices and IoT CS. Behind the scene, the communication is based on messages exchanged through REST calls, protected by TLS.
At this point you’re able to start sending messages to Oracle IoT CS and monitor the flows of messages using the Web UI.
In the picture you see that the IoT application ApplicationEdison1 has received 12 messages.
And you can imagine 1000 connected devices sending their messages. Each one identified by the device id and some other metadata.
Now, the Analytics part: you want to analyze the streams and identify when some conditions are met (for example: temperature greater than 10 degree (10 C)).
Oracle IoT gives you an already configured and integrated instance of Oracle Stream Explorer.
You can define a Source of Data, starting from a Device Model, and can define an “Exploration”. In this exploration you can specify filters conditions and therefore you will define an output stream that will give only device-id and timestamp for those messages where the condition is met (temperature > 10 )
Lastly, you can define an action, and send the output stream to a Java app that expose a REST service. This Java app will receive a JSON message for each situation where the threshold is crossed (T > 10) and can trigger what you want (for example, send an SMS).
The Java App can be hosted in Oracle Java Cloud Services or Oracle Application Container Cloud Services (based on Docker).
Ok… this is only a first introduction to concepts and what you can do with Oracle IoT CS.
One last thing: as you can see from my Linkedin profile, I work for Oracle. But I’m interested in many (iot) things and, as I have a degree in Physics, I’m always happy when I have time to play with measures and electronics.
Stay tuned.
Monday, June 6, 2016
Working with Oracle IoT Cloud Service (1)
I have created a simple prototype in Java, using Oracle IoT SDK for Java SE.
In this prototype, I use UPM library (upm_grove) to read a temperature sensor, and I send the temperature readings to my instance of Oracle IoT CS using the Device Virtualization API from the SDK.
Not difficult. You need only to carefully configure the keystore in order to have TLS correctly working. More details in the next blog post.
8/11/2016: I have added more blog's posts on Oracle IoT CS... have a look!
Sunday, May 29, 2016
Secure MQQT (2) with RabbitMQ
The next step has been configuring the RabbitMQ broker I have installed on my RPI to use TLS/SSL
It has worked.
The configuration file is located under /etc/rabbitmq
This is the final configuration, enabled for SSL and MQTT.
MQTT port used is 8883 (the default).
[{rabbit, [{loopback_users, []},
{ssl_options, [{cacertfile,"/etc/rabbitmq/certs/ca.crt"},
{certfile, "/etc/rabbitmq/certs/server.crt"},
{keyfile, "/etc/rabbitmq/certs/server.key"},
{password, “<insert here>"}
]}
]},
{rabbitmq_mqtt, [{default_user, <<"guest">>},
{default_pass, <<….>>},
{allow_anonymous, true},
{vhost, <<"/">>},
{exchange, <<"amq.topic">>},
{subscription_ttl, 1800000},
{prefetch, 10},
{ssl_listeners, []},
%% Default MQTT with TLS port is 8883
{ssl_listeners, [8883]},
{tcp_listeners, [1883]},
{tcp_listen_options, [{backlog, 128},
{nodelay, true}]}]}
].
From the RabbitMQ Web UI, accessible at the URL:
http://iotgateway1:15672/#/
you can easily monitor the flow of messages.
Some snapshot from the WebUI
Saturday, May 28, 2016
Secure MQTT (TLS/SSL)
Introduction.
(Updated: 04/11/2016)In this blog post I want to explore how to make secure the communication between an Intel Edison Board and a MQTT Broker, using Transport Layer Security (TLS).
With TLS you can make highly secure the communication between your devices and the broker, by:
- Authenticating the board (the device) against the broker;
- Encrypting all the the communication between the board and the broker; The channel is entirely encrypted and MQTT messages, sent over this channel, are not readable by others;
- Protecting the integrity of messages.
Security is OK, but encryption has its costs: an higher CPU usage and high latency. It is OK if you only need to send several hundreds of bytes/sec (as with our telemetry tests). But if you need to sustain high transmission rates you need to carefully consider the overhead (I don’t think you want to send a film streamed from the Edison, entirely encrypted, in real-time).
In a commercial/industrial scenario you would surely use certificates provided by a Trusted Provider (i.e.: Verisign). For our examples we don’t want to buy certificates and therefore we will use self-signed certificates. In other words we’re signing our certificates.
The configuration.
These are, at high level, the needed configuration steps:- Generate keys and a certificate for “Our Certification Authority"
- Generate the key-pair for the board;
- Generate the key-pair for the broker;
- Configure the MQTT broker in order to use TLS and use the generated keys.
- Configure the JVM on the board and Paho client in order to use TLS and generated keys.
We will do the first tests using Mosquitto.
We will generate key-pair and certificates using Openssl. In my case I have openssl on My MacBook and I will generate all the files using openssl.
A quick list of the commands to be used is found in : http://mosquitto.org/man/mosquitto-tls-7.html.
One advice: be consistent in your specification (always use the name of the server, the same company, the same Country..). You’re mimicking a certification authority that is giving certificates for your boards and server, they won’t accept “fake names”.
1. Generate keys and certificate for the Certification Authority
You're going to generate a self-signed certificate, contained in ca.crt file.
(don’t forget to remember the pass-phrase you set).openssl req -new -x509 -days 730 -extensions v3_ca -keyout ca.key -out ca.crt
2. Generate key-pair for the board (whose name is thunder10).
3. Generate key-pair for the broker.openssl genrsa -des3 -out client.key 2048openssl req -out client.csr -key client.key -newopenssl x509 -req -in client.csr -CA ../authority/ca.crt -CAkey ../authority/ca.key -CAcreateserial -out client.crt -days 730
After you have generated the key-pair for the broker (iotagateway1) you need to sign the certificate assigned to the broker using the keys of the CA.
4. This is the configuration for the Mosquitto Broker (mosquitto.conf):openssl x509 -req -in server.csr -CA ../authority/ca.crt -CAkey ../authority/ca.key -CAcreateserial -out server.crt -days 730Signature oksubject=/C=IT/ST=Italy/L=Rome/O=LSaetta/OU=IT/CN=iotgateway1/emailAddress=luigi.saetta@gmail.comGetting CA Private KeyEnter pass phrase for ../authority/ca.key:
listener 8883cafile /etc/mosquitto/ca_certificates/ca.crtcertfile /etc/mosquitto/certs/server.crtkeyfile /etc/mosquitto/certs/server.keytls_version tlsv1
mosquitto_pub -h iotgateway1 -m "Hello" -p 8883 -t thunder10 --cafile ./authority/ca.crt --key ./board/client.key --cert ./board/client.crt<supply pem passphrase>
private KeyStore readKeyStore(){KeyStore keystore = null;try{FileInputStream is = new FileInputStream(config.KEYSTORE);keystore = KeyStore.getInstance(KeyStore.getDefaultType());String keypwd = config.KEYPWD;keystore.load(is, keypwd.toCharArray());} catch (Exception e){e.printStackTrace();}returnkeystore;}
// verify is SSL is requestedif (config.BROKER.contains("ssl")){try{SSLContext sslContext = SSLContext.getInstance("SSL");TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());KeyStore keyStore = readKeyStore();trustManagerFactory.init(keyStore);sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());connOpts.setSocketFactory(sslContext.getSocketFactory());} catch (Exception e){e.printStackTrace();System.exit(-1);}}
Some more comments about performances.
As I said before, TLS has its overhead, and with constrained devices you should always consider how much additional CPU you need.But, to be precise, the biggest overhead is in the session establishment phase, at the beginning, where client and server exchange the keys-pair and negotiate a symmetric session key, used for all the following communication.
Therefore, if your devices keeps a permanent connection, the overhead after is not so high, at least in terms of latency.