Click on the “Embedded Application Research Institute” above, and select “Top/Star Official Account“
Useful Resources Delivered First Hand!
Source | Embedded Application Research Institute
Compiled & Formatted | Embedded Application Research Institute
In the development of IoT-related applications, MQTT is used to some extent. The following open-source project is an interface I encapsulated based on the mqttclient
project by the great Jiejie:
https://github.com/Yangyuanxin/EasyMqttClient
The mqttclient
project by Jiejie:
https://github.com/jiejieTop/mqttclient
Before encapsulation, I used a memory leak tool to locate and troubleshoot issues with mqtt_release
and SALOF_LOG
. Fortunately, the mqtt_release
scenario is rarely used, but it is still necessary to mention:
-
Bug1 (Memory Leak in platform_thread
)
The function platform_thread_destroy
in the mqttclient/platform/linux/platform_thread.c
file does not free the memory allocated for thread
in the thread encapsulation function, which causes a memory leak when mqttclient
calls the mqtt_release
function.
-
Bug2 (To be resolved – can be fixed by disabling macro definitions)
The mqttclient/common/log
module has a memory leak, which can be resolved by disabling MQTT_LOG_IS_SALOF
in the mqtt_config.h
file.
-
Bug3 (To be resolved – can be temporarily ignored)
When executing mqtt_release
, there is a chance of encountering a core dump
, but the mqtt_release
scenario is not commonly seen in general product development unless there is a specific need. For details, see the Issues I raised:
https://github.com/jiejieTop/mqttclient/issues/60
Aside from that, using mqttclient
is quite pleasant, and many open-source projects and actual products have utilized this interface, making it very stable.
Here are the 7 APIs of my encapsulated interface, which are very simple! They are:
//MQTT Initialization
EasyMqttClient_t *EasyMqttInit(EasyMqttAttr_t *Attr);
//MQTT De-initialization
int EasyMqttUnInit(EasyMqttClient_t *Client);
//MQTT Connection
int EasyMqttConnect(EasyMqttClient_t *Client);
//MQTT Disconnection
int EasyMqttDisConnect(EasyMqttClient_t *Client);
//MQTT Topic Subscription
int EasyMqttSubscribe(EasyMqttClient_t *Client, const char *Topic, enum EasyMqttQos_t Qos,
void (*Cb)(const char *Topic,char* Data,unsigned short Len));
//MQTT Unsubscription
int EasyMqttUnsubscribe(EasyMqttClient_t *Client, const char *Topic);
//MQTT Topic Publishing
int EasyMqttPublish(EasyMqttClient_t *Client, const char *Topic, enum EasyMqttQos_t Qos, char *Data, unsigned short Len);
The EasyMqttInit
function encapsulates these trivial processes, such as setting the URL and port number, into a structure EasyMqttAttr
:
typedef struct EasyMqttAttr
{
char *Url;
char *Port;
char *ClientId;
char *Username;
char *Password;
}EasyMqttAttr_t;
//......................
mqtt_set_host;
mqtt_set_port;
mqtt_set_client_id;
mqtt_set_user_name;
mqtt_set_password;
mqtt_set_clean_session;
//When calling, it's very simple
//1.
//2.Define a structure variable
example:
EasyMqttClient_t *Client = NULL;
EasyMqttAttr_t Attr =
{
.Url = "192.168.4.248",
.Port = "30157",
.ClientId = "EasyMqttMqtt",
.Username = "EasyMqtt",
.Password = "123456"
};
//3.Call the EasyMqttInit function
Client = EasyMqttInit(Client, &Attr);
//to do
//Implement your MQTT connection, subscription, distribution logic
//to do end
Additionally, it implements separate handling of callback functions for different subscribed Topics, making the development logic clearer and easier to debug and troubleshoot. This mechanism is based on an array of structures, as shown below:
struct TopicHandler_t
{
//Topic
const char *Topic;
//Callback function corresponding to the Topic
void (*CallBack)(const char *Topic,char* Data,unsigned short Len);
};
//Structure array table, maximum support for handling Topics is MAX_TOPIC, which defaults to 64
struct TopicHandler_t Table[MAX_TOPIC];
When calling the EasyMqttSubscribe
Topic subscription function to subscribe to a Topic, this Topic and its callback will be added to this table. When mqttclient
receives different Topics, it will look up the table to call the corresponding callback function for different Topics. The specific logic is as follows:
//Topic callback trigger
static void TopicHandlerCallBack(void* client, message_data_t* Msg)
{
(void)client;
int Index = 0;
char *Topic = Msg->topic_name;
unsigned short Len = Msg->message->payloadlen;
char *Data = (char *)Msg->message->payload;
//Locking
pthread_mutex_lock(&Mutex);
//When receiving different Topics, find the corresponding callback function based on the Topic and call it
for(Index = 0; Index < sizeof(Table)/sizeof(Table[0]); Index++)
{
if(0 == strcmp(Msg->topic_name,Table[Index].Topic))
{
Table[Index].CallBack(Topic,Data,Len);
break;
}
}
//Unlocking
pthread_mutex_unlock(&Mutex);
}
//EasyMqttSubscribe Topic subscription function
int EasyMqttSubscribe(EasyMqttClient_t *Client, const char *Topic, enum EasyMqttQos_t Qos,
void (*Cb)(const char *Topic, char* Data, unsigned short Len))
{
if(Index > MAX_TOPIC-1)
{
printf("Exceeds the maximum number of topics set:%d!\n", Index);
return -1;
}
Table[Index].Topic = Topic;
Table[Index].CallBack = Cb;
Index++;
return mqtt_subscribe(Client, Topic, (mqtt_qos_t)Qos, TopicHandlerCallBack);
}
For specific usage methods, please refer to the EasyMqtt.c
file’s EasyMqttTest
function. Currently, this project has only been tested on Linux projects; further testing will be conducted in different RTOS environments. Continuous attention is welcomed, and PRs are also welcome to make embedded MQTT application development simpler together.
Using this project in a Linux environment:
-
1. Clone this project
git clone https://github.com/Yangyuanxin/EasyMqttClient.git
-
2. Modify the cross-compilation toolchain (default is gcc)
If you want to run it on an embedded platform, you need to modify the Makefile
as follows:
CROSS_COMPILE =
Otherwise, it will compile in the default gcc environment.
-
3. Compile
make
-
4. Execute
./a.out
Other environments: to be tested.
Previous Highlights
Hands-on open-source tutorials based on HarmonyOS projects
Sharing some highly-rated open-source projects related to embedded systems on GitHub
Open Source: AliOS_Things_Developer_Kit revival plan
An amazing open-source interpretation project [Linux Kernel Unveiling], definitely don’t miss it!
If you find this article helpful, please click <span>[Looking]</span>
and share it, it is also a support for me.