简体   繁体   中英

Publishing JSON object through MQTT to AWS IoT from ESP32 using C and ESP-IDF framework

I have a structure IoT_Publish_Message_Params that needs to be prepared in order to prepare a publishing on AWS IoT. The below snippet works completely fine when I'm passing a string as the payload.

/**
 * @brief Publish Message Parameters Type
 *
 * Defines a type for MQTT Publish messages. Used for both incoming and out going messages
 *
 */
typedef struct {
    QoS qos;        ///< Message Quality of Service
    uint8_t isRetained; ///< Retained messages are \b NOT supported by the AWS IoT Service at the time of this SDK release.
    uint8_t isDup;      ///< Is this message a duplicate QoS > 0 message?  Handled automatically by the MQTT client.
    uint16_t id;        ///< Message sequence identifier.  Handled automatically by the MQTT client.
    void *payload;      ///< Pointer to MQTT message payload (bytes).
    size_t payloadLen;  ///< Length of MQTT payload.
} IoT_Publish_Message_Params;

IoT_Publish_Message_Params paramsQOS0;
sprintf(cPayload, "%s : %d ", "Hello from HOME!!", i);

paramsQOS0.qos = QOS0;
paramsQOS0.payload = (void *) cPayload;
paramsQOS0.isRetained = 0;
paramsQOS0.payloadLen = strlen(cPayload);
rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS0);

Now I want to send an actual JSON payload and I'm not sure how I can do that. I've tried using cJSON to create a JSON object:

cJSON *root,*fmt;
root=cJSON_CreateObject();
paramsQOS0.payload = (void *) root
cJSON_AddItemToObject(root, "response", fmt=cJSON_CreateObject());
cJSON_AddNumberToObject(fmt,"hello", 123);
cJSON_AddNumberToObject(fmt,"bye", 321);

However, my question is, what do I pass as IoT_Publish_Message_Params.payloadLen here? And how do I pass the json object to IoT_Publish_Message_Params.payload?

As I see it you have two options. Send the JSON as a string, or as raw bytes.

If you want to send it as a string (eg {"CarType":"BMW","carID":"bmw123"} ), then you want to convert it to a string. Found some code here .

char* str = cJSON_Print(root);  
paramsQOS0.payload = (void *) str;
paramsQOS0.payloadLen = strlen(str);

However, it would be much more efficient to send it as raw bytes. For this, you would need a pointer to the start of the object, and the size of the object in bytes. Quickly scanning the GitHub Page I found the cJSON_GetArraySize which apparently returns the object size.

Then it should look something like this:

paramsQOS0.payload = (void *) root;
paramsQOS0.payloadLen = cJSON_GetArraySize(root); // Not sure about this one

Disclaimer, I haven't used cJSON and haven't tested the code. I'm trying to show you which direction to take.

IoT_Publish_Message_Params has payload and payloadLen members, so you can provide any valid memory and length of bytes you want to send. In your first example you provided a statically allocated string and it's length.

JSON is a string based encoding protocol, so payload will be a char pointer and payloadLen can be calculated using strlen .

cJSON_Print returns the json string for an object, use the pointer returned by it and assign it to payload .

Please read cJSON API documentation how to use it. And below is how you can use modify your code to send the JSON string.

IoT_Publish_Message_Params paramsQOS0;
char *json_str;

/* create a json message */
cJSON *root, *response;
root = cJSON_CreateObject();
response = cJSON_CreateObject();
cJSON_AddItemToObject(root, "response", response);
cJSON_AddNumberToObject(response, "hello", 123);
cJSON_AddNumberToObject(response, "bye", 321);

json_str = cJSON_Print(root);
if (json_str != NULL)
{
    paramsQOS0.qos = QOS0;
    paramsQOS0.isRetained = 0;
    paramsQOS0.payload = json_str;
    paramsQOS0.payloadLen = strlen(json_str);
    rc = aws_iot_mqtt_publish(&client, TOPIC, TOPIC_LEN, &paramsQOS0);
    free(json_str);
}

cJSON_Delete(root);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM