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。

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