1.. _mqtt-publisher-sample:
2
3MQTT Publisher
4##############
5
6Overview
7********
8
9`MQTT <http://mqtt.org/>`_ (MQ Telemetry Transport) is a lightweight
10publish/subscribe messaging protocol optimized for small sensors and
11mobile devices.
12
13The Zephyr MQTT Publisher sample application is a MQTT v3.1.1
14client that sends MQTT PUBLISH messages to a MQTT broker.
15See the `MQTT V3.1.1 spec`_ for more information.
16
17.. _MQTT V3.1.1 spec: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
18
19The source code of this sample application can be found at:
20:zephyr_file:`samples/net/mqtt_publisher`.
21
22Requirements
23************
24
25- Linux machine
26- Freedom Board (FRDM-K64F)
27- Mosquitto server: any version that supports MQTT v3.1.1. This sample
28 was tested with mosquitto 1.3.4.
29- Mosquitto subscriber
30- LAN for testing purposes (Ethernet)
31
32Build and Running
33*****************
34
35Currently, this sample application only supports static IP addresses.
36Open the :file:`src/config.h` file and set the IP addresses according
37to the LAN environment.
38Alternatively, set the IP addresses in the :file:`prj.conf` file.
39
40The file :file:`src/config.h` also contains some variables that may be changed:
41
42MQTT broker TCP port:
43
44.. code-block:: c
45
46 #define SERVER_PORT 1883
47
48Application sleep time:
49
50.. code-block:: c
51
52 #define APP_SLEEP_MSECS 500
53
54Max number of connection tries:
55
56.. code-block:: c
57
58 #define APP_CONNECT_TRIES 10
59
60MQTT Client Identifier:
61
62.. code-block:: c
63
64 #define MQTT_CLIENTID "zephyr_publisher"
65
66This sample application supports the IBM Bluemix Watson topic format that can
67be enabled by changing the default value of APP_BLUEMIX_TOPIC from 0 to 1:
68
69.. code-block:: c
70
71 #define APP_BLUEMIX_TOPIC 1
72
73The Bluemix topic may include some parameters like device type, device
74identifier, event type and message format. This application uses the
75following macros to specify those values:
76
77.. code-block:: c
78
79 #define BLUEMIX_DEVTYPE "sensor"
80 #define BLUEMIX_DEVID "carbon"
81 #define BLUEMIX_EVENT "status"
82 #define BLUEMIX_FORMAT "json"
83
84Max number of MQTT PUBLISH iterations is defined in Kconfig:
85
86.. code-block:: c
87
88 CONFIG_NET_SAMPLE_APP_MAX_ITERATIONS 5
89
90On your Linux host computer, open a terminal window, locate the source code
91of this sample application (i.e., :zephyr_file:`samples/net/mqtt_publisher`) and type:
92
93.. zephyr-app-commands::
94 :zephyr-app: samples/net/mqtt_publisher
95 :board: frdm_k64f
96 :goals: build flash
97 :compact:
98
99Open another terminal window and type:
100
101.. code-block:: console
102
103 $ sudo mosquitto -v -p 1883
104
105Open another terminal window and type:
106
107.. code-block:: console
108
109 $ mosquitto_sub -t sensors
110
111Connecting securely using TLS
112=============================
113
114While it is possible to set up a local secure MQTT server and update the
115sample to connect to it, it does require some work on the user's part to
116create the certificates and to set them up with the server.
117
118Alternatively, a `publicly available Mosquitto MQTT server/broker
119<https://test.mosquitto.org/>`_ is available to quickly and easily
120try this sample with TLS enabled, by following these steps:
121
122- Download the server's CA certificate file in DER format from
123 https://test.mosquitto.org
124- In :file:`src/test_certs.h`, set ``ca_certificate[]`` using the certificate
125 contents (or set it to its filename if the socket offloading feature is
126 enabled on your platform and :kconfig:`CONFIG_TLS_CREDENTIAL_FILENAMES` is
127 set to ``y``).
128- In :file:`src/config.h`, set SERVER_ADDR to the IP address to connect to,
129 i.e., the IP address of test.mosquitto.org ``"37.187.106.16"``
130- In :file:`src/main.c`, set TLS_SNI_HOSTNAME to ``"test.mosquitto.org"``
131 to match the Common Name (CN) in the downloaded certificate.
132- Build the sample by specifying ``-DOVERLAY_CONFIG=overlay-tls.conf``
133 when running ``west build`` or ``cmake`` (or refer to the TLS offloading
134 section below if your platform uses the offloading feature).
135- Flash the binary onto the device to run the sample:
136
137.. code-block:: console
138
139 $ ninja flash
140
141TLS offloading
142==============
143
144For boards that support this feature, TLS offloading is used by
145specifying ``-DOVERLAY_CONFIG=overlay-tls-offload.conf`` when running ``west
146build`` or ``cmake``.
147
148Using this overlay enables TLS without bringing in mbedtls.
149
150SOCKS5 proxy support
151====================
152
153It is also possible to connect to the MQTT broker through a SOCKS5 proxy.
154To enable it, use ``-DOVERLAY_CONFIG=overlay-socks5.conf`` when running ``west
155build`` or ``cmake``.
156
157By default, to make the testing easier, the proxy is expected to run on the
158same host as the MQTT broker.
159
160To start a proxy server, ``ssh`` can be used.
161Use the following command to run it on your host with the default port:
162
163.. code-block: console
164
165 $ ssh -N -D 0.0.0.0:1080 localhost
166
167To connect to a proxy server that is not running under the same IP as the MQTT
168broker or uses a different port number, modify the following values:
169
170.. code-block:: c
171
172 #define SOCKS5_PROXY_ADDR SERVER_ADDR
173 #define SOCKS5_PROXY_PORT 1080
174
175
176Running on cc3220sf_launchxl
177============================
178
179Offloading on cc3220sf_launchxl also provides DHCP services, so the sample
180uses dynamic IP addresses on this board.
181
182By default, the sample is set up to connect to the broker at the address
183specified by SERVER_ADDR in config.h. If the broker is secured using TLS, users
184should enable TLS offloading, upload the server's certificate
185authority file in DER format to the device filesystem using TI Uniflash,
186and name it "ca_cert.der".
187
188In addition, TLS_SNI_HOSTNAME in main.c should be defined to match the
189Common Name (CN) in the certificate file in order for the TLS domain
190name verification to succeed.
191
192See the note on Provisioning and Fast Connect in :ref:`cc3220sf_launchxl`.
193
194The Secure Socket Offload section has information on programming the
195certificate to flash.
196
197Proceed to test as above.
198
199Sample output
200=============
201
202This is the output from the FRDM UART console, with:
203
204.. code-block:: c
205
206 CONFIG_NET_SAMPLE_APP_MAX_ITERATIONS 5
207
208.. code-block:: console
209
210 [dev/eth_mcux] [INF] eth_0_init: Enabled 100M full-duplex mode.
211 [dev/eth_mcux] [DBG] eth_0_init: MAC 00:04:9f:3e:1a:0a
212 [publisher:233] network_setup: 0 <OK>
213 [publisher:258] mqtt_init: 0 <OK>
214 [connect_cb:81] user_data: CONNECTED
215 [try_to_connect:212] mqtt_tx_connect: 0 <OK>
216 [publisher:276] try_to_connect: 0 <OK>
217 [publisher:285] mqtt_tx_pingreq: 0 <OK>
218 [publisher:290] mqtt_tx_publish: 0 <OK>
219 [publish_cb:149] <MQTT_PUBACK> packet id: 1888, user_data: PUBLISH
220 [publisher:295] mqtt_tx_publish: 0 <OK>
221 [publish_cb:149] <MQTT_PUBREC> packet id: 16356, user_data: PUBLISH
222 [publish_cb:149] <MQTT_PUBCOMP> packet id: 16356, user_data: PUBLISH
223 [publisher:300] mqtt_tx_publish: 0 <OK>
224 [publisher:285] mqtt_tx_pingreq: 0 <OK>
225 [publisher:290] mqtt_tx_publish: 0 <OK>
226 [publish_cb:149] <MQTT_PUBACK> packet id: 45861, user_data: PUBLISH
227 [publisher:295] mqtt_tx_publish: 0 <OK>
228 [publish_cb:149] <MQTT_PUBREC> packet id: 53870, user_data: PUBLISH
229 [publish_cb:149] <MQTT_PUBCOMP> packet id: 53870, user_data: PUBLISH
230 [publisher:300] mqtt_tx_publish: 0 <OK>
231 [publisher:285] mqtt_tx_pingreq: 0 <OK>
232 [publisher:290] mqtt_tx_publish: 0 <OK>
233 [publish_cb:149] <MQTT_PUBACK> packet id: 60144, user_data: PUBLISH
234 [publisher:295] mqtt_tx_publish: 0 <OK>
235 [publish_cb:149] <MQTT_PUBREC> packet id: 6561, user_data: PUBLISH
236 [publish_cb:149] <MQTT_PUBCOMP> packet id: 6561, user_data: PUBLISH
237 [publisher:300] mqtt_tx_publish: 0 <OK>
238 [publisher:285] mqtt_tx_pingreq: 0 <OK>
239 [publisher:290] mqtt_tx_publish: 0 <OK>
240 [publish_cb:149] <MQTT_PUBACK> packet id: 38355, user_data: PUBLISH
241 [publisher:295] mqtt_tx_publish: 0 <OK>
242 [publish_cb:149] <MQTT_PUBREC> packet id: 60656, user_data: PUBLISH
243 [publish_cb:149] <MQTT_PUBCOMP> packet id: 60656, user_data: PUBLISH
244 [publisher:300] mqtt_tx_publish: 0 <OK>
245 [publisher:285] mqtt_tx_pingreq: 0 <OK>
246 [publisher:290] mqtt_tx_publish: 0 <OK>
247 [publish_cb:149] <MQTT_PUBACK> packet id: 28420, user_data: PUBLISH
248 [publisher:295] mqtt_tx_publish: 0 <OK>
249 [publish_cb:149] <MQTT_PUBREC> packet id: 49829, user_data: PUBLISH
250 [publish_cb:149] <MQTT_PUBCOMP> packet id: 49829, user_data: PUBLISH
251 [publisher:300] mqtt_tx_publish: 0 <OK>
252 [disconnect_cb:101] user_data: DISCONNECTED
253 [publisher:304] mqtt_tx_disconnect: 0 <OK>
254
255 Bye!
256
257The line:
258
259.. code-block:: console
260
261 [try_to_connect:220] mqtt_connect: -5 <ERROR>
262
263means that an error was detected and a new connect message will be sent.
264
265The MQTT API is asynchronous, so messages are displayed as the callbacks are
266executed.
267
268This is the information that the subscriber will receive:
269
270.. code-block:: console
271
272 $ mosquitto_sub -t sensors
273 DOORS:OPEN_QoS0
274 DOORS:OPEN_QoS1
275 DOORS:OPEN_QoS2
276 DOORS:OPEN_QoS0
277 DOORS:OPEN_QoS1
278 DOORS:OPEN_QoS2
279 DOORS:OPEN_QoS0
280 DOORS:OPEN_QoS1
281 DOORS:OPEN_QoS2
282 DOORS:OPEN_QoS0
283 DOORS:OPEN_QoS1
284 DOORS:OPEN_QoS2
285 DOORS:OPEN_QoS0
286 DOORS:OPEN_QoS1
287 DOORS:OPEN_QoS2
288
289This is the output from the MQTT broker:
290
291.. code-block:: console
292
293 $ sudo mosquitto -v
294 1485663791: mosquitto version 1.3.4 (build date 2014-08-17 00:14:52-0300) starting
295 1485663791: Using default config.
296 1485663791: Opening ipv4 listen socket on port 1883.
297 1485663791: Opening ipv6 listen socket on port 1883.
298 1485663797: New connection from 192.168.1.101 on port 1883.
299 1485663797: New client connected from 192.168.1.101 as zephyr_publisher (c1, k0).
300 1485663797: Sending CONNACK to zephyr_publisher (0)
301 1485663798: Received PINGREQ from zephyr_publisher
302 1485663798: Sending PINGRESP to zephyr_publisher
303 1485663798: Received PUBLISH from zephyr_publisher (d0, q0, r0, m0, 'sensors', ... (15 bytes))
304 1485663799: Received PUBLISH from zephyr_publisher (d0, q1, r0, m1888, 'sensors', ... (15 bytes))
305 1485663799: Sending PUBACK to zephyr_publisher (Mid: 1888)
306 1485663799: Received PUBLISH from zephyr_publisher (d0, q2, r0, m16356, 'sensors', ... (15 bytes))
307 1485663799: Sending PUBREC to zephyr_publisher (Mid: 16356)
308 1485663799: Received PUBREL from zephyr_publisher (Mid: 16356)
309 1485663799: Sending PUBCOMP to zephyr_publisher (Mid: 16356)
310 1485663800: Received PINGREQ from zephyr_publisher
311 1485663800: Sending PINGRESP to zephyr_publisher
312 1485663800: Received PUBLISH from zephyr_publisher (d0, q0, r0, m0, 'sensors', ... (15 bytes))
313 1485663801: Received PUBLISH from zephyr_publisher (d0, q1, r0, m45861, 'sensors', ... (15 bytes))
314 1485663801: Sending PUBACK to zephyr_publisher (Mid: 45861)
315 1485663801: Received PUBLISH from zephyr_publisher (d0, q2, r0, m53870, 'sensors', ... (15 bytes))
316 1485663801: Sending PUBREC to zephyr_publisher (Mid: 53870)
317 1485663801: Received PUBREL from zephyr_publisher (Mid: 53870)
318 1485663801: Sending PUBCOMP to zephyr_publisher (Mid: 53870)
319 1485663802: Received PINGREQ from zephyr_publisher
320 1485663802: Sending PINGRESP to zephyr_publisher
321 1485663802: Received PUBLISH from zephyr_publisher (d0, q0, r0, m0, 'sensors', ... (15 bytes))
322 1485663803: Received PUBLISH from zephyr_publisher (d0, q1, r0, m60144, 'sensors', ... (15 bytes))
323 1485663803: Sending PUBACK to zephyr_publisher (Mid: 60144)
324 1485663803: Received PUBLISH from zephyr_publisher (d0, q2, r0, m6561, 'sensors', ... (15 bytes))
325 1485663803: Sending PUBREC to zephyr_publisher (Mid: 6561)
326 1485663803: Received PUBREL from zephyr_publisher (Mid: 6561)
327 1485663803: Sending PUBCOMP to zephyr_publisher (Mid: 6561)
328 1485663804: Received PINGREQ from zephyr_publisher
329 1485663804: Sending PINGRESP to zephyr_publisher
330 1485663804: Received PUBLISH from zephyr_publisher (d0, q0, r0, m0, 'sensors', ... (15 bytes))
331 1485663805: Received PUBLISH from zephyr_publisher (d0, q1, r0, m38355, 'sensors', ... (15 bytes))
332 1485663805: Sending PUBACK to zephyr_publisher (Mid: 38355)
333 1485663805: Received PUBLISH from zephyr_publisher (d0, q2, r0, m60656, 'sensors', ... (15 bytes))
334 1485663805: Sending PUBREC to zephyr_publisher (Mid: 60656)
335 1485663805: Received PUBREL from zephyr_publisher (Mid: 60656)
336 1485663805: Sending PUBCOMP to zephyr_publisher (Mid: 60656)
337 1485663806: Received PINGREQ from zephyr_publisher
338 1485663806: Sending PINGRESP to zephyr_publisher
339 1485663806: Received PUBLISH from zephyr_publisher (d0, q0, r0, m0, 'sensors', ... (15 bytes))
340 1485663807: Received PUBLISH from zephyr_publisher (d0, q1, r0, m28420, 'sensors', ... (15 bytes))
341 1485663807: Sending PUBACK to zephyr_publisher (Mid: 28420)
342 1485663807: Received PUBLISH from zephyr_publisher (d0, q2, r0, m49829, 'sensors', ... (15 bytes))
343 1485663807: Sending PUBREC to zephyr_publisher (Mid: 49829)
344 1485663807: Received PUBREL from zephyr_publisher (Mid: 49829)
345 1485663807: Sending PUBCOMP to zephyr_publisher (Mid: 49829)
346 1485663808: Received DISCONNECT from zephyr_publisher
347