Browse Source

Merge pull request #17 from Ryan-CW-Code/next

refactor: RyanMqttBool_e使用原生bool类型、优化结构体内存布局
RyanCW 3 months ago
parent
commit
0bcc2f0990

+ 0 - 2
mqttclient/RyanMqttClient.c

@@ -525,7 +525,6 @@ RyanMqttError_e RyanMqttPublishWithUserData(RyanMqttClient_t *client, char *topi
 	RyanMqttCheck(NULL != topic && topicLen > 0, RyanMqttParamInvalidError, RyanMqttLog_d);
 	RyanMqttCheck(RyanMqttMaxPayloadLen >= payloadLen, RyanMqttParamInvalidError, RyanMqttLog_d);
 	RyanMqttCheck(RyanMqttQos0 <= qos && RyanMqttQos2 >= qos, RyanMqttParamInvalidError, RyanMqttLog_d);
-	RyanMqttCheck(RyanMqttTrue == retain || RyanMqttFalse == retain, RyanMqttParamInvalidError, RyanMqttLog_d);
 	RyanMqttCheck(RyanMqttConnectState == RyanMqttGetClientState(client), RyanMqttNotConnectError, RyanMqttLog_d);
 
 	// 报文支持有效载荷长度为0
@@ -992,7 +991,6 @@ RyanMqttError_e RyanMqttSetLwt(RyanMqttClient_t *client, char *topicName, char *
 	RyanMqttCheck(RyanMqttConnectState != RyanMqttGetClientState(client), RyanMqttFailedError, RyanMqttLog_d);
 	RyanMqttCheck(RyanMqttMaxPayloadLen >= payloadLen, RyanMqttParamInvalidError, RyanMqttLog_d);
 	RyanMqttCheck(RyanMqttQos0 <= qos && RyanMqttQos2 >= qos, RyanMqttParamInvalidError, RyanMqttLog_d);
-	RyanMqttCheck(RyanMqttTrue == retain || RyanMqttFalse == retain, RyanMqttParamInvalidError, RyanMqttLog_d);
 
 	// 报文支持有效载荷长度为0
 	if (NULL == payload && payloadLen > 0)

+ 58 - 48
mqttclient/include/RyanMqttClient.h

@@ -18,54 +18,62 @@ typedef void (*RyanMqttEventHandle)(void *client, RyanMqttEventId_e event, const
 // 定义结构体类型
 typedef struct
 {
-	RyanMqttBool_e retained: 1; // retained 标志位
-	RyanMqttBool_e dup: 1;      // 重发标志
-	uint16_t packetId;          // packetId 系统生成
-	RyanMqttQos_e qos;          // QOS等级
-	uint32_t payloadLen;        // 数据长度
-	uint32_t topicLen;          // topic长度
-	char *topic;                // 主题信息
-	char *payload;              // 数据内容
+	char *topic;         // 主题信息
+	char *payload;       // 数据内容
+	uint32_t payloadLen; // 数据长度
+	uint32_t topicLen;   // topic长度
+	RyanMqttQos_e qos;   // QOS等级
+
+	uint16_t packetId; // packetId 系统生成
+
+	RyanMqttBool_e retained; // retained 标志位
+	RyanMqttBool_e dup;      // 重发标志
 } RyanMqttMsgData_t;
 
 typedef struct
 {
-	uint16_t packetId;   // 关联的packetId
-	uint16_t topicLen;   // 主题长度
-	RyanMqttQos_e qos;   // qos等级
 	RyanMqttList_t list; // 链表节点,用户勿动
 	void *userData;      // 用户自定义数据
-	char *topic;         // 主题,不要求必须是最后一位,但最好保持这样
+	char *topic;         // 主题
+	RyanMqttQos_e qos;   // qos等级
+
+	uint16_t packetId; // 关联的packetId
+	uint16_t topicLen; // 主题长度
 } RyanMqttMsgHandler_t;
 
 typedef struct
 {
-	RyanMqttBool_e packetAllocatedExternally: 1; // packet 是外部分配的
-	uint8_t packetType;                          // 期望接收到的ack报文类型
-	uint16_t repeatCount;                        // 当前ack超时重发次数
-	uint16_t packetId;                           // 报文标识符 系统生成,用户勿动
-	uint32_t packetLen;                          // 报文长度
-	RyanMqttList_t list;                         // 链表节点,用户勿动
-	RyanMqttTimer_t timer;                       // ack超时定时器,用户勿动
-	RyanMqttMsgHandler_t *msgHandler;            // msg信息
-	uint8_t *packet; // 没有收到期望ack,重新发送的原始报文,不要求必须是最后一位,但最好保持这样
+	RyanMqttList_t list;   // 链表节点,用户勿动
+	RyanMqttTimer_t timer; // ack超时定时器,用户勿动
+
+	RyanMqttMsgHandler_t *msgHandler; // msg信息
+	uint8_t *packet;                  // 没有收到期望ack,重新发送的原始报文
+	uint32_t packetLen;               // 报文长度
+
+	uint16_t packetId;    // 报文标识符 系统生成,用户勿动
+	uint16_t repeatCount; // 当前ack超时重发次数
+
+	uint8_t packetType;                       // 期望接收到的ack报文类型
+	RyanMqttBool_e packetAllocatedExternally; // packet 是外部分配的
 } RyanMqttAckHandler_t;
 
 typedef struct
 {
-	RyanMqttBool_e lwtFlag: 1; // 遗嘱标志位
-	RyanMqttBool_e retain: 1;  // 遗嘱保留标志位
-	RyanMqttQos_e qos;         // 遗嘱qos等级
-	uint32_t payloadLen;       // 消息长度
-	char *topic;               // 遗嘱主题
-	char *payload;             // 遗嘱消息
+	char *topic;   // 遗嘱主题
+	char *payload; // 遗嘱消息
+
+	uint32_t payloadLen; // 消息长度
+	RyanMqttQos_e qos;   // 遗嘱qos等级
+
+	RyanMqttBool_e lwtFlag; // 遗嘱标志位
+	RyanMqttBool_e retain;  // 遗嘱保留标志位
 } lwtOptions_t;
 
 typedef struct
 {
 	char *topic;
-	uint16_t topicLen;
 	RyanMqttQos_e qos;
+	uint16_t topicLen;
 } RyanMqttSubscribeData_t;
 
 typedef struct
@@ -76,20 +84,18 @@ typedef struct
 
 typedef struct
 {
-	char *clientId;      // 客户端ID
-	char *userName;      // 用户名
-	char *password;      // 密码
-	char *host;          // mqtt服务器地址
-	uint16_t port;       // mqtt服务器端口
-	uint8_t mqttVersion; // mqtt版本 3.1.1是4, 3.1是3
+	void *userData;                      // 用户自定义数据,用户需要保证指针指向内容的持久性
+	RyanMqttEventHandle mqttEventHandle; // mqtt事件回调函数
 
+	char *clientId;     // 客户端ID
+	char *userName;     // 用户名
+	char *password;     // 密码
+	char *host;         // mqtt服务器地址
 	char *taskName;     // 线程名字
+	uint16_t port;      // mqtt服务器端口
 	uint16_t taskPrio;  // mqtt线程优先级
 	uint16_t taskStack; // 线程栈大小
 
-	RyanMqttBool_e autoReconnectFlag: 1; // 自动重连标志位
-	RyanMqttBool_e cleanSessionFlag: 1;  // 清除会话标志位
-
 	// ack重发超过这个数值后触发事件回调,根据实际硬件选择。典型值为 5
 	uint16_t ackHandlerRepeatCountWarning;
 
@@ -103,18 +109,14 @@ typedef struct
 	uint16_t keepaliveTimeoutS; // mqtt心跳时间间隔。单位S
 	uint16_t reconnectTimeout;  // mqtt重连间隔时间。单位ms
 
-	RyanMqttEventHandle mqttEventHandle; // mqtt事件回调函数
-	void *userData;                      // 用户自定义数据,用户需要保证指针指向内容的持久性
+	uint8_t mqttVersion;              // mqtt版本 3.1.1是4, 3.1是3
+	RyanMqttBool_e autoReconnectFlag; // 自动重连标志位
+	RyanMqttBool_e cleanSessionFlag;  // 清除会话标志位
 } RyanMqttClientConfig_t;
 
 typedef struct
 {
-	RyanMqttBool_e destroyFlag: 1;    // 销毁标志位
-	RyanMqttBool_e pendingAckFlag: 1; // 需要处理ack, 缩短recv超时时间,避免阻塞太久
-	uint16_t ackHandlerCount;         // 等待ack的记录个数
-	uint16_t packetId;                // mqtt报文标识符,控制报文必须包含一个非零的 16 位报文标识符
-	uint32_t eventFlag;               // 事件标志位
-	RyanMqttState_e clientState;      // mqtt客户端的状态
+	RyanMqttClientConfig_t config; // mqtt config
 
 	// 维护消息处理列表,这是mqtt协议必须实现的内容,所有来自服务器的publish报文都会被处理(前提是订阅了对应的消息,或者设置了拦截器)
 	RyanMqttList_t msgHandlerList;
@@ -123,15 +125,23 @@ typedef struct
 	RyanMqttTimer_t ackScanThrottleTimer;   // ack链表检查节流定时器
 	RyanMqttTimer_t keepaliveTimer;         // 保活定时器
 	RyanMqttTimer_t keepaliveThrottleTimer; // 保活检查节流定时器
-	platformNetwork_t network;              // 网络组件
-	RyanMqttClientConfig_t config;          // mqtt config
-	platformThread_t mqttThread;            // mqtt线程
 	platformMutex_t sendLock;               // 写缓冲区锁
 	platformMutex_t msgHandleLock;          // msg链表锁
 	platformMutex_t ackHandleLock;          // ack链表锁
 	platformMutex_t userSessionLock;        // 用户接口的锁
 	platformCritical_t criticalLock;        // 临界区锁
+	platformNetwork_t network;              // 网络组件
+	platformThread_t mqttThread;            // mqtt线程
 	lwtOptions_t *lwtOptions;               // 遗嘱相关配置
+
+	uint32_t eventFlag;          // 事件标志位
+	RyanMqttState_e clientState; // mqtt客户端的状态
+
+	uint16_t ackHandlerCount; // 等待ack的记录个数
+	uint16_t packetId;        // mqtt报文标识符,控制报文必须包含一个非零的 16 位报文标识符
+
+	RyanMqttBool_e destroyFlag;    // 销毁标志位
+	RyanMqttBool_e pendingAckFlag; // 需要处理ack, 缩短recv超时时间,避免阻塞太久
 } RyanMqttClient_t;
 
 /* extern variables-----------------------------------------------------------*/

+ 16 - 17
mqttclient/include/RyanMqttPublic.h

@@ -7,6 +7,7 @@ extern "C" {
 
 #include <stdio.h>
 #include <stdint.h>
+#include <stdbool.h>
 
 // 允许的mqtt packetId最大值,协议标准为1-65534的非零16位数
 #define RyanMqttMaxPacketId   (UINT16_MAX - 1U)
@@ -74,11 +75,9 @@ typedef enum
 	RyanMqttBit0 = 0x00000001,
 } RyanMqttBit_e;
 
-typedef enum
-{
-	RyanMqttFalse = 0,
-	RyanMqttTrue = 1
-} RyanMqttBool_e;
+#define RyanMqttFalse (false)
+#define RyanMqttTrue  (true)
+typedef bool RyanMqttBool_e;
 
 typedef enum
 {
@@ -233,7 +232,7 @@ typedef enum
 	RyanMqttFailedError,                // 失败
 	RyanMqttInvalidPacketError,         // 收到非法的报文
 	RyanMqttSuccessError = 0x0000,      // 成功
-	RyanMqttErrorForceInt32 = INT32_MAX // 强制编译器使用int32_t类型
+					    // RyanMqttErrorForceInt32 = INT32_MAX // 强制编译器使用int32_t类型
 } RyanMqttError_e;
 
 typedef enum
@@ -247,17 +246,17 @@ typedef enum
 	RyanMqttConnectRefusedNotAuthorized = 5,   // 连接已拒绝,未授权
 
 	// mqtt非标准定义
-	RyanMqttConnectClientInvalid = 200,         // 客户端处于无效状态
-	RyanMqttConnectNetWorkFail,                 // 网络错误
-	RyanMqttConnectDisconnected,                // mqtt客户端断开连接
-	RyanMqttKeepaliveTimeout,                   // 心跳超时断开连接
-	RyanMqttConnectUserDisconnected,            // 用户手动断开连接
-	RyanMqttConnectTimeout,                     // 超时断开
-	RyanMqttConnectFirstPackNotConnack,         // 发送connect后接受到的第一个报文不是connack
-	RyanMqttConnectProtocolError,               // 多次收到connack
-	RyanMqttConnectInvalidPacketError,          // 收到不符合MQTT3.1.1协议的报文,并且要求关闭客户端的
-	RyanMqttConnectFailedError,                 // 杂项原因,比如内存分配失败,序列化失败等
-	RyanMqttConnectStatusForceInt32 = INT32_MAX // 强制编译器使用int32_t类型
+	RyanMqttConnectClientInvalid = 200, // 客户端处于无效状态
+	RyanMqttConnectNetWorkFail,         // 网络错误
+	RyanMqttConnectDisconnected,        // mqtt客户端断开连接
+	RyanMqttKeepaliveTimeout,           // 心跳超时断开连接
+	RyanMqttConnectUserDisconnected,    // 用户手动断开连接
+	RyanMqttConnectTimeout,             // 超时断开
+	RyanMqttConnectFirstPackNotConnack, // 发送connect后接受到的第一个报文不是connack
+	RyanMqttConnectProtocolError,       // 多次收到connack
+	RyanMqttConnectInvalidPacketError,  // 收到不符合MQTT3.1.1协议的报文,并且要求关闭客户端的
+	RyanMqttConnectFailedError,         // 杂项原因,比如内存分配失败,序列化失败等
+					    // RyanMqttConnectStatusForceInt32 = INT32_MAX // 强制编译器使用int32_t类型
 } RyanMqttConnectStatus_e;
 
 extern const char *RyanMqttStrError(int32_t state);

+ 0 - 4
test/RyanMqttPublicApiParamCheckTest.c

@@ -135,10 +135,6 @@ static RyanMqttError_e RyanMqttLwtApiParamCheckTest(void)
 	result = RyanMqttSetLwt(validClient, "test/lwt", "offline", 7, invalidQos(), RyanMqttTrue);
 	RyanMqttCheckCodeNoReturn(RyanMqttParamInvalidError == result, result, RyanMqttLog_e, { goto __exit; });
 
-	// 无效retain
-	// NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
-	result = RyanMqttSetLwt(validClient, "test/lwt", "offline", 7, RyanMqttQos1, 200);
-	RyanMqttCheckCodeNoReturn(RyanMqttParamInvalidError == result, result, RyanMqttLog_e, { goto __exit; });
 	// 清理资源
 	if (validClient)
 	{