CJSON failing to print via cJSON_Print()

I'm using the CJSON library to bundle up some log file data that I send over a custom BLE characteristic.  Everything seems to work until I bump the number of data elements I am sending, and then I start getting errors back from my cJSON_Print() API call.

I have an array of data, each element consisting of the following:

struct time_stamp {
	uint16_t year;
	uint8_t month;
	uint8_t day;
	uint8_t hours;
	uint8_t minutes;
	uint8_t seconds;
};

struct log_data {
	uint8_t event_type;
	int16_t event_value;
	struct time_stamp event_time_date;
	uint16_t event_time_offset;
};

Rather than trying to send the whole array, I am carving it up into its individual elements, adding the CJSON encoding, then sending an element of data.  I then move on to the next element until all elements have been sent.

I can send about 90 elements without issue, but once I go past that, I get errors back from subsequent calls to the cJSON_Print() API.

This is how I am encoding each element of data:

char *create_log_data(struct log_data *data)
{
    char *string = NULL;
    
    cJSON *json_log_data = cJSON_CreateObject();


    if (json_log_data == NULL) {
        goto end;
    }

    if (cJSON_AddNumberToObject(json_log_data, "event", data->event_type) == NULL) {
        LOG_ERR("Failed to print event data");
        goto end;
    }

    if (cJSON_AddNumberToObject(json_log_data, "value", data->event_value) == NULL) {
        LOG_ERR("Failed to print value data");
        goto end;
    }

    if (cJSON_AddNumberToObject(json_log_data, "yy", data->event_time_date.year) == NULL) {
        LOG_ERR("Failed to print yy data");
        goto end;
    }

    if (cJSON_AddNumberToObject(json_log_data, "mm", data->event_time_date.month) == NULL) {
        LOG_ERR("Failed to print mm data");
        goto end;
    }

    if (cJSON_AddNumberToObject(json_log_data, "dd", data->event_time_date.day) == NULL) {
        LOG_ERR("Failed to print dd data");
        goto end;
    }

    if (cJSON_AddNumberToObject(json_log_data, "hh", data->event_time_date.hours) == NULL) {
         LOG_ERR("Failed to print hh data");
        goto end;
    }

    if (cJSON_AddNumberToObject(json_log_data, "mm", data->event_time_date.minutes) == NULL) {
        LOG_ERR("Failed to print mm data");
        goto end;
    }

    if (cJSON_AddNumberToObject(json_log_data, "ss", data->event_time_date.seconds) == NULL) {
        LOG_ERR("Failed to print ss data");
        goto end;
    }

    if (cJSON_AddNumberToObject(json_log_data, "+UTC", data->event_time_offset) == NULL) {
        LOG_ERR("Failed to print +UTC data");
        goto end;
    }

    string = cJSON_Print(json_log_data);
    if (string == NULL) {
        LOG_ERR("Failed to print event data");
    }

end:
    cJSON_Delete(json_log_data);
    return string;
}

And this is how I am then sending the encoded data:

for (i = 0; i < MAX_EVENTS; i++) {
						log_file_json_data = create_log_data(&log_file_info[i]);
						err = send_log_data_indication(current_conn, log_file_json_data, strlen(log_file_json_data));
						if (err < 0) {
							LOG_ERR("Error sending log data");
						};
					}

I am getting an error message in my logs saying "Failed to print event data", which means at some point the call to:

    string = cJSON_Print(json_log_data);
    if (string == NULL) {
        LOG_ERR("Failed to print event data");
    }

is returning a NULL.  Looking at the relevant API's in the cJSON.c file, I can't really see anything obvious that might be causing the issue.  I'm not getting any of the error messages prior to this that would indicate its failing to add the formatted data to the cJSON struct.

This is what my prj.conf file looks like with regards to cJSON:

#cJSON
CONFIG_CJSON_LIB=y
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

I've read in a few posts the need to make a call to cJSON_Init() in my main, but the moment I add that, I get a compile error that says:

c:/nordic/toolchains/v2.2.0/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.1.0/../../../../arm-zephyr-eabi/bin/ld.exe: modules/cjson/libcjson.a(cJSON_os.c.obj): in function `malloc_fn_hook':
C:\Nordic\v2.2.0\nrf\modules\cjson\os\cJSON_os.c:15: undefined reference to `k_malloc'

Not sure if that's related.

Is there anyone out there with experience usign the cJSON encoding that can help me get to the bottom of this issue?

I'm using NCS V2.2.0 and nRF52-DK's in my testing.  One DK is the peripheral that is sending the data and the other DK is connected ot nRF Connect for Desktop acting as the central, so I can test receiving the data

Cheers,

Mike

Related