Skip to content

Commit cb4ee9c

Browse files
committed
update code
1 parent ebe6eb8 commit cb4ee9c

38 files changed

+6357
-51
lines changed

.gitignore

Lines changed: 4 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,6 @@
11
# Prerequisites
2-
*.d
2+
# SConscript
33

4-
# Object files
5-
*.o
6-
*.ko
7-
*.obj
8-
*.elf
9-
10-
# Linker output
11-
*.ilk
12-
*.map
13-
*.exp
14-
15-
# Precompiled Headers
16-
*.gch
17-
*.pch
18-
19-
# Libraries
20-
*.lib
21-
*.a
22-
*.la
23-
*.lo
24-
25-
# Shared objects (inc. Windows DLLs)
26-
*.dll
27-
*.so
28-
*.so.*
29-
*.dylib
30-
31-
# Executables
32-
*.exe
33-
*.out
34-
*.app
35-
*.i*86
36-
*.x86_64
37-
*.hex
38-
39-
# Debug files
40-
*.dSYM/
41-
*.su
42-
*.idb
43-
*.pdb
44-
45-
# Kernel Module Compile Results
46-
*.mod*
47-
*.cmd
48-
.tmp_versions/
49-
modules.order
50-
Module.symvers
51-
Mkfile.old
52-
dkms.conf
4+
# 平台移植层
5+
platform/linux/*
6+
platform/FreeRTOS/*

README.md

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,93 @@
11
# RyanMqtt
2-
RyanMqtt实现了MQTT3.1.1协议的客户端。此库针对资源受限的嵌入式设备进行了优化。
2+
3+
### 1、介绍
4+
5+
RyanMqtt 实现了 MQTT3.1.1 协议的客户端。此库针对资源受限的嵌入式设备进行了优化。
6+
7+
初衷:在使用[RT-Thread](https://github.com/RT-Thread/rt-thread)时,没有非常合适的 mqtt 客户端。项目中 mqtt 又是非常核心的功能。随即参考 MQTT3.1.1 标准和项目需求设计的 mqtt 客户端,它拥有以下特点。
8+
9+
- 严格遵循 MQTT3.1.1 协议标准
10+
- 应该是非常稳定的 QOS2 / QOS1 消息实现。用户可控的消息丢弃,避免 QOS2 / QOS1 消息无限重发消耗的内存空间
11+
- 丰富的、可配置的事件回调函数和多功能参数配置,满足实际项目的绝大部分需求
12+
- 支持多客户端
13+
- 完整的 MQTT3.1.1 通配符支持
14+
- 可选择的内部心跳保活、掉线重连、遗嘱消息等
15+
- 跨平台,只需实现少量的平台接口即可
16+
- 更高的并发能力,无等待的连续 200 条 QOS2 消息稳定发送和接收(也取决于硬件收发能力)
17+
- 没有内置 TLS 支持,用户可以在接口层实现 TLS(作者对 TLS 并不熟悉、项目中也暂未使用到)
18+
- 不支持裸机平台,裸机想要稳定的 MQTT3.1.1 实现可以参考[coreMQTT](https://github.com/FreeRTOS/coreMQTT)
19+
20+
### 2、设计
21+
22+
RyanMqtt 设计时参考了[mqttclient](https://github.com/jiejieTop/mqttclient)[esp-mqtt](https://github.com/espressif/esp-mqtt)[coreMQTT](https://github.com/FreeRTOS/coreMQTT)
23+
24+
文案待补充
25+
26+
### 3、平台接口
27+
28+
*RyanMqtt库希望应用程序为以下接口提供实现:*
29+
30+
#### system接口
31+
32+
*RyanMqtt需要RTOS支持,必须实现如下接口才可以保证mqtt客户端的正常运行*
33+
34+
| 函数名称 | 函数简介 |
35+
| --------------------- | ------------------- |
36+
| platformMemoryMalloc | 申请内存 |
37+
| platformMemoryFree | 释放已申请内存 |
38+
| platformDelay | 毫秒延时 |
39+
| platformThreadInit | 初始化线程 |
40+
| platformThreadStart | 开启线程 |
41+
| platformThreadStop | 挂起线程 |
42+
| platformThreadDestroy | 销毁线程 |
43+
| platformMutexInit | 初始化互斥锁 |
44+
| platformMutexLock | 获取互斥锁 |
45+
| platformMutexUnLock | 释放互斥锁 |
46+
| platformMutexDestroy | 销毁互斥锁 |
47+
| platformCriticalEnter | 进入临界区 / 关中断 |
48+
| platformCriticalExit | 退出临界区 / 开中断 |
49+
50+
#### network接口
51+
52+
*RyanMqtt依赖于底层传输接口 API,必须实现该接口 API 才能在网络上发送和接收数据包*
53+
54+
*MQTT 协议要求基础传输层能够提供有序的、可靠的、双向传输(从客户端到服务端 和从服务端到客户端)的字节流*
55+
56+
| 函数名称 | 函数简介 |
57+
| ------------------------ | ------------------ |
58+
| platformNetworkConnect | 连接mqtt服务器 |
59+
| platformNetworkRecvAsync | 非阻塞接收数据 |
60+
| platformNetworkSendAsync | 非阻塞发送数据 |
61+
| platformNetworkClose | 断开mqtt服务器连接 |
62+
63+
#### time接口
64+
65+
*RyanMqtt依靠函数生成毫秒时间戳,用于计算持续时间和超时,内部已经做了数值溢出处理*
66+
67+
| 函数名称 | 函数简介 |
68+
| ---------------- | ------------------ |
69+
| platformUptimeMs | 自启动以来ms时间戳 |
70+
71+
72+
73+
### 4、示例
74+
75+
RT-Thread 平台
76+
77+
- 接口示例请参考platform/rtthread文件夹
78+
- RyanMqtt使用示例请参考 example 文件夹
79+
- 需要使能 SAL 或者 LWIP,示例使用 socket 实现数据收发。
80+
- 需要MSH组件,示例默认挂载到MSH组件
81+
82+
其余平台暂无示例
83+
84+
### 5、依赖
85+
86+
RT-Thread 内置 ulog 组件,方便的使用 ulog api 来管理 RyanMqtt 打印信息
87+
88+
如果没有使能 ulog 或者非 RT-Thread 平台,用户需要手动修改 RyanMqttLog.h 文件调整打印等级。
89+
90+
### 6、声明
91+
92+
- 请勿将此库QOS消息等级用于支付等可能造成重大损失的场景,如需使用请自行深度评估后使用,作者不对使用此库造成的任何经济损失负责。(尽管此库QOS2消息等级经过很多测试,但是异步组件由于诸多因素例如波动非常大的网络甚至无法建立稳定的tcp连接、mqtt服务端的策略配置等,无法做到绝对的实时性,需要用户手动做到数据的最终一致性。)
93+

SConscript

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from building import *
2+
Import('RTT_ROOT')
3+
4+
# get current directory
5+
cwd = GetCurrentDir()
6+
7+
# The set of source files associated with this SConscript file.
8+
src = Glob('common/*.c')
9+
src += Glob('pahoMqtt/*.c')
10+
src += Glob('mqttclient/*.c')
11+
src += Glob('platform/rtthread/*.c')
12+
13+
path = [cwd + '/common']
14+
path += [cwd + '/pahoMqtt']
15+
path += [cwd + '/mqttclient']
16+
path += [cwd + '/platform/rtthread']
17+
18+
if GetDepend(['PKG_USING_RYANMQTT_EXAMPLE']):
19+
src += Glob('example/*.c')
20+
path += [cwd + '/example']
21+
22+
group = DefineGroup('RyanMqtt', src, depend=[
23+
'PKG_USING_RYANMQTT'], CPPPATH=path)
24+
25+
Return('group')

common/RyanList.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
2+
3+
#include "RyanList.h"
4+
5+
/**
6+
* @brief 在prev和next之前插入节点
7+
*
8+
* @param node
9+
* @param prev
10+
* @param next
11+
*/
12+
static void _RyanListAdd(RyanList_t *node, RyanList_t *prev, RyanList_t *next)
13+
{
14+
next->prev = node;
15+
node->next = next;
16+
node->prev = prev;
17+
prev->next = node;
18+
}
19+
20+
/**
21+
* @brief 删除prev和next之间的节点
22+
*
23+
* @param prev
24+
* @param next
25+
*/
26+
static void _RyanListDel(RyanList_t *prev, RyanList_t *next)
27+
{
28+
prev->next = next;
29+
next->prev = prev;
30+
}
31+
32+
/**
33+
* @brief 删除自己
34+
*
35+
* @param entry
36+
*/
37+
static void _RyanListDel_entry(RyanList_t *entry)
38+
{
39+
_RyanListDel(entry->prev, entry->next);
40+
}
41+
42+
/**
43+
* @brief 初始链表
44+
*
45+
* @param list
46+
*/
47+
void RyanMqttListInit(RyanList_t *list)
48+
{
49+
list->next = list;
50+
list->prev = list;
51+
}
52+
53+
/**
54+
* @brief 链表头插
55+
*
56+
* @param node
57+
* @param list
58+
*/
59+
void RyanListAdd(RyanList_t *node, RyanList_t *list)
60+
{
61+
_RyanListAdd(node, list, list->next);
62+
}
63+
64+
/**
65+
* @brief 链表尾插
66+
*
67+
* @param node
68+
* @param list
69+
*/
70+
void RyanListAddTail(RyanList_t *node, RyanList_t *list)
71+
{
72+
_RyanListAdd(node, list->prev, list);
73+
}
74+
75+
/**
76+
* @brief 删除自己
77+
*
78+
* @param entry
79+
*/
80+
void RyanListDel(RyanList_t *entry)
81+
{
82+
_RyanListDel_entry(entry);
83+
}
84+
85+
/**
86+
* @brief 删除自己
87+
*
88+
* @param entry
89+
*/
90+
void RyanListDelInit(RyanList_t *entry)
91+
{
92+
_RyanListDel_entry(entry);
93+
RyanMqttListInit(entry);
94+
}
95+
96+
/**
97+
* @brief 将节点移到链表头部
98+
*
99+
* @param node
100+
* @param list
101+
*/
102+
void RyanListMove(RyanList_t *node, RyanList_t *list)
103+
{
104+
_RyanListDel_entry(node);
105+
RyanListAdd(node, list);
106+
}
107+
108+
/**
109+
* @brief 将节点移到链表尾部
110+
*
111+
* @param node
112+
* @param list
113+
*/
114+
void RyanListMoveTail(RyanList_t *node, RyanList_t *list)
115+
{
116+
_RyanListDel_entry(node);
117+
RyanListAddTail(node, list);
118+
}
119+
120+
/**
121+
* @brief 链表是否为空
122+
*
123+
* @param list
124+
* @return int
125+
*/
126+
int RyanListIsEmpty(RyanList_t *list)
127+
{
128+
return list->next == list;
129+
}

common/RyanList.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
2+
#ifndef __RyanList__
3+
#define __RyanList__
4+
5+
#ifdef __cplusplus
6+
extern "C"
7+
{
8+
#endif
9+
10+
typedef struct RyanListNode
11+
{
12+
struct RyanListNode *next;
13+
struct RyanListNode *prev;
14+
} RyanList_t;
15+
16+
#define RyanOffsetOf(type, member) ((size_t) & (((type *)0)->member))
17+
18+
#define RyanContainerOf(ptr, type, member) \
19+
((type *)((unsigned char *)(ptr)-RyanOffsetOf(type, member)))
20+
21+
// 通过链表获取节点首地址
22+
#define RyanListEntry(list, type, member) \
23+
RyanContainerOf(list, type, member)
24+
25+
// 从链表指针ptr的下一指针中获得包含该链表的结构体指针
26+
#define RyanListFirstEntry(list, type, member) \
27+
RyanListEntry((list)->next, type, member)
28+
29+
// 从链表指针ptr的上一指针中获得包含该链表的结构体指针
30+
#define RyanListPrevEntry(list, type, member) \
31+
RyanListEntry((list)->prev, type, member)
32+
33+
// 遍历链表正序
34+
#define RyanListForEach(curr, list) \
35+
for ((curr) = (list)->next; (curr) != (list); (curr) = (curr)->next)
36+
37+
// 遍历链表反序
38+
#define RyanListForEachPrev(curr, list) \
39+
for ((curr) = (list)->prev; (curr) != (list); (curr) = (curr)->prev)
40+
41+
// 安全遍历链表正序
42+
#define RyanListForEachSafe(curr, next, list) \
43+
for ((curr) = (list)->next, (next) = (curr)->next; \
44+
(curr) != (list); \
45+
(curr) = (next), (next) = (curr)->next)
46+
47+
// 安全遍历链表反序
48+
#define RyanListForEachPrevSafe(curr, next, list) \
49+
for ((curr) = (list)->prev, (next) = (curr)->prev; \
50+
(curr) != (list); \
51+
(curr) = (next), (next) = (curr)->prev)
52+
53+
void RyanMqttListInit(RyanList_t *list);
54+
55+
void RyanListAdd(RyanList_t *node, RyanList_t *list);
56+
void RyanListAddTail(RyanList_t *node, RyanList_t *list);
57+
58+
void RyanListDel(RyanList_t *entry);
59+
void RyanListDelInit(RyanList_t *entry);
60+
61+
void RyanListMove(RyanList_t *node, RyanList_t *list);
62+
void RyanListMoveTail(RyanList_t *node, RyanList_t *list);
63+
int RyanListIsEmpty(RyanList_t *list);
64+
65+
#ifdef __cplusplus
66+
}
67+
#endif
68+
69+
#endif

0 commit comments

Comments
 (0)