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