简介:
实现在开发板上用mosquitto通过三元组连接阿里云并进行消息发送与接收。
主要分为3部分,第一部分在Ubuntu上搭建mosquitto进行初步测试,第二部分下载并编译依赖库,第三部分移植到开发板并编写代码。
环境:
ubuntu 16.04.5 64位
正点原子IMX6ULL开发板
参考:
迅为电子实战项目,正点原子相关资料,以及广大网友博客
这里写目录标题
第一部分 在x86上搭建mosquitto并进行测试
一、在x86上搭建mosquitto并进行测试
1、搭载环境
ubuntu 16.04.5 64位
2、下载mosquitto
//1、安装mosquitto
sudo apt-get install mosquitto
//2、安装mosquitto客户端
sudo apt-get install mosquitto-clients
3、在Ubuntu上使用
//1、开启mosquitto服务,把Ubuntu主机当成服务器
service mosquitto start
//2、在服务器上订阅主题为“mqtt”的消息(192.168.9.209为主机IP)
mosquitto_sub -h 192.168.9.209 -t "mqtt" -v
//3、再打开一个终端,并在此终端上向服务器发送信息“hello”
mosquitto_pub -h 192.168.9.209 -t "mqtt" -m "hello"
第二部分 下载并编译mosquitto依赖库
二、下载并安装libuuid库
1、版本libuuid-1.0.3,下载地址: https://sourceforge.net/projects/libuuid/files/.
2、解压libuuid-1.0.3.tar.gz到自己文件夹下
3、创建文件夹用来存放编译安装后的库(之后两个库都放此文件夹下)
sudo mkdir /opt/mosquitto-arm
4、授予文件夹权限
sudo chmod 777 /opt/mosquitto-arm/
5、配置configure
./configure --prefix=/opt/mosquitto-arm/libuuid-1.0.3 CC=arm-linux-gnueabihf-gcc --host=arm-linux
6、编译并安装
make
make install
7、检查/opt/mosquitto-arm是否有libuuid-1.0.3文件夹,若存在则代表安装成功
三、下载并安装OpenSSL库
1、版本openssl-1.0.2g,下载地址: https://oomake.com/download/openssl.
2、解压openssl-1.0.2g.tar.gz到自己文件夹下
3、配置configure
setarch i386 ./config no-asm shared --prefix=/opt/mosquitto-arm/openssl
4、修改Makefile
CC= arm-linux-gnueabihf-gcc
AR= arm-linux-gnueabihf-ar $(ARFLAGS) r
RANLIB= arm-linux-gnueabihf-ranlib
NM= arm-linux-gnueabihf-nm
5、编译并安装
make
make install
6、检查/opt/mosquitto-arm是否有openssl-1.0.2g文件夹,若存在则代表安装成功
四、下载并安装mosquitto库
1、版本mosquitto-1.5.1,下载地址: https://mosquitto.org/files/source/.
2、解压mosquitto-1.5.1.tar.gz到自己文件夹下
3、编译并安装
//1、进行交叉编译
make WITH_SRV=no CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ CFLAGS=" -I /opt/mosquitto-arm/openssl/include -I /opt/mosquitto-arm/openssl/lib -I /opt/mosquitto-arm/openssl/include/openssl -I /opt/mosquitto-arm/libuuid-1.0.3/include -I /opt/mosquitto-arm/libuuid-1.0.3/lib" LDFLAGS=" -L /opt/mosquitto-arm/openssl/lib -L /opt/mosquitto-arm/libuuid-1.0.3/lib -lssl -lcrypto -luuid"
//2、安装到指定文件夹
make DESTDIR=/opt/mosquitto-arm/mosquitto-1.5.1 install
4、检查/opt/mosquitto-arm是否有mosquitto-1.5.1文件夹,若存在则代表安装成功
第三部分 移植到开发板并编写程序实现连接阿里云
五、移植编译后的文件到开发板
1、将/opt/mosquitto-arm下3个文件夹进行打包
tar -czf mqtt.tar.gz ./*
2、将打包后的文件复制到开发板根目录下并解压到根目录
cp mqtt.tar.gz /home/cxd/linux/nfs/rootfs/
tar -vxf mqtt.tar.gz
3、将libuuid_1.0.3/lib openssl_1.0.2g/lib mosquitto_1.5.1/usr/local/lib 文件夹下所有文件复制到根目录/lib文件夹下
cd libuuid_1.0.3
cp -rf ./lib/* /lib
cd openssl_1.0.2g
cp -rf ./lib/* /lib
cd /usr/local/
cp -rf ./lib/* /lib
4、将mosquitto_1.5.1/usr/local/bin mosquitto_1.5.1/usr/local/sbin 文件夹下所有文件复制到根目录/bin下
cd mosquitto_1.5.1/usr/local
cp -rf ./bin/* /bin
cp -rf ./sbin/* /bin
5、将mosquitto_1.5.1/etc/mosquitto/文件夹下mosquitto.conf.example文件复制到根目录/etc下并更改名字为mosquitto.conf
cp mosquitto.conf.example /etc/mosquitto.conf
6、使用vi 修改mosquitto.conf文件,在第40行下添加"user root"
7、启动mosquitto服务,通过PS命令查看有没有成功
mosquitto -d -c /etc/mosquitto.conf
ps -ef|grep mosqu
六、编写测试.c文件并测试
1、在Ubuntu下新建文件夹,并在里面新建mosquitto_example.c文件以及Makefile
mkdir test
touch mosquitto_example.c
touch Makefile
2、程序内容如下
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "mosquitto.h"
typedef struct
{
char host[128];
int port;
char topic[64];
char client_id[64];
char user[64];
char password[128];
int keepalive;
char pub_message;
}mosquitto_t;
mosquitto_t mosquitto_obj;
void mqtt_log_callback (struct mosquitto *mqtt, void *ubuf, int level,const char *str)
{
printf("[log] level=%d str=%s ubuf=%s\n",level, str,(char *)ubuf);
}
void mqtt_connect_callback (struct mosquitto *mqtt, void *ubuf, int result)
{
int i;
printf("[connect] level=%d \n",result);
if(!result)
{
mosquitto_subscribe(mqtt,NULL,mosquitto_obj.topic,2);
}
else
{
fprintf(stderr,"Connect failed\n");
}
}
void mqtt_message_callback (struct mosquitto *mqtt, void *ubuf, const struct mosquitto_message *message)
{
if(message->payloadlen)
{
printf("%s %d %s\n",message->topic,(char *)message->payloadlen,(char *)message->payload);
}
else
{
printf("%s (null)",message->topic);
}
fflush(stdout);
}
void mqtt_disconnect_callback (struct mosquitto *mosq, void *obj, int result)
{
printf("mqtt disconnect");
}
void mqtt_publish_callback (struct mosquitto *mosq, void *obj, int mid)
{
printf("mqttt publish callback");
}
int main (int argc, char **argv)
{
int ret ;
int session=true;
char buf[1024];
// char name[]="mqtt";
struct mosquitto *mosquitto_sub=NULL;
memset(&mosquitto_obj, 0, sizeof(mosquitto_obj));
mosquitto_lib_init();//初始化mosquitto
strcpy(mosquitto_obj.host,"ProductKey.iot-as-mqtt.cn-shanghai.aliyuncs.com");
strcpy(mosquitto_obj.client_id,"12345|securemode=3,signmethod=hmacsha1|");
strcpy(mosquitto_obj.topic,"topic");
strcpy(mosquitto_obj.user,"DeviceName&ProductKey");
strcpy(mosquitto_obj.password,"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
mosquitto_obj.port=1883;
mosquitto_obj.keepalive=60;
printf("mosquitto_obj->host=%s \n",mosquitto_obj.host);
printf("mosquitto_obj->client_id=%s \n",mosquitto_obj.client_id);
printf("mosquitto_obj->topic=%s \n",mosquitto_obj.topic);
printf("mosquitto_obj->user=%s \n",mosquitto_obj.user);
printf("mosquitto_obj->password=%s \n",mosquitto_obj.password);
printf("mosquitto_obj->port=%d \n",mosquitto_obj.port);
printf("mosquitto_obj->keepalive=%d \n",mosquitto_obj.keepalive);
mosquitto_sub =mosquitto_new(mosquitto_obj.client_id,session,(void *)&mosquitto_obj); //新建一个客户端
if(!mosquitto_sub)
{
printf("mqtt new client error ");
return -1;
}
mosquitto_connect_callback_set(mosquitto_sub,mqtt_connect_callback);
mosquitto_message_callback_set(mosquitto_sub,mqtt_message_callback);
mosquitto_disconnect_callback_set(mosquitto_sub,mqtt_disconnect_callback);
mosquitto_publish_callback_set(mosquitto_sub,mqtt_publish_callback);
if( mosquitto_username_pw_set(mosquitto_sub, mosquitto_obj.user, mosquitto_obj.password))
{
printf("mosquitto username and password failure:%s %s\n", mosquitto_obj.user,mosquitto_obj.password);
// goto cleanup;
}
ret = mosquitto_connect(mosquitto_sub,mosquitto_obj.host,mosquitto_obj.port,mosquitto_obj.keepalive);//连接到服务器
if(ret)
{
printf("connect error \n");
return ret;
}
printf("connect success\n");
printf("start recv...\n");
// mosquitto_loop_forever(mosquitto_sub,-1,1);
ret=mosquitto_loop_start(mosquitto_sub);
if(ret != MOSQ_ERR_SUCCESS)
{
mosquitto_destroy(mosquitto_sub);
printf("loop error \n");
return ret;
}
while(1)
{
memset(buf,0,sizeof(buf));
fgets(buf,sizeof(buf),stdin);
if(strcmp(buf,"\n")== 0)
{
printf("bye...\n");
break;
}
mosquitto_publish(mosquitto_sub,NULL,"topic",strlen(buf)+1,buf,0,0); //发消息
}
// while(1)
// {
// memset(buf,0,sizeof(buf));
// fgets(buf,sizeof(buf),stdin);
// if(strcmp(buf,"\n")== 0)
// {
// printf("bye...\n");
// break;
// }
// mosquitto_publish(mosquitto_sub,NULL,mosquitto_obj.topic,strlen(buf)+1,buf,0,0); //发消息
// }
mosquitto_destroy(mosquitto_sub); //释放mosquitto实例关联的内存
mosquitto_lib_cleanup(); //释放库相关的资源
return 0;
}
3、Makefile文件内容如下,此Makefile可以编译此文件夹下多个.c文件并生成对应目标
CROSS_COMPILE ?= arm-linux-gnueabihf-
CFLAG += -o
#将本目录下所有.c结尾文件加入到SOURCE中
SOURCE = $(wildcard *.c)
#去掉所有.c文件中的后缀.c
TARGETS = $(patsubst %.c, %, $(SOURCE))
CC := $(CROSS_COMPILE)gcc
#LD := $(CROSS_COMPILE)ld
#OBJCOPY := $(CROSS_COMPILE)objcopy
#OBJDUMP := $(CROSS_COMPILE)objdump
#指定交叉编译程序中所用到的头文件路径
INC_DIR += /opt/mosquitto-arm/mosquitto-1.5.1/usr/local/include/
#指定交叉编译程序中所用到的库文件路径
LD_DIR += /opt/mosquitto-arm/mosquitto-1.5.1/usr/local/lib/ \
/opt/mosquitto-arm/libuuid-1.0.3/lib/ \
/opt/mosquitto-arm/openssl/lib/
#指定交叉编译程序中所用到的库路径
USR_LIB := -lmosquitto -lssl -lcrypto -luuid
#在头文件目录信息前加 -I
INCLUDE := $(patsubst %, -I %, $(INC_DIR))
#在库文件目录信息前加 -L
LDCLUDE := $(patsubst %, -L %, $(LD_DIR))
#VPATH := $(INC_DIR) $(LD_DIR)
.PHONY: clean all
#mq_pub : mq_pub.c
# $(CC) mq_pub.c -o mq_pub $(INCLUDE) $(LDCLUDE) $(USR_LIB)
all:$(TARGETS)
#目标为去掉.c后对象,依赖为.c文件
#使用自动化变量编译文件夹下所有.c,并输出对应目标
$(TARGETS):%:%.c
$(CC) $< $(CFLAG) $@ $(INCLUDE) $(LDCLUDE) $(USR_LIB)
#清空所有编译好的文件
clean:
-rm -rf $(TARGETS)
# rm mq_pub
4、在此文件夹下使用make命令
make
5、将生成的可执行文件拷贝到开发板根目录下并运行
cp mosquitto_example /home/cxd/linux/nfs/rootfs/
./mosquitto_example
6、在开发板命令行输入aaa并回车,在阿里云可以收到相应消息,再次按回车退出发送。在阿里云对应topic下发送消息,开发板命令行显示对应消息。