MQTT协议在STM32上的移植

MQTT协议在STM32上的移植

The Eclipse Paho project provides open-source client implementations of MQTT and MQTT-SN messaging protocols aimed at new, existing, and emerging applications for the Internet of Things (IoT).

开发平台

软件环境

  • Keil uVision 5.12
  • STM32F10x_StdPeriph_Lib_V3.5.0 标准库

硬件环境

  • stm32f103系列
  • SIM800C无线通讯GSM模块

参考文档

下载MQTT 嵌入式C/C++库

本篇是MQTT在STM32设备上的移植,因此使用paho的嵌入式C,源码地址https://github.com/eclipse/paho.mqtt.embedded-c.

移植

首先,需要将../paho.mqtt.embedded-c/MQTTPacket/中的所有文件添加到keil工程文件,然后参考../paho.mqtt.embedded-c/MQTTPacket/samples/中的例程编写。

移植的前提是保证已经建立TCP连接,因为MQTT协议实在TCP基础上的数据传输协议。本实验使用sim800c无线通讯模块先与MQTT服务器建立TCP连接(使用透传模式),再通过串口与stm32建立通讯联系。

接口函数

移植主要参考修改库中的../paho.mqtt.embedded-c/MQTTPacket/samples/transport.c例程文件
,且主要是transport_sendPacketBuffer()和transport_getdata()函数,分别用来作为硬件实现发送和接收数据包的接口函数,因此需要针对硬件平台做相应修改。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

int32_t transport_sendPacketBuffer(uint8_t* buf, uint32_t buflen)

{

    int rc = 0;

   

    SendBuffer(UART4, buf, buflen);

   

    return rc;

}

int32_t transport_getdata(uint8_t* buf, int32_t count)

{

    int32_t n, rc = 0;

   

    memcpy(buf, (void*)&RxBuffer4[readBufLen], count);

    readBufLen += count;

   

    return count;

}

连接

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

uint8_t mqtt_connect(void)

{

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;

    int rc = 0;

    uint8_t buf[200];

    int buflen = sizeof(buf);

    int mysock = 0;

    MQTTString topicString = MQTTString_initializer;

    int len = 0;

    data.clientID.cstring = "yao";

    data.keepAliveInterval = 20;      //seconds

    data.cleansession = 1;

    data.username.cstring = "nncy";

    data.password.cstring = "nncy";

    data.MQTTVersion = 4;

    len = MQTTSerialize_connect((unsigned char *)buf, buflen, &data);

//    len += MQTTSerialize_disconnect((unsigned char *)(buf + len), buflen - len);

    rc = transport_sendPacketBuffer(buf, len);

    printf("len:%d|rc:%d\r\n", len, rc);

   

    reset_receive_buf();

   

    /* wait for connack */

    if (MQTTPacket_read(buf, buflen, transport_getdata) == CONNACK)

    {

        unsigned char sessionPresent, connack_rc;

        if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) != 1 || connack_rc != 0)

        {

            printf("Unable to connect, return code %d\n", connack_rc);

            return 0;

        }

        else

        {

            printf("MQTT CONNECT!\n");

        }

    }

    else

        printf("no connack\n");

        return 0;

}

订阅和发布函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

void mqtt_publish(char *pPubTopic, char *pMessage)

{

    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;

    int rc = 0;

    uint8_t buf[200];

    int buflen = sizeof(buf);

    int mysock = 0;

    MQTTString topicString = MQTTString_initializer;

    char* payload = pMessage;

    int payloadlen = strlen(payload);

    int len = 0;

    topicString.cstring = pPubTopic;

    len += MQTTSerialize_publish((unsigned char *)(buf + len), buflen - len, 0, 0, 0, 0, topicString, (unsigned char *)payload, payloadlen);

//    len += MQTTSerialize_disconnect((unsigned char *)(buf + len), buflen - len);

    rc = transport_sendPacketBuffer(buf, len)

}

uint8_t mqtt_subscribe(char *pSubTopic)

{

    uint8_t buf[200] = {0};

    uint32_t buflen = sizeof(buf);

    int32_t msgid = 1;

    int32_t req_qos = 0;

    uint32_t rc, len = 0;

    MQTTString topicString = MQTTString_initializer;

    topicString.cstring = pSubTopic;

   

    len = MQTTSerialize_subscribe(buf, buflen, 0, msgid, 1, &topicString, &req_qos);

    rc = transport_sendPacketBuffer(buf, len);

    reset_receive_buf();

    if (MQTTPacket_read(buf, buflen, transport_getdata) == SUBACK) /* wait for suback */

    {

        unsigned short submsgid;

        int subcount;

        int granted_qos;

        rc = MQTTDeserialize_suback(&submsgid, 1, &subcount, &granted_qos, buf, buflen);

        if (granted_qos != 0)

        {

            printf("granted qos != 0, %d\n", granted_qos);

            return 0;

        }

        else

        {

            printf("granted qos = 0\n");

            return 1;

        }

    }

    else

        printf("no suback received!\r\n");

        return 0;

}

接收数据包解析函数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

bool MQTT_Received_Data_Parser(char *Topic, char *message)

{

    uint8_t len = 0;

    uint8_t buf[256];

   

    len = uart4RxBufLen;

    printf("Received data lenth:%d\r\n", len);

   

    if (strstr(RxBuffer4, "CLOSED")){

        GPRS_CIP_MODE = 0;

        return false;

    } else {

        memcpy(buf, (void*)&RxBuffer4, len);

   

        printf("buf:%s\r\n", buf);

        printf("topicLength:%d\r\n", buf[3]);

        printf("Topic: %s\r\n", buf+4);

        printf("dataLength:%d\r\n", buf[1]-buf[3]-2);

        printf("Message: %s\r\n", buf+4+buf[3]);

       

       

        if (0xD0 == *buf) {

            printf("MQTT Heart Beat \r\n");

        } else {

            strncpy(Topic,(void*)(buf+4),buf[3]);

            printf("Topic: %s\r\n", Topic);

            strncpy(message,(void*)(buf+4+buf[3]),buf[1]-buf[3]-2);

            printf("Message: %s\r\n", message);

           

            memset(buf,0,sizeof(buf));

        }

    }

    return true;

}


blog/mqtt/mqtt.jpg:

blog/mqtt/mqtt1.jpg:

blog/mqtt/mqtt2.jpg:

blog/mqtt/mqtt3.jpg:

blog/mqtt/mqtt4.jpg:

 

发布了13 篇原创文章 · 获赞 1 · 访问量 855

猜你喜欢

转载自blog.csdn.net/qq_36191395/article/details/103736376