This topic describes how to use the open source Paho MQTT project for embedded C to connect a device to IoT Platform and enable messaging.
Usage notes
In this topic, the permissions of a common user are used to perform all operations. If you want to perform specific operations that require administrator permissions, run the sudo
command.
Prerequisites
A product and a device are created in an instance in the IoT Platform console. The device certificate and an MQTT endpoint are obtained. The device certificate information includes the ProductKey, DeviceName, and DeviceSecret. For more information, see the following topics:
Prepare the development environment
In this example, Ubuntu 16.04-LTS is used to build the development environment. Run the following commands to build the development environment:
sudo apt-get update
sudo apt-get install build-essential git sed cmake
Download the Paho MQTT library for C
Run the following command to clone the Paho MQTT library for C:
git clone https://github.com/eclipse/paho.mqtt.embedded-c.git
In this topic, the master branch is used to develop the sample code. The commit ID is 29ab2aa29c5e47794284376d7f8386cfd54c3eed
.
The Paho MQTT project for embedded C includes the following sub-projects:
MQTTPacket: provides serialization and deserialization of MQTT data packets and some helper functions.
MQTTClient: encapsulates the high-level C++ client program that is generated by MQTTPacket.
MQTTClient-C: encapsulates the high-level C client program that is generated by MQTTPacket.
The MQTTClient-C project includes the following directories and files:
├── CMakeLists.txt ├── samples │ ├── CMakeLists.txt │ ├── FreeRTOS │ └── linux ├── src │ ├── CMakeLists.txt │ ├── FreeRTOS │ ├── MQTTClient.c │ ├── MQTTClient.h │ ├── cc3200 │ └── linux └── test ├── CMakeLists.txt └── test1.c
The samples directory provides sample code for FreeRTOS and Linux systems.
The src directory provides sample code to implement MQTTClient and network drivers for porting to FreeRTOS, CC3200, and Linux.
For more information about the Paho MQTT API, see MQTTClient.h.
Connect the client to IoT Platform
Click aiot_mqtt_sign.c and copy the source code that is provided by Alibaba Cloud to obtain the MQTT connection parameters. Then, create a file named aiot_mqtt_sign.c on premises and paste the code to the file.
The aiot_mqtt_signal.c file defines the aiotMqttSign() function.
Definition:
int aiotMqttSign(const char *productKey, const char *deviceName, const char *deviceSecret, char clientId[150], char username[65], char password[65]);
Description
You can use this class to obtain the following MQTT connection parameters: username, password and clientid.
Input parameters:
Parameter
Type
Description
productKey
const char *
The ProductKey of the product to which the device belongs. This ProductKey is used to identify the device in the IoT Platform console.
deviceName
const char *
The DeviceName of the device. This DeviceName is used to identify the device in the IoT Platform console.
deviceSecret
const char *
The DeviceSecret of the device. This DeviceSecret is used to identify the device in the IoT Platform console.
Output:
Parameter
Type
Description
username
char *
The username that is used to establish the MQTT connection.
password
char *
The password that is used to establish the MQTT connection.
clientId
char *
The ID of the MQTT client.
Response codes
Response code
Description
0
The call was successful.
-1
The call failed.
Add a program file that can connect a device to IoT Platform.
You must write a program to call the aiotMqttSign() function in the aiot_mqtt_sign.c file to obtain the parameters that are required to establish an MQTT connection to IoT Platform.
This section provides the development instructions and sample code.
Call the aiotMqttSign() function to initialize the clientId, username, and password parameters.
#define EXAMPLE_PRODUCT_KEY "a11xsrW****" #define EXAMPLE_DEVICE_NAME "paho_****" #define EXAMPLE_DEVICE_SECRET "Y877Bgo8X5owd3lcB5wWDjryNPoB****" extern int aiotMqttSign(const char *productKey, const char *deviceName, const char *deviceSecret, char clientId[150], char username[65], char password[65]); /* invoke aiotMqttSign to generate mqtt connect parameters */ char clientId[150] = {0}; char username[65] = {0}; char password[65] = {0}; if ((rc = aiotMqttSign(EXAMPLE_PRODUCT_KEY, EXAMPLE_DEVICE_NAME, EXAMPLE_DEVICE_SECRET, clientId, username, password) < 0)) { printf("aiotMqttSign -%0x4x\n", -rc); return -1; } printf("clientid: %s\n", clientId); printf("username: %s\n", username); printf("password: %s\n", password);
Connect the client to IoT Platform.
Perform the following operations:
Call the NetworkInit() and NetworkConnect() functions to establish a TCP connection.
Call the MQTTClientInit() function to initialize the MQTT client.
Configure the MQTTPacket_connectData structure that contains the MQTT connection parameters.
Sample code:
/* network init and establish network to aliyun IoT platform */ NetworkInit(&n); rc = NetworkConnect(&n, host, port); printf("NetworkConnect %d\n", rc); /* init mqtt client */ MQTTClientInit(&c, &n, 1000, buf, sizeof(buf), readbuf, sizeof(readbuf)); /* set the default message handler */ c.defaultMessageHandler = messageArrived; /* set mqtt connect parameter */ MQTTPacket_connectData data = MQTTPacket_connectData_initializer; data.willFlag = 0; data.MQTTVersion = 3; data.clientID.cstring = clientId; data.username.cstring = username; data.password.cstring = password; data.keepAliveInterval = 60; data.cleansession = 1; printf("Connecting to %s %d\n", host, port); rc = MQTTConnect(&c, &data); printf("MQTTConnect %d, Connect aliyun IoT Cloud Success!\n", rc);
Publish messages.
Call the MQTTPublish() function to publish messages in the custom format to the specified custom topic.
For more information about topics, see Topics.
char *pubTopic = "/"EXAMPLE_PRODUCT_KEY"/"EXAMPLE_DEVICE_NAME"/user/update"; int cnt = 0; unsigned int msgid = 0; while (!toStop) { MQTTYield(&c, 1000); if (++cnt % 5 == 0) { MQTTMessage msg = { QOS1, 0, 0, 0, "Hello world", strlen("Hello world"), }; msg.id = ++msgid; rc = MQTTPublish(&c, pubTopic, &msg); printf("MQTTPublish %d, msgid %d\n", rc, msgid); } }
Subscribe to a topic to receive messages from IoT Platform.
void messageArrived(MessageData* md) { MQTTMessage* message = md->message; printf("%.*s\t", md->topicName->lenstring.len, md->topicName->lenstring.data); printf("%.*s\n", (int)message->payloadlen, (char*)message->payload); } char *subTopic = "/"EXAMPLE_PRODUCT_KEY"/"EXAMPLE_DEVICE_NAME"/user/get"; printf("Subscribing to %s\n", subTopic); rc = MQTTSubscribe(&c, subTopic, 1, messageArrived); printf("MQTTSubscribe %d\n", rc);
For more information about the communication methods of devices, servers, and IoT Platform, see Overview.
Copy the aiot_mqtt_signal.c file and the file that is modified in Step 2 to ../paho.mqtt.embedded-c/MQTTClient-C/samples/linux. Then, compile the project.
Sample code
You can run the sample code to connect to IoT Platform.
Download the demo package and decompress it.
The following files are obtained:
Certificate file
Description
aiot_mqtt_sign.c
This file contains the code that is used to obtain the MQTT connection parameters. When you run the aiot_c_demo.c file, the aiotMqttSign() function is called to obtain values of the username, password, and clientId parameters.
aiot_c_demo.c
This file contains the logic code that is used to connect to and communicate with IoT Platform.
In the aiot_c_demo.c file, replace the device information with your device information.
Replace the values of the EXAMPLE_PRODUCT_KEY, EXAMPLE_DEVICE_NAME, and EXAMPLE_DEVICE_SECRET parameters with your device certificate information.
#define EXAMPLE_PRODUCT_KEY "The ProductKey of the product" #define EXAMPLE_DEVICE_NAME "The DeviceName of the device" #define EXAMPLE_DEVICE_SECRET "The DeviceSecret of the device"
Modify the endpoint in
char *host = EXAMPLE_PRODUCT_KEY".iot-as-mqtt.cn-shanghai.aliyuncs.com"
.For more information about the endpoints of public instances and Enterprise Edition instances and the formats of the endpoints, see View the endpoint of an instance.
Move the aiot_mqtt_signal.c and aiot_c_demo.c files to the ../paho.mqtt.embedded-c/MQTTClient-C/samples/linux directory of the Paho project.
Compile the project and run the program.
You can compile the project by using one of the following methods:
Use the CMake tool.
Add aiot_c_demo.c and aiot_mqtt_signal.c to the CMakeLists.txt file in the /paho.mqtt.embedded-c/MQTTClient-C/samples/linux directory.
The following code shows how to modify the CMakeLists.txt file.
add_executable( stdoutsubc stdoutsub.c ) add_executable( aiot_c_demo aiot_c_demo.c aiot_mqtt_sign.c ) target_link_libraries(stdoutsubc paho-embed-mqtt3cc paho-embed-mqtt3c) target_include_directories(stdoutsubc PRIVATE "../../src" "../../src/linux") target_compile_definitions(stdoutsubc PRIVATE MQTTCLIENT_PLATFORM_HEADER=MQTTLinux.h) target_link_libraries(aiot_c_demo paho-embed-mqtt3cc paho-embed-mqtt3c) target_include_directories(aiot_c_demo PRIVATE "../../src" "../../src/linux") target_compile_definitions(aiot_c_demo PRIVATE MQTTCLIENT_PLATFORM_HEADER=MQTTLinux.h)
Go back to the /paho.mqtt.embedded-c directory and run the following command to compile the project.
mkdir build.paho cd build.paho cmake .. make
Go to the /paho.mqtt.embedded-c/build.paho directory and run the following command to run the program:
./MQTTClient-C/samples/linux/aiot_c_demo
Use the build.sh file.
Open the build.sh file in the /paho.mqtt.embedded-c/MQTTClient-C/samples/linux directory.
In the build.sh file, replace
stdoutsub.c
withaiot_mqtt_sign.c aiot_c_demo.c
, and-o stdoutsub
with-o aiot_c_demo
. Then, save the build.sh file.Go to the /paho.mqtt.embedded-c/MQTTClient-C/samples/linux directory and run the
./build.sh
command.After the compilation, the aiot_c_demo executable file is generated.
Run the
./aiot_c_demo
command to run the file.
After you run the file, the following local logs are generated:
clientid: paho_mqtt&a11xsrW****|timestamp=2524608000000,_v=sdk-c-1.0.0,securemode=3,signmethod=hmacsha256,lan=C| username: paho_mqtt&a11xsrW**** password: 36E955DC3D9D012EF62C80657A29328B1CFAE6186C611A17DC7939FAB637**** NetworkConnect 0 Connecting to a11xsrW****.iot-as-mqtt.cn-shanghai.aliyuncs.com 443 MQTTConnect 0, Connect aliyun IoT Cloud Success! Subscribing to /a11xsrW****/paho_mqtt/user/get MQTTSubscribe 0 MQTTPublish 0, msgid 1 MQTTPublish 0, msgid 2 MQTTPublish 0, msgid 3 MQTTPublish 0, msgid 4 MQTTPublish 0, msgid 5 ...
In the IoT Platform console, you can view the device status and logs.
Choose
. The Devices page shows that the device is in Online state.Choose IoT Platform logs and Local device logs.
. Then, click the Cloud run log or Device local log tab to view logs. For more information, see
Error codes
If a device fails to establish an MQTT connection to IoT Platform, you can troubleshoot the issue based on the error code. For more information, see Troubleshooting.