MQTT開源協議棧paho.mqtt.c 移植到安卓平臺及測試過程

Paho代碼下載:

1
2

 

git clone https://github.com/eclipse/paho.mqtt.c.git
cd paho.mqtt.c

 

添加根目錄下的Android.mk文件:

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

 

 

LOCAL_PATH := $(call my-dir)
libpaho-mqtt3_lib_path := src
libpaho-mqtt3_c_includes := $(LOCAL_PATH)/$(libpaho-mqtt3_lib_path) \
    external/hdc/android-ifaddrs \
    external/openssl/include \
    external/zlib

# build sample util
define build_sample_util
__sample_module:= $1
__sample_lib:= $2
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(libpaho-mqtt3_c_includes)
LOCAL_SHARED_LIBRARIES := $$(__sample_lib)
LOCAL_MODULE := $$(__sample_module)
LOCAL_SRC_FILES := $(libpaho-mqtt3_lib_path)/samples/$$(__sample_module).c
include $(BUILD_EXECUTABLE)
endef

libpaho-mqtt3_local_src_c_files_common := \
    $(libpaho-mqtt3_lib_path)/MQTTProtocolClient.c \
    $(libpaho-mqtt3_lib_path)/Tree.c \
    $(libpaho-mqtt3_lib_path)/Heap.c \
    $(libpaho-mqtt3_lib_path)/MQTTPacket.c \
    $(libpaho-mqtt3_lib_path)/Clients.c \
    $(libpaho-mqtt3_lib_path)/Thread.c \
    $(libpaho-mqtt3_lib_path)/utf-8.c \
    $(libpaho-mqtt3_lib_path)/StackTrace.c \
    $(libpaho-mqtt3_lib_path)/MQTTProtocolOut.c \
    $(libpaho-mqtt3_lib_path)/Socket.c \
    $(libpaho-mqtt3_lib_path)/Log.c \
    $(libpaho-mqtt3_lib_path)/Messages.c \
    $(libpaho-mqtt3_lib_path)/LinkedList.c \
    $(libpaho-mqtt3_lib_path)/MQTTPersistence.c \
    $(libpaho-mqtt3_lib_path)/MQTTPacketOut.c \
    $(libpaho-mqtt3_lib_path)/SocketBuffer.c \
    $(libpaho-mqtt3_lib_path)/MQTTPersistenceDefault.c \
    $(libpaho-mqtt3_lib_path)/MQTTProperties.c \
    $(libpaho-mqtt3_lib_path)/WebSocket.c \
    $(libpaho-mqtt3_lib_path)/SHA1.c \
    $(libpaho-mqtt3_lib_path)/Base64.c \
    $(libpaho-mqtt3_lib_path)/samples/pubsub_opts.c \

libpaho-mqtt3_local_src_c_files_c := \
    $(libpaho-mqtt3_lib_path)/MQTTClient.c \

libpaho-mqtt3_local_src_c_files_cs := \
    $(libpaho-mqtt3_lib_path)/MQTTClient.c \
    $(libpaho-mqtt3_lib_path)/SSLSocket.c \

libpaho-mqtt3_local_src_c_files_a := \
    $(libpaho-mqtt3_lib_path)/MQTTAsync.c \

libpaho-mqtt3_local_src_c_files_as := \
    $(libpaho-mqtt3_lib_path)/MQTTAsync.c \
    $(libpaho-mqtt3_lib_path)/SSLSocket.c \

# update the header file which normally generated by cmake
$(shell (cp -f $(LOCAL_PATH)/$(libpaho-mqtt3_lib_path)/VersionInfo.h.in $(LOCAL_PATH)/$(libpaho-mqtt3_lib_path)/VersionInfo.h))
$(shell (sed -i "s/@CLIENT_VERSION@/1.2.0/g" $(LOCAL_PATH)/$(libpaho-mqtt3_lib_path)/VersionInfo.h))
$(shell ( sed -i "s/@BUILD_TIMESTAMP@/$(shell date)/g" $(LOCAL_PATH)/$(libpaho-mqtt3_lib_path)/VersionInfo.h))

# building static libraries

include $(CLEAR_VARS)
LOCAL_MODULE    := libpaho-mqtt3c
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/$(libpaho-mqtt3_lib_path)
LOCAL_C_INCLUDES:= $(libpaho-mqtt3_c_includes)
LOCAL_SRC_FILES := $(libpaho-mqtt3_local_src_c_files_common) $(libpaho-mqtt3_local_src_c_files_c)
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := libpaho-mqtt3cs
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/$(libpaho-mqtt3_lib_path)
LOCAL_C_INCLUDES:= $(libpaho-mqtt3_c_includes)
LOCAL_CFLAGS += -DOPENSSL
LOCAL_SRC_FILES := $(libpaho-mqtt3_local_src_c_files_common) $(libpaho-mqtt3_local_src_c_files_cs)
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := libpaho-mqtt3a
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/${libpaho-mqtt3_lib_path}
LOCAL_C_INCLUDES:= $(libpaho-mqtt3_c_includes)
LOCAL_SRC_FILES := $(libpaho-mqtt3_local_src_c_files_common) $(libpaho-mqtt3_local_src_c_files_a)
include $(BUILD_STATIC_LIBRARY)
  
include $(CLEAR_VARS)
LOCAL_MODULE    := libpaho-mqtt3as
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/${libpaho-mqtt3_lib_path}
LOCAL_CFLAGS += -DOPENSSL
LOCAL_C_INCLUDES:= $(libpaho-mqtt3_c_includes)
LOCAL_SRC_FILES := $(libpaho-mqtt3_local_src_c_files_common) $(libpaho-mqtt3_local_src_c_files_as)
include $(BUILD_STATIC_LIBRARY)

# building shared libraries

include $(CLEAR_VARS)
LOCAL_MODULE    := libpaho-mqtt3c
LOCAL_SHARED_LIBRARIES := libdl
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/$(libpaho-mqtt3_lib_path)
LOCAL_C_INCLUDES:= $(libpaho-mqtt3_c_includes)
LOCAL_SRC_FILES := $(libpaho-mqtt3_local_src_c_files_common) $(libpaho-mqtt3_local_src_c_files_c)
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := libpaho-mqtt3cs
LOCAL_SHARED_LIBRARIES := libcrypto libssl libdl
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/$(libpaho-mqtt3_lib_path)
LOCAL_C_INCLUDES:= $(libpaho-mqtt3_c_includes)
LOCAL_CFLAGS += -DOPENSSL
LOCAL_SRC_FILES := $(libpaho-mqtt3_local_src_c_files_common) $(libpaho-mqtt3_local_src_c_files_cs)
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE    := libpaho-mqtt3a
LOCAL_SHARED_LIBRARIES := libdl
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/${libpaho-mqtt3_lib_path}
LOCAL_C_INCLUDES:= $(libpaho-mqtt3_c_includes)
LOCAL_SRC_FILES := $(libpaho-mqtt3_local_src_c_files_common) $(libpaho-mqtt3_local_src_c_files_a)
include $(BUILD_SHARED_LIBRARY)
 
include $(CLEAR_VARS)
LOCAL_MODULE    := libpaho-mqtt3as
LOCAL_SHARED_LIBRARIES := libcrypto libssl libdl
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/${libpaho-mqtt3_lib_path}
LOCAL_CFLAGS += -DOPENSSL
LOCAL_C_INCLUDES:= $(libpaho-mqtt3_c_includes)
LOCAL_SRC_FILES := $(libpaho-mqtt3_local_src_c_files_common) $(libpaho-mqtt3_local_src_c_files_as)
include $(BUILD_SHARED_LIBRARY)

# building samples

$(eval $(call build_sample_util, MQTTAsync_subscribe, libpaho-mqtt3a ) )
$(eval $(call build_sample_util, MQTTAsync_publish, libpaho-mqtt3a ) )
$(eval $(call build_sample_util, MQTTClient_publish, libpaho-mqtt3c ) )
$(eval $(call build_sample_util, MQTTClient_publish_async, libpaho-mqtt3c ) )
$(eval $(call build_sample_util, MQTTClient_subscribe, libpaho-mqtt3c ) )
$(eval $(call build_sample_util, paho_c_pub, libpaho-mqtt3a ) )
$(eval $(call build_sample_util, paho_c_sub, libpaho-mqtt3a ) )
$(eval $(call build_sample_util, paho_cs_pub, libpaho-mqtt3c ) )
$(eval $(call build_sample_util, paho_cs_sub, libpaho-mqtt3c ) )

 

編譯mqtt模塊:直接執行當前Android.mk文件。

 

相應安卓源碼目錄下會生成所需要的

動態庫(.so)文件:

1

 

Z:\sprdiot\out\target\product\sl8521e_3h10\obj\SHARED_LIBRARIES

 

靜態庫(.a)文件:

1

 

Z:\sprdiot\out\target\product\sl8521e_3h10\obj\STATIC_LIBRARIES

 

樣例程序(安卓下運行的二進制文件)

源碼目錄在paho根目錄下:src/samples/

1

 

Z:\sprdiot\out\target\product\sl8521e_3h10\obj\EXECUTABLES

 

由上圖可知,MQTT測試需要代理服務器-broker作爲中轉TOPIC消息,

我們使用簡單的方法,測試樣例用官方MQTT服務器作爲broker。

tcp://iot.eclipse.org:1883

測試代碼如下:

1.分發者測試代碼

MQTTClient_publish.c:

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

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTClient.h"

#define ADDRESS     "tcp://iot.eclipse.org:1883"
#define CLIENTID    "DCClientPub"
#define TOPIC       "SPRDTOPIC01"
#define PAYLOAD     "xixixixi"
#define QOS         1
#define TIMEOUT     10000L

int main(int argc, char* argv[])
{
    MQTTClient client;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    MQTTClient_message pubmsg = MQTTClient_message_initializer;
    MQTTClient_deliveryToken token;
    int rc;

    MQTTClient_create(&client, ADDRESS, CLIENTID,
        MQTTCLIENT_PERSISTENCE_NONE, NULL);
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;

    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }
    pubmsg.payload = PAYLOAD;
    pubmsg.payloadlen = (int)strlen(PAYLOAD);
    pubmsg.qos = QOS;
    pubmsg.retained = 0;
    MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
    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);
    MQTTClient_disconnect(client, 10000);
    MQTTClient_destroy(&client);
    return rc;
}

 

2.訂閱者測試代碼:

MQTTClient_subscribe.c:

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "MQTTClient.h"

#define ADDRESS     "tcp://iot.eclipse.org:1883"
#define CLIENTID    "DCClientSub"
#define TOPIC       "SPRDTOPIC01"
#define PAYLOAD     "hahahaha"
#define QOS         1
#define TIMEOUT     10000L

volatile MQTTClient_deliveryToken deliveredtoken;

void delivered(void *context, MQTTClient_deliveryToken dt)
{
    printf("Message with token value %d delivery confirmed\n", dt);
    deliveredtoken = dt;
}

int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    int i;
    char* payloadptr;

    printf("Message arrived\n");
    printf("     topic: %s\n", topicName);
    printf("   message: ");

    payloadptr = message->payload;
    for(i=0; i<message->payloadlen; i++)
    {
        putchar(*payloadptr++);
    }
    putchar('\n');
    MQTTClient_freeMessage(&message);
    MQTTClient_free(topicName);
    return 1;
}

void connlost(void *context, char *cause)
{
    printf("\nConnection lost\n");
    printf("     cause: %s\n", cause);
}

int main(int argc, char* argv[])
{
    MQTTClient client;
    MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
    int rc;
    int ch;

    MQTTClient_create(&client, ADDRESS, CLIENTID,
        MQTTCLIENT_PERSISTENCE_NONE, NULL);
    conn_opts.keepAliveInterval = 20;
    conn_opts.cleansession = 1;

    MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);

    if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
    {
        printf("Failed to connect, return code %d\n", rc);
        exit(EXIT_FAILURE);
    }
    printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
           "Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS);
    MQTTClient_subscribe(client, TOPIC, QOS);

    do 
    {
        ch = getchar();
    } while(ch!='Q' && ch != 'q');

    MQTTClient_unsubscribe(client, TOPIC);
    MQTTClient_disconnect(client, 10000);
    MQTTClient_destroy(&client);
    return rc;
}

 

使用adb工具將樣例程序push到手機上運行,我這裏使用的是模擬器作爲手機。

push操作步驟:

執行樣例程序步驟:

可以看出Message arrived,並且成功打印出相應的消息以及topic。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章