-
Notifications
You must be signed in to change notification settings - Fork 884
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* added mqtt pub/sub example * added mqtt pub/sub example * removed unnecessary comments * Move mqtt example to wifi folder * Tidy up mqtt example Fix review comments and build warnings. Use MQTT_SERVER build variable instead of hard coding IP address. Make a DNS request for the server. Use async timer for publishing the temperature. * Add support for username and password * Add TLS support Move the code down one level * Add some more topics print, just print the message to stdout ping, publish uptime to pong exit, quit the client * Add will topic /online Add some defines for some magic numbers * Unique topic names per device Disabled by default with MQTT_UNIQUE_TOPIC * Some MQTT updates Change /pong to /uptime Display a message if MQTT_SERVER is not defined Put picow_ in the name like the other examples Add details to the readme! --------- Co-authored-by: ellebi2000 <[email protected]> Co-authored-by: Peter Harper <[email protected]>
- Loading branch information
1 parent
b01d600
commit bc20ff6
Showing
12 changed files
with
657 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# Define the host name of the MQTT server in an environment variable or pass it to cmake, | ||
# e.g. cmake -DMQTT_SERVER=myserver .. | ||
|
||
if (DEFINED ENV{MQTT_SERVER} AND (NOT MQTT_SERVER)) | ||
set(MQTT_SERVER $ENV{MQTT_SERVER}) | ||
message("Using MQTT_SERVER from environment ('${MQTT_SERVER}')") | ||
endif() | ||
if (NOT MQTT_SERVER) | ||
message("Skipping MQTT example as MQTT_SERVER is not defined") | ||
return() | ||
endif() | ||
# Define the name of an MQTT broker/server to enable this example | ||
set(MQTT_SERVER "${MQTT_SERVER}" CACHE INTERNAL "MQTT server for examples") | ||
|
||
if (DEFINED ENV{MQTT_USERNAME} AND (NOT MQTT_USERNAME)) | ||
set(MQTT_USERNAME $ENV{MQTT_USERNAME}) | ||
message("Using MQTT_USERNAME from environment ('${MQTT_USERNAME}')") | ||
endif() | ||
set(MQTT_USERNAME "${MQTT_USERNAME}" CACHE INTERNAL "MQTT user name for examples") | ||
if (DEFINED ENV{MQTT_PASSWORD} AND (NOT MQTT_PASSWORD)) | ||
set(MQTT_PASSWORD $ENV{MQTT_PASSWORD}) | ||
message("Using MQTT_PASSWORD from environment") | ||
endif() | ||
set(MQTT_PASSWORD "${MQTT_PASSWORD}" CACHE INTERNAL "MQTT password for examples") | ||
|
||
# Set path to the certificate include file | ||
if (NOT MQTT_CERT_PATH) | ||
set(MQTT_CERT_PATH ${CMAKE_CURRENT_LIST_DIR}/certs/${MQTT_SERVER}) | ||
endif() | ||
|
||
# Set the name of the certificate include file | ||
if (NOT MQTT_CERT_INC) | ||
set(MQTT_CERT_INC mqtt_client.inc) | ||
endif() | ||
|
||
set(TARGET_NAME picow_mqtt_client) | ||
add_executable(${TARGET_NAME} | ||
mqtt_client.c | ||
) | ||
target_link_libraries(${TARGET_NAME} | ||
pico_stdlib | ||
hardware_adc | ||
pico_cyw43_arch_lwip_threadsafe_background | ||
pico_lwip_mqtt | ||
pico_mbedtls | ||
pico_lwip_mbedtls | ||
) | ||
target_include_directories(${TARGET_NAME} PRIVATE | ||
${CMAKE_CURRENT_LIST_DIR} | ||
${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required | ||
) | ||
target_compile_definitions(${TARGET_NAME} PRIVATE | ||
WIFI_SSID=\"${WIFI_SSID}\" | ||
WIFI_PASSWORD=\"${WIFI_PASSWORD}\" | ||
MQTT_SERVER=\"${MQTT_SERVER}\" | ||
) | ||
if (EXISTS "${MQTT_CERT_PATH}/${MQTT_CERT_INC}") | ||
target_compile_definitions(${TARGET_NAME} PRIVATE | ||
MQTT_CERT_INC=\"${MQTT_CERT_INC}\" # contains the tls certificates for MQTT_SERVER needed by the client | ||
ALTCP_MBEDTLS_AUTHMODE=MBEDTLS_SSL_VERIFY_REQUIRED | ||
) | ||
target_include_directories(${TARGET_NAME} PRIVATE | ||
${MQTT_CERT_PATH} | ||
) | ||
endif() | ||
if (MQTT_USERNAME AND MQTT_PASSWORD) | ||
target_compile_definitions(${TARGET_NAME} PRIVATE | ||
MQTT_USERNAME=\"${MQTT_USERNAME}\" | ||
MQTT_PASSWORD=\"${MQTT_PASSWORD}\" | ||
) | ||
endif() | ||
pico_add_extra_outputs(${TARGET_NAME}) | ||
|
||
# Ignore warnings from lwip code | ||
set_source_files_properties( | ||
${PICO_LWIP_PATH}/src/apps/altcp_tls/altcp_tls_mbedtls.c | ||
PROPERTIES | ||
COMPILE_OPTIONS "-Wno-unused-result" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# Quick start | ||
|
||
To use this example you will need to install an MQTT server on your network. | ||
To install the Mosquitto MQTT client on a Raspberry Pi Linux device run the following... | ||
|
||
``` | ||
sudo apt install mosquitto | ||
sudo apt install mosquitto-clients | ||
``` | ||
|
||
Check it works... | ||
|
||
``` | ||
mosquitto_pub -t test_topic -m "Yes it works" -r | ||
mosquitto_sub -t test_topic -C 1 | ||
``` | ||
|
||
To allow an external client to connect to the server you will have to change the configuration. Add the following to /etc/mosquitto/conf.d/mosquitto.conf | ||
|
||
``` | ||
allow_anonymous true | ||
listener 1883 0.0.0.0 | ||
``` | ||
|
||
Then restart the service. | ||
|
||
``` | ||
sudo service mosquitto restart | ||
``` | ||
|
||
When building the code set the host name of the MQTT server, e.g. | ||
|
||
``` | ||
export MQTT_SERVER=myhost | ||
cmake .. | ||
``` | ||
|
||
The example should publish its core temperature to the /temperature topic. You can subscribe to this topic from another machine. | ||
|
||
``` | ||
mosquitto_sub -h $MQTT_SERVER -t '/temperature' | ||
``` | ||
|
||
You can turn the led on and off by publishing messages. | ||
|
||
``` | ||
mosquitto_pub -h $MQTT_SERVER -t '/led' -m on | ||
mosquitto_pub -h $MQTT_SERVER -t '/led' -m off | ||
``` | ||
|
||
# Security | ||
|
||
If your server has a username and password, you can set these with the following variables. | ||
|
||
``` | ||
export MQTT_USERNAME=user | ||
export MQTT_PASSWORD=pass | ||
``` | ||
|
||
Be aware that these details are sent in plain text unless you use TLS. | ||
|
||
## Using TLS | ||
|
||
To use TLS and client server authentication you need some keys and certificates for the client and server. | ||
The `certs/makecerts.sh` script demonstrates a way to make these. | ||
It creates a folder named after `MQTT_SERVER` containing all the required files. | ||
From these files it generates a header file `mqtt_client.inc` included by the code. | ||
Your server will have to be configured to use TLS and the port 8883 rather than the non-TLS port 1883. | ||
|
||
``` | ||
listener 1883 127.0.0.1 | ||
|
||
listener 8883 0.0.0.0 | ||
allow_anonymous true | ||
cafile /etc/mosquitto/ca_certificates/ca.crt | ||
certfile /etc/mosquitto/certs/server.crt | ||
keyfile /etc/mosquitto/certs/server.key | ||
require_certificate true | ||
``` | ||
|
||
To connect to your server with the mosquitto tools in linux you will have to pass extra parameters. | ||
|
||
``` | ||
mosquitto_pub -h $MQTT_SERVER --cafile $MQTT_SERVER/ca.crt --key $MQTT_SERVER/client.key --cert $MQTT_SERVER/client.crt -t /led -m on | ||
mosquitto_sub -h $MQTT_SERVER --cafile $MQTT_SERVER/ca.crt --key $MQTT_SERVER/client.key --cert $MQTT_SERVER/client.crt -t "/temperature" | ||
``` | ||
|
||
There are some shell scripts in the certs folder to reduce the amount of typing assuming `MQTT_SERVER` is defined. | ||
|
||
``` | ||
cd certs | ||
./pub.sh /led on | ||
./sub.sh /temperature | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#!/usr/bin/bash | ||
|
||
if [ "${PWD##*/}" != "certs" ]; then | ||
echo Run this in the certs folder | ||
exit 1 | ||
fi | ||
if [ -z "$MQTT_SERVER" ]; then | ||
echo Define MQTT_SERVER | ||
exit 1 | ||
fi | ||
SERVER_NAME=$MQTT_SERVER | ||
|
||
if [ -d "$SERVER_NAME" ]; then | ||
echo Run \"rm -fr $SERVER_NAME\" to regenerate these keys | ||
exit 1 | ||
fi | ||
mkdir $SERVER_NAME | ||
echo Generating keys in $PWD/$SERVER_NAME | ||
|
||
openssl genrsa -out $SERVER_NAME/ca.key 2048 | ||
openssl req -new -x509 -days 99999 -key $SERVER_NAME/ca.key -out $SERVER_NAME/ca.crt -subj "/C=UK/ST=Cambridgeshire/L=Cambridge/O=Raspberry Pi Ltd/OU=Software/CN=rpiroot" | ||
|
||
openssl genrsa -out $SERVER_NAME/server.key 2048 | ||
openssl req -new -out $SERVER_NAME/server.csr -key $SERVER_NAME/server.key -subj "/C=UK/ST=Cambridgeshire/L=Cambridge/O=Raspberry Pi Ltd/OU=Software/CN=$SERVER_NAME" | ||
openssl x509 -req -in $SERVER_NAME/server.csr -CA $SERVER_NAME/ca.crt -CAkey $SERVER_NAME/ca.key -CAcreateserial -out $SERVER_NAME/server.crt -days 9999 | ||
|
||
openssl genrsa -out $SERVER_NAME/client.key 2048 | ||
openssl req -new -out $SERVER_NAME/client.csr -key $SERVER_NAME/client.key -subj "/C=UK/ST=Cambridgeshire/L=Cambridge/O=Raspberry Pi Ltd/OU=Software/CN=$SERVER_NAME" | ||
openssl x509 -req -in $SERVER_NAME/client.csr -CA $SERVER_NAME/ca.crt -CAkey $SERVER_NAME/ca.key -CAcreateserial -out $SERVER_NAME/client.crt -days 999 | ||
|
||
echo -n \#define TLS_ROOT_CERT \" > $SERVER_NAME/mqtt_client.inc | ||
cat $SERVER_NAME/ca.crt | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/mqtt_client.inc | ||
echo "\"" >> $SERVER_NAME/mqtt_client.inc | ||
echo >> $SERVER_NAME/mqtt_client.inc | ||
|
||
echo -n \#define TLS_CLIENT_KEY \" >> $SERVER_NAME/mqtt_client.inc | ||
cat $SERVER_NAME/client.key | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/mqtt_client.inc | ||
echo "\"" >> $SERVER_NAME/mqtt_client.inc | ||
echo >> $SERVER_NAME/mqtt_client.inc | ||
|
||
echo -n \#define TLS_CLIENT_CERT \" >> $SERVER_NAME/mqtt_client.inc | ||
cat $SERVER_NAME/client.crt | awk '{printf "%s\\n\\\n", $0}' >> $SERVER_NAME/mqtt_client.inc | ||
echo "\"" >> $SERVER_NAME/mqtt_client.inc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#/usr/bin/bash | ||
|
||
if [ -z "$MQTT_SERVER" ]; then | ||
echo Define MQTT_SERVER | ||
exit 1 | ||
fi | ||
|
||
mosquitto_pub -h $MQTT_SERVER --cafile $MQTT_SERVER/ca.crt --key $MQTT_SERVER/client.key --cert $MQTT_SERVER/client.crt -t "$1" -m "$2" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#/usr/bin/bash | ||
|
||
if [ -z "$MQTT_SERVER" ]; then | ||
echo Define MQTT_SERVER | ||
exit 1 | ||
fi | ||
|
||
mosquitto_sub -h $MQTT_SERVER --cafile $MQTT_SERVER/ca.crt --key $MQTT_SERVER/client.key --cert $MQTT_SERVER/client.crt -t "$1" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#ifndef _LWIPOPTS_H | ||
#define _LWIPOPTS_H | ||
|
||
// Need more memory for TLS | ||
#ifdef MQTT_CERT_INC | ||
#define MEM_SIZE 8000 | ||
#endif | ||
|
||
// Generally you would define your own explicit list of lwIP options | ||
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html) | ||
// | ||
// This example uses a common include to avoid repetition | ||
#include "lwipopts_examples_common.h" | ||
|
||
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL+1) | ||
|
||
#ifdef MQTT_CERT_INC | ||
#define LWIP_ALTCP 1 | ||
#define LWIP_ALTCP_TLS 1 | ||
#define LWIP_ALTCP_TLS_MBEDTLS 1 | ||
#ifndef NDEBUG | ||
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_ON | ||
#endif | ||
/* TCP WND must be at least 16 kb to match TLS record size | ||
or you will get a warning "altcp_tls: TCP_WND is smaller than the RX decrypion buffer, connection RX might stall!" */ | ||
#undef TCP_WND | ||
#define TCP_WND 16384 | ||
#endif // MQTT_CERT_INC | ||
|
||
// This defaults to 4 | ||
#define MQTT_REQ_MAX_IN_FLIGHT 5 | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#ifndef MBEDTLS_CONFIG_TLS_CLIENT_H | ||
#define MBEDTLS_CONFIG_TLS_CLIENT_H | ||
|
||
#include "mbedtls_config_examples_common.h" | ||
|
||
#endif |
Oops, something went wrong.