Introduction
Here we will do two things: 1) Compile the C version libraries of two open-source projects, paho.mqtt
and mosquitto
(the mosquitto library will not be used) 2) Compile the library that depends on paho.mqtt
and write examples + mosquitto server.
Host Platform: Ubuntu 16.04 ARM Platform: s5p6818 SSL: openssl-1.0.2t MQTT Client: paho.mqtt.c
Now we will proceed with the porting of the MQTT client.
The MQTT server (Broker) is included in many cloud servers, and there is no need for porting unless there are special requirements; furthermore, even if the Broker is ported, it is relatively simple.
Host Preparation
You can use the following script.
The previous article “Setting Up MQTT Communication Environment and Packet Capture Testing” did not introduce compiling and running the mosquitto server under Linux, so the script below also includes this. For details, refer to:
make_mosquitto ()
bash
##
# Copyright By Schips, All Rights Reserved
# https://gitee.com/schips/
# File Name: make.sh
# Created : Sat 30 Nov 2019 01:56:37 PM CST
##
#!/bin/sh
BUILD_HOST=arm-linux-
ARM_GCC=${BUILD_HOST}gcc
ARM_CPP=${BUILD_HOST}g++
BASE=`pwd`
OUTPUT_PATH=${BASE}/install
OPENSSL=openssl-1.0.2t
make_dirs () {
# To facilitate management, create related directories
cd ${BASE} && mkdir compressed install source -p
}
tget () { #try wget
filename=`basename $1`
echo "Downloading [${filename}]..."
if [ ! -f ${filename} ];then
wget $1
fi
echo "[OK] Downloaded [${filename}] "
}
tgit () { #try git and tar
filename=`basename $1 | sed 's/.git//g'`
echo "Clone [${filename}]..."
if [ ! -f ${filename}.tgz ];then
git clone $1
rm ${filename}/.git* -rf
echo "Making a tar file."
tar -zcf ${filename}.tgz ${filename}
rm ${filename} -rf
fi
echo "[OK] Cloned [${filename}] "
}
download_package () {
cd ${BASE}/compressed
# Download packages
tget https://www.openssl.org/source/${OPENSSL}.tar.gz
tgit https://github.com/eclipse/paho.mqtt.c.git
tgit https://github.com/eclipse/mosquitto.git
}
tar_package () {
cd ${BASE}/compressed
ls * > /tmp/list.txt
for TAR in `cat /tmp/list.txt`
do
tar -xf $TAR -C ../source
done
rm -rf /tmp/list.txt
}
pre_make_ssl () {
cd ${BASE}/source/${OPENSSL}
startLine=`sed -n '/install_html_docs r/' Makefile`
echo $startLine
# To avoid multi-line results
for startline in $startLine
do
lineAfter=99
endLine=`expr $startline + 999`
sed -i $startline','$endLine'd' Makefile
echo "install_html_docs:" >> Makefile
echo " @echo skip by Schips" >> Makefile
echo "install_docs:" >> Makefile
echo " @echo skip by Schips" >> Makefile
echo "# DO NOT DELETE THIS LINE -- make depend depends on it." >> Makefile
break
done
}
make_ssl () {
# Compile and install zlib
cd ${BASE}/source/${OPENSSL}
rm ${OUTPUT_PATH}/${OPENSSL} -rf
echo "SSL ABOUT"
CC=${ARM_GCC} ./Configure no-asm shared --prefix=${OUTPUT_PATH}/${OPENSSL}
sed 's/-m64//g' -i Makefile # Remove -m64 keyword (arm-gcc does not support)
#sudo mv /usr/bin/pod2man /usr/bin/pod2man_bak
#mv doc/apps /tmp/
pre_make_ssl
make && make install
}
make_paho_mqtt_c () {
cd ${BASE}/source/paho.mqtt.c
make CFLAGS+="-I ${OUTPUT_PATH}/${OPENSSL}/include" \
LDFLAGS+="-L${OUTPUT_PATH}/${OPENSSL}/lib" \
CC=${ARM_GCC} \
prefix=${OUTPUT_PATH}/paho.mqtt.c
# BUG: make install does not meet our intention
rm ${OUTPUT_PATH}/paho.mqtt.c -rf
mkdir ${OUTPUT_PATH}/paho.mqtt.c/lib -p
mkdir ${OUTPUT_PATH}/paho.mqtt.c/bin -p
mkdir ${OUTPUT_PATH}/paho.mqtt.c/include -p
cp ${BASE}/source/paho.mqtt.c/build/output/lib* ${OUTPUT_PATH}/paho.mqtt.c/lib -d -v
cp ${BASE}/source/paho.mqtt.c/build/output/samples ${OUTPUT_PATH}/paho.mqtt.c/bin -r -v
cp ${BASE}/source/paho.mqtt.c/build/output/test ${OUTPUT_PATH}/paho.mqtt.c/bin -r -v
cp ${BASE}/source/paho.mqtt.c/src/*.h ${OUTPUT_PATH}/paho.mqtt.c/include -v
}
make_mosquitto () {
cd ${BASE}/source/mosquitto
sed -r -i "/WITH_DOCS:=/ s/.*/WITH_DOCS:=no/" config.mk
sed -r -i "/WITH_SRV:=/ s/.*/WITH_SRV:=no/" config.mk
sed -r -i "/WITH_UUID:=/ s/.*/WITH_UUID:=no/" config.mk
sed -r -i "/WITH_WEBSOCKETS:=/ s/.*/WITH_WEBSOCKETS:=no/" config.mk
sed -r -i "/WITH_STRIP:=/ s/.*/WITH_STRIP:=yes/" config.mk
# Do not add ssl support
sed -r -i "/WITH_TLS:=/ s/.*/WITH_TLS:=no/" config.mk
sed -r -i "/WITH_TLS_PSK:=/ s/.*/WITH_TLS_PSK:=no/" config.mk
# Specify toolchain
sed -i "N;2aCC=${BUILD_HOST}gcc" config.mk
sed -i "N;2aCXX=${BUILD_HOST}g++" config.mk
sed -i "N;2aCPP=${BUILD_HOST}g++" config.mk
sed -i "N;2aCC=${BUILD_HOST}gcc" config.mk
sed -i "N;2aAR=${BUILD_HOST}ar" config.mk
sed -i "N;2aLD=${BUILD_HOST}ld" config.mk
sed -r -i "/STRIP\?=/ s/.*/STRIP\?=${BUILD_HOST}strip/" config.mk
# Set output path
echo "DESTDIR=${OUTPUT_PATH}/mosquitto" >> config.mk
echo "prefix=\" >> config.mk
make && make install
# Add ssl support for the compiled mosquitto
#sed -r -i "/WITH_TLS:=/ s/.*/WITH_TLS:=yes/" config.mk
#sed -r -i "/WITH_TLS_PSK:=/ s/.*/WITH_TLS_PSK:=yes/" config.mk
#make \
# CFLAGS+="-I ${OUTPUT_PATH}/${OPENSSL}/include" \
# LDFLAGS+="-L${OUTPUT_PATH}/${OPENSSL}/lib -lssl -lcrypto"
#make \
# CFLAGS+="-I ${OUTPUT_PATH}/${OPENSSL}/include" \
# LDFLAGS+="-L${OUTPUT_PATH}/${OPENSSL}/lib -lssl -lcrypto" \
# install
}
make_dirs
download_package
tar_package
make_ssl
make_paho_mqtt_c
make_mosquitto
exit $?
Target Board Preparation
Copy the runtime libraries from the install directory to the board and add them to the path.
Testing
Use the following test program, specifying the server according to your needs.
The relevant examples can be found in ${paho_mqtt_c}/src/samples.
cpp
/*
# Copyright By Schips, All Rights Reserved
# https://gitee.com/schips/
#
# File Name: main.cpp
# Created : Sun 09 Feb 2020 10:14:44 AM CST
*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <MQTTClient.h> /* Location of MQTT header file */
#include <sys/time.h>
#include <termios.h>
#define ADDRESS "tcp://localhost:1883" /* Specify the server's IP address here using the local mosquitto for testing */
#define CLIENTID "ExampleClientPub"
#define TOPIC "MQTT Examples"
#define PAYLOAD "Hello World!"
#define QOS 1
#define TIMEOUT 10000L
using namespace std;
int main(int argc, char* argv[]){
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
MQTTClient_message *receivemsg = NULL ;
char* topicName_rev = NULL;
int topicLen_rev;
int rc;
int i;
MQTTClient_create(&client, ADDRESS, CLIENTID,
MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 60;
conn_opts.cleansession = 1;
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(-1);
}
pubmsg.payload = (void *)PAYLOAD;
pubmsg.payloadlen = strlen(PAYLOAD);
pubmsg.qos = QOS;
pubmsg.retained = 0;
MQTTClient_subscribe(client, "test", 1); /* Subscribe to a topic for a client */
usleep(10000);
MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token); /* Send message */
printf("Waiting for up to %d seconds for publication of %s\n"
"on topic %s for client with ClientID: %s\n",
(int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID);
rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
printf("Message with delivery token %d delivered\n", token);
for(;;)
{
if(MQTTClient_isConnected(client) == true) /* Check connection status */
{
printf("alive \n");
}else{
printf(" no alive \n");
break;
}
rc = MQTTClient_receive(client,&topicName_rev, &topicLen_rev, &receivemsg,5000); /* Receive message */
if(rc == MQTTCLIENT_SUCCESS)
{
printf("Message REv %d delivered\n", rc);
printf("topicName: %s topicName_LEN: %d \n", topicName_rev,topicLen_rev);
if(topicName_rev != NULL) /* Filter out heartbeat packets */
{
printf("topicName: ");
for(i=0;i<topicLen_rev;i++)
{
printf(" %c ", topicName_rev[i]);
}
printf("\n");
printf("Data: %s len:%d msgid: %d \n",(char *)receivemsg->payload,receivemsg->payloadlen,receivemsg->msgid);
if(strcmp((char *)receivemsg->payload,"ESC") == 0)
{
printf("ESC \n");
break;
}
}
}
usleep(10000);
usleep(100000);
}
MQTTClient_disconnect(client, 10000);
MQTTClient_destroy(&client);
return rc;
}
Compile Command
arm-linux-g++ -I ./paho.mqtt.c/src -L ./paho.mqtt.c/build/output/ -lpaho-mqtt3c main.cpp -o client