Dynamically assign MQTT subscription topic on AWS

I try to subscribe to a MQTT topic on AWS using the following code which is used to compose a dynamic MQTT topic based on IMEI

char imei[32] = {'\0',};
modem_info_string_get(MODEM_INFO_IMEI, imei, sizeof(imei));
printk("Modem IMEI: %s \n", imei);
static char settingsString[20] =  "/settings\0";
static char topicString[75];
strcpy(topicString, imei);
strcat(topicString, settingsString);
printk("Subscribe string: %s \n", imei);
printk("Subscribe string length: %d \n", strlen(imei));

const struct aws_iot_topic_data topics_list[APP_TOPICS_COUNT] = {
	[0].str = *topicString,
	[0].len = strlen(*topicString)};

err = aws_iot_subscription_topics_add(topics_list, ARRAY_SIZE(topics_list));
if (err)
{
	printk("aws_iot_subscription_topics_add, error: %d\n", err);
}

The output is this (*** for security reasons) 

Modem IMEI: 351358815046***
Subscribe string: 351358815046***/settings
Subscribe string length: 24

If I now publish a message using AWS MQTT Client the message will not reach the device. The strange thing is if i declare the same variable hard coded using

static char topicString[75] = "351358815046880/settings"

All works as expected and the publish messages get received as expected. 

Is there anything wrong using the strcat function? 

Thanks!

  • Hello,

    What version of the nRF Connect SDK are you using? Could there be an issue with "\0" added to end of settingsString?

    Kind regards,
    Øyvind

  • I tried with and without the "\0", result is the same. 

    I am using  2.1.2

  • Are you able to provide me the project you are working on, in order to reproduce the issue?

  • Below is the aws_iot sample as provided with minimal changes. 

    main.c

    /*
     * Copyright (c) 2020 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <stdio.h>
    #include <stdlib.h>
    #if defined(CONFIG_NRF_MODEM_LIB)
    #include <modem/lte_lc.h>
    #include <modem/nrf_modem_lib.h>
    #include <modem/modem_info.h>
    #include <nrf_modem.h>
    #endif
    #include <net/aws_iot.h>
    #include <zephyr/sys/reboot.h>
    #include <date_time.h>
    #include <zephyr/dfu/mcuboot.h>
    #include <cJSON.h>
    #include <cJSON_os.h>
    #include <zephyr/logging/log.h>
    
    char imei[32] = {
    	'\0',
    };
    
    LOG_MODULE_REGISTER(aws_iot_sample, CONFIG_AWS_IOT_SAMPLE_LOG_LEVEL);
    
    BUILD_ASSERT(!IS_ENABLED(CONFIG_LTE_AUTO_INIT_AND_CONNECT),
    	     "This sample does not support LTE auto-init and connect");
    
    #define APP_TOPICS_COUNT CONFIG_AWS_IOT_APP_SUBSCRIPTION_LIST_COUNT
    
    static struct k_work_delayable shadow_update_work;
    static struct k_work_delayable connect_work;
    static struct k_work shadow_update_version_work;
    
    static bool cloud_connected;
    
    static K_SEM_DEFINE(lte_connected, 0, 1);
    static K_SEM_DEFINE(date_time_obtained, 0, 1);
    
    #if defined(CONFIG_NRF_MODEM_LIB)
    NRF_MODEM_LIB_ON_INIT(aws_iot_init_hook, on_modem_lib_init, NULL);
    
    /* Initialized to value different than success (0) */
    static int modem_lib_init_result = -1;
    
    static void on_modem_lib_init(int ret, void *ctx)
    {
    	modem_lib_init_result = ret;
    }
    #endif
    
    static int json_add_obj(cJSON *parent, const char *str, cJSON *item)
    {
    	cJSON_AddItemToObject(parent, str, item);
    
    	return 0;
    }
    
    static int json_add_str(cJSON *parent, const char *str, const char *item)
    {
    	cJSON *json_str;
    
    	json_str = cJSON_CreateString(item);
    	if (json_str == NULL) {
    		return -ENOMEM;
    	}
    
    	return json_add_obj(parent, str, json_str);
    }
    
    static int json_add_number(cJSON *parent, const char *str, double item)
    {
    	cJSON *json_num;
    
    	json_num = cJSON_CreateNumber(item);
    	if (json_num == NULL) {
    		return -ENOMEM;
    	}
    
    	return json_add_obj(parent, str, json_num);
    }
    
    static int shadow_update(bool version_number_include)
    {
    	int err;
    	char *message;
    	int64_t message_ts = 0;
    	int16_t bat_voltage = 0;
    
    	err = date_time_now(&message_ts);
    	if (err) {
    		LOG_ERR("date_time_now, error: %d", err);
    		return err;
    	}
    
    #if defined(CONFIG_NRF_MODEM_LIB)
    	/* Request battery voltage data from the modem. */
    	err = modem_info_short_get(MODEM_INFO_BATTERY, &bat_voltage);
    	if (err != sizeof(bat_voltage)) {
    		LOG_ERR("modem_info_short_get, error: %d", err);
    		return err;
    	}
    #endif
    
    	cJSON *root_obj = cJSON_CreateObject();
    	cJSON *state_obj = cJSON_CreateObject();
    	cJSON *reported_obj = cJSON_CreateObject();
    
    	if (root_obj == NULL || state_obj == NULL || reported_obj == NULL) {
    		cJSON_Delete(root_obj);
    		cJSON_Delete(state_obj);
    		cJSON_Delete(reported_obj);
    		err = -ENOMEM;
    		return err;
    	}
    
    	if (version_number_include) {
    		err = json_add_str(reported_obj, "app_version", CONFIG_APP_VERSION);
    	} else {
    		err = 0;
    	}
    
    	err += json_add_number(reported_obj, "batv", bat_voltage);
    	err += json_add_number(reported_obj, "ts", message_ts);
    	err += json_add_obj(state_obj, "reported", reported_obj);
    	err += json_add_obj(root_obj, "state", state_obj);
    
    	if (err) {
    		LOG_ERR("json_add, error: %d", err);
    		goto cleanup;
    	}
    
    	message = cJSON_Print(root_obj);
    	if (message == NULL) {
    		LOG_ERR("cJSON_Print, error: returned NULL");
    		err = -ENOMEM;
    		goto cleanup;
    	}
    
    	struct aws_iot_data tx_data = { .qos = MQTT_QOS_0_AT_MOST_ONCE,
    					.topic.type = AWS_IOT_SHADOW_TOPIC_UPDATE,
    					.ptr = message,
    					.len = strlen(message) };
    
    	LOG_INF("Publishing: %s to AWS IoT broker", message);
    
    	err = aws_iot_send(&tx_data);
    	if (err) {
    		LOG_ERR("aws_iot_send, error: %d", err);
    	}
    
    	cJSON_FreeString(message);
    
    cleanup:
    
    	cJSON_Delete(root_obj);
    
    	return err;
    }
    
    static void connect_work_fn(struct k_work *work)
    {
    	int err;
    
    	if (cloud_connected) {
    		return;
    	}
    
    	err = aws_iot_connect(NULL);
    	if (err) {
    		LOG_ERR("aws_iot_connect, error: %d", err);
    	}
    
    	LOG_INF("Next connection retry in %d seconds", CONFIG_CONNECTION_RETRY_TIMEOUT_SECONDS);
    
    	k_work_schedule(&connect_work, K_SECONDS(CONFIG_CONNECTION_RETRY_TIMEOUT_SECONDS));
    }
    
    static void shadow_update_work_fn(struct k_work *work)
    {
    	int err;
    
    	if (!cloud_connected) {
    		return;
    	}
    
    	err = shadow_update(false);
    	if (err) {
    		LOG_ERR("shadow_update, error: %d", err);
    	}
    
    	LOG_INF("Next data publication in %d seconds", CONFIG_PUBLICATION_INTERVAL_SECONDS);
    
    	k_work_schedule(&shadow_update_work, K_SECONDS(CONFIG_PUBLICATION_INTERVAL_SECONDS));
    }
    
    static void shadow_update_version_work_fn(struct k_work *work)
    {
    	int err;
    
    	err = shadow_update(true);
    	if (err) {
    		LOG_ERR("shadow_update, error: %d", err);
    	}
    }
    
    static void print_received_data(const char *buf, const char *topic, size_t topic_len)
    {
    	char *str = NULL;
    	cJSON *root_obj = NULL;
    
    	root_obj = cJSON_Parse(buf);
    	if (root_obj == NULL) {
    		LOG_ERR("cJSON Parse failure");
    		return;
    	}
    
    	str = cJSON_Print(root_obj);
    	if (str == NULL) {
    		LOG_ERR("Failed to print JSON object");
    		goto clean_exit;
    	}
    
    	LOG_INF("Data received from AWS IoT console: Topic: %.*s Message: %s", topic_len, topic,
    		str);
    
    	cJSON_FreeString(str);
    
    clean_exit:
    	cJSON_Delete(root_obj);
    }
    
    void aws_iot_event_handler(const struct aws_iot_evt *const evt)
    {
    	switch (evt->type) {
    	case AWS_IOT_EVT_CONNECTING:
    		LOG_INF("AWS_IOT_EVT_CONNECTING");
    		break;
    	case AWS_IOT_EVT_CONNECTED:
    		LOG_INF("AWS_IOT_EVT_CONNECTED");
    
    		cloud_connected = true;
    		/* This may fail if the work item is already being processed,
    		 * but in such case, the next time the work handler is executed,
    		 * it will exit after checking the above flag and the work will
    		 * not be scheduled again.
    		 */
    		(void)k_work_cancel_delayable(&connect_work);
    
    		if (evt->data.persistent_session) {
    			LOG_INF("Persistent session enabled");
    		}
    
    #if defined(CONFIG_NRF_MODEM_LIB)
    		/** Successfully connected to AWS IoT broker, mark image as
    		 *  working to avoid reverting to the former image upon reboot.
    		 */
    		boot_write_img_confirmed();
    #endif
    
    		/** Send version number to AWS IoT broker to verify that the
    		 *  FOTA update worked.
    		 */
    		k_work_submit(&shadow_update_version_work);
    
    		/** Start sequential shadow data updates.
    		 */
    		k_work_schedule(&shadow_update_work,
    				K_SECONDS(CONFIG_PUBLICATION_INTERVAL_SECONDS));
    
    #if defined(CONFIG_NRF_MODEM_LIB)
    		int err = lte_lc_psm_req(true);
    		if (err) {
    			LOG_ERR("Requesting PSM failed, error: %d", err);
    		}
    #endif
    		break;
    	case AWS_IOT_EVT_READY:
    		LOG_INF("AWS_IOT_EVT_READY");
    		break;
    	case AWS_IOT_EVT_DISCONNECTED:
    		LOG_INF("AWS_IOT_EVT_DISCONNECTED");
    		cloud_connected = false;
    		/* This may fail if the work item is already being processed,
    		 * but in such case, the next time the work handler is executed,
    		 * it will exit after checking the above flag and the work will
    		 * not be scheduled again.
    		 */
    		(void)k_work_cancel_delayable(&shadow_update_work);
    		k_work_schedule(&connect_work, K_NO_WAIT);
    		break;
    	case AWS_IOT_EVT_DATA_RECEIVED:
    		LOG_INF("AWS_IOT_EVT_DATA_RECEIVED");
    		print_received_data(evt->data.msg.ptr, evt->data.msg.topic.str,
    				    evt->data.msg.topic.len);
    		break;
    	case AWS_IOT_EVT_PUBACK:
    		LOG_INF("AWS_IOT_EVT_PUBACK, message ID: %d", evt->data.message_id);
    		break;
    	case AWS_IOT_EVT_FOTA_START:
    		LOG_INF("AWS_IOT_EVT_FOTA_START");
    		break;
    	case AWS_IOT_EVT_FOTA_ERASE_PENDING:
    		LOG_INF("AWS_IOT_EVT_FOTA_ERASE_PENDING");
    		LOG_INF("Disconnect LTE link or reboot");
    #if defined(CONFIG_NRF_MODEM_LIB)
    		err = lte_lc_offline();
    		if (err) {
    			LOG_ERR("Error disconnecting from LTE");
    		}
    #endif
    		break;
    	case AWS_IOT_EVT_FOTA_ERASE_DONE:
    		LOG_INF("AWS_FOTA_EVT_ERASE_DONE");
    		LOG_INF("Reconnecting the LTE link");
    #if defined(CONFIG_NRF_MODEM_LIB)
    		err = lte_lc_connect();
    		if (err) {
    			LOG_ERR("Error connecting to LTE");
    		}
    #endif
    		break;
    	case AWS_IOT_EVT_FOTA_DONE:
    		LOG_INF("AWS_IOT_EVT_FOTA_DONE");
    		LOG_INF("FOTA done, rebooting device");
    		aws_iot_disconnect();
    		sys_reboot(0);
    		break;
    	case AWS_IOT_EVT_FOTA_DL_PROGRESS:
    		LOG_INF("AWS_IOT_EVT_FOTA_DL_PROGRESS, (%d%%)", evt->data.fota_progress);
    	case AWS_IOT_EVT_ERROR:
    		LOG_INF("AWS_IOT_EVT_ERROR, %d", evt->data.err);
    		break;
    	case AWS_IOT_EVT_FOTA_ERROR:
    		LOG_INF("AWS_IOT_EVT_FOTA_ERROR");
    		break;
    	default:
    		LOG_WRN("Unknown AWS IoT event type: %d", evt->type);
    		break;
    	}
    }
    
    static void work_init(void)
    {
    	k_work_init_delayable(&shadow_update_work, shadow_update_work_fn);
    	k_work_init_delayable(&connect_work, connect_work_fn);
    	k_work_init(&shadow_update_version_work, shadow_update_version_work_fn);
    }
    
    #if defined(CONFIG_NRF_MODEM_LIB)
    static void lte_handler(const struct lte_lc_evt *const evt)
    {
    	switch (evt->type) {
    	case LTE_LC_EVT_NW_REG_STATUS:
    		if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
    		    (evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {
    			break;
    		}
    
    		LOG_INF("Network registration status: %s",
    			evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ?
    				"Connected - home network" :
    				"Connected - roaming");
    
    		k_sem_give(&lte_connected);
    		break;
    	case LTE_LC_EVT_PSM_UPDATE:
    		LOG_INF("PSM parameter update: TAU: %d, Active time: %d", evt->psm_cfg.tau,
    			evt->psm_cfg.active_time);
    		break;
    	case LTE_LC_EVT_EDRX_UPDATE: {
    		char log_buf[60];
    		ssize_t len;
    
    		len = snprintf(log_buf, sizeof(log_buf), "eDRX parameter update: eDRX: %f, PTW: %f",
    			       evt->edrx_cfg.edrx, evt->edrx_cfg.ptw);
    		if (len > 0) {
    			LOG_INF("%s", log_buf);
    		}
    		break;
    	}
    	case LTE_LC_EVT_RRC_UPDATE:
    		LOG_INF("RRC mode: %s",
    			evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ? "Connected" : "Idle");
    		break;
    	case LTE_LC_EVT_CELL_UPDATE:
    		LOG_INF("LTE cell changed: Cell ID: %d, Tracking area: %d", evt->cell.id,
    			evt->cell.tac);
    		break;
    	default:
    		break;
    	}
    }
    
    static void modem_configure(void)
    {
    	int err;
    
    	if (IS_ENABLED(CONFIG_LTE_AUTO_INIT_AND_CONNECT)) {
    		/* Do nothing, modem is already configured and LTE connected. */
    	} else {
    		err = lte_lc_init_and_connect_async(lte_handler);
    		if (err) {
    			LOG_ERR("Modem could not be configured, error: %d", err);
    			return;
    		}
    	}
    }
    
    static void nrf_modem_lib_dfu_handler(void)
    {
    	int err;
    
    	err = modem_lib_init_result;
    
    	switch (err)
    	{
    	case MODEM_DFU_RESULT_OK:
    		printk("Modem update suceeded, reboot\n");
    		sys_reboot(SYS_REBOOT_COLD);
    		break;
    	case MODEM_DFU_RESULT_UUID_ERROR:
    	case MODEM_DFU_RESULT_AUTH_ERROR:
    		printk("Modem update failed, error: %d\n", err);
    		printk("Modem will use old firmware\n");
    		sys_reboot(SYS_REBOOT_COLD);
    		break;
    	case MODEM_DFU_RESULT_HARDWARE_ERROR:
    	case MODEM_DFU_RESULT_INTERNAL_ERROR:
    		printk("Modem update malfunction, error: %d, reboot\n", err);
    		sys_reboot(SYS_REBOOT_COLD);
    		break;
    	default:
    		break;
    	}
    }
    #endif
    
    static int app_topics_subscribe(void)
    {
    	int err;
    	static char settingsString[20] = "/settings";
    	static char topicString[75];
    	strcpy(topicString, imei);
    	strcat(topicString, settingsString);
    	static char custom_topic_2[75] = "my-custom-topic/example_2";
    
    	const struct aws_iot_topic_data topics_list[APP_TOPICS_COUNT] = {
    		[0].str = topicString,
    		[0].len = strlen(topicString),
    		[1].str = custom_topic_2,
    		[1].len = strlen(custom_topic_2)
    	};
    
    	err = aws_iot_subscription_topics_add(topics_list, ARRAY_SIZE(topics_list));
    	if (err) {
    		LOG_ERR("aws_iot_subscription_topics_add, error: %d", err);
    	}
    
    	return err;
    }
    
    static void date_time_event_handler(const struct date_time_evt *evt)
    {
    	switch (evt->type) {
    	case DATE_TIME_OBTAINED_MODEM:
    		/* Fall through */
    	case DATE_TIME_OBTAINED_NTP:
    		/* Fall through */
    	case DATE_TIME_OBTAINED_EXT:
    		LOG_INF("Date time obtained");
    		k_sem_give(&date_time_obtained);
    
    		/* De-register handler. At this point the sample will have
    		 * date time to depend on indefinitely until a reboot occurs.
    		 */
    		date_time_register_handler(NULL);
    		break;
    	case DATE_TIME_NOT_OBTAINED:
    		LOG_INF("DATE_TIME_NOT_OBTAINED");
    		break;
    	default:
    		LOG_ERR("Unknown event: %d", evt->type);
    		break;
    	}
    }
    
    void main(void)
    {
    	int err;
    
    	LOG_INF("The AWS IoT sample started, version: %s", CONFIG_APP_VERSION);
    
    	cJSON_Init();
    
    #if defined(CONFIG_NRF_MODEM_LIB)
    	nrf_modem_lib_dfu_handler();
    #endif
    
    	err = aws_iot_init(NULL, aws_iot_event_handler);
    	if (err) {
    		LOG_ERR("AWS IoT library could not be initialized, error: %d", err);
    	}
    
    	/** Subscribe to customizable non-shadow specific topics
    	 *  to AWS IoT backend.
    	 */
    	err = app_topics_subscribe();
    	if (err) {
    		LOG_ERR("Adding application specific topics failed, error: %d", err);
    	}
    
    	work_init();
    #if defined(CONFIG_NRF_MODEM_LIB)
    	modem_configure();
    
    	err = modem_info_init();
    	if (err) {
    		LOG_ERR("Failed initializing modem info module, error: %d", err);
    	}
    	modem_info_string_get(MODEM_INFO_IMEI, imei, sizeof(imei));
    	printk("Modem IMEI: %s \n", imei);
    
    	k_sem_take(&lte_connected, K_FOREVER);
    #endif
    
    	/* Trigger a date time update. The date_time API is used to timestamp data that is sent
    	 * to AWS IoT.
    	 */
    	date_time_update_async(date_time_event_handler);
    
    	/* Postpone connecting to AWS IoT until date time has been obtained. */
    	k_sem_take(&date_time_obtained, K_FOREVER);
    	k_work_schedule(&connect_work, K_NO_WAIT);
    }
    

    prj.conf (*** changed) 

    #
    # Copyright (c) 2020 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    # General config
    CONFIG_NCS_SAMPLES_DEFAULTS=y
    CONFIG_REBOOT=y
    
    # NEWLIB C
    CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
    
    # Log
    CONFIG_LOG=y
    
    # Network
    CONFIG_NETWORKING=y
    CONFIG_NET_NATIVE=n
    
    # LTE link control
    CONFIG_LTE_LINK_CONTROL=y
    CONFIG_LTE_NETWORK_MODE_LTE_M=y
    CONFIG_LTE_AUTO_INIT_AND_CONNECT=n
    
    # Modem library
    CONFIG_NRF_MODEM_LIB=y
    
    # AT Host
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_AT_HOST_LIBRARY=n
    
    # AWS IoT library
    CONFIG_AWS_IOT=y
    CONFIG_AWS_IOT_CLIENT_ID_STATIC="351358815046***"
    CONFIG_AWS_IOT_BROKER_HOST_NAME="***.iot.eu-central-1.amazonaws.com"
    CONFIG_AWS_IOT_SEC_TAG=***
    CONFIG_AWS_IOT_APP_SUBSCRIPTION_LIST_COUNT=2
    CONFIG_AWS_IOT_TOPIC_UPDATE_DELTA_SUBSCRIBE=y
    CONFIG_AWS_IOT_LAST_WILL=y
    CONFIG_AWS_IOT_TOPIC_GET_ACCEPTED_SUBSCRIBE=y
    CONFIG_AWS_IOT_TOPIC_GET_REJECTED_SUBSCRIBE=y
    
    # MQTT - Maximum MQTT keepalive timeout specified by AWS IoT Core
    CONFIG_MQTT_KEEPALIVE=1200
    
    # Date Time library
    CONFIG_DATE_TIME=y
    
    # Modem information
    CONFIG_MODEM_INFO=y
    
    # Heap and stacks
    CONFIG_HEAP_MEM_POOL_SIZE=8192
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
    
    # MCUBOOT
    CONFIG_BOOTLOADER_MCUBOOT=y
    CONFIG_MCUBOOT_IMG_MANAGER=y
    
    # Image manager
    CONFIG_IMG_MANAGER=y
    CONFIG_FLASH=y
    CONFIG_IMG_ERASE_PROGRESSIVELY=y
    
    # AWS FOTA
    CONFIG_AWS_FOTA=y
    CONFIG_FOTA_DOWNLOAD=y
    CONFIG_DFU_TARGET=y
    
    # CJSON
    CONFIG_CJSON_LIB=y
    
    # Download client (needed by AWS FOTA)
    CONFIG_DOWNLOAD_CLIENT=y
    CONFIG_DOWNLOAD_CLIENT_STACK_SIZE=4096
    
    ## PSM
    CONFIG_LTE_PSM_REQ_RPTAU="00100001"
    CONFIG_LTE_PSM_REQ_RAT="00000000"

    Seems not to work for me. This is the output: 

    13:02:12:301 -> *** Booting Zephyr OS build v3.1.99-ncs1-1  ***
    13:02:12:306 -> I: The AWS IoT sample started, version: v1.0.0
    13:02:12:354 -> Modem IMEI: 351358815046***
    13:02:39:360 -> I: LTE cell changed: Cell ID: 6712589, Tracking area: 34101
    13:02:39:408 -> I: RRC mode: Connected
    13:02:41:089 -> I: Network registration status: Connected - roaming
    13:02:41:096 -> I: PSM parameter update: TAU: 3240, Active time: -1
    13:02:41:101 -> I: Date time obtained
    13:02:41:101 -> I: Next connection retry in 30 seconds
    13:02:41:116 -> I: AWS_IOT_EVT_CONNECTING
    13:02:44:647 -> I: AWS_IOT_EVT_CONNECTED
    13:02:44:647 -> I: Persistent session enabled
    13:02:44:647 -> I: Publishing: {
    13:02:44:652 ->         "state":        {
    13:02:44:652 ->                 "reported":     {
    13:02:44:652 ->                         "app_version":  "v1.0.0",
    13:02:44:658 ->                         "batv": 3316,
    13:02:44:658 ->                         "ts":   1680087764074
    13:02:44:658 ->                 }
    13:02:44:658 ->         }
    13:02:44:658 -> } to AWS IoT broker
    13:02:44:673 -> I: AWS_IOT_EVT_READY
    13:02:44:977 -> I: AWS_IOT_EVT_DATA_RECEIVED
    13:02:45:005 -> E: Failed to print JSON object
    13:02:45:005 -> I: AWS_IOT_EVT_PUBACK, message ID: 30604
    13:02:57:683 -> I: RRC mode: Idle
    13:03:44:651 -> I: Publishing: {
    13:03:44:657 ->         "state":        {
    13:03:44:657 ->                 "reported":     {
    13:03:44:657 ->                         "batv": 3312,
    13:03:44:657 ->                         "ts":   1680087824074
    13:03:44:669 ->                 }
    13:03:44:669 ->         }
    13:03:44:669 -> } to AWS IoT broker
    13:03:44:669 -> I: Next data publication in 60 seconds
    13:03:44:752 -> I: RRC mode: Connected

    This is the AWS console MQTT page

    To be clear, the other (default) topic works fine:

    13:40:33:455 -> I: RRC mode: Connected
    13:40:33:597 -> I: AWS_IOT_EVT_DATA_RECEIVED
    13:40:33:597 -> I: Data received from AWS IoT console: Topic: my-custom-topic/example_2 Message: {
    13:40:33:603 ->         "message":      "Hello from AWS IoT console"
    13:40:33:618 -> }

  • Thanks for sharing. I am able to reproduce with nRF Connect SDK v2.1.2. Had to rearrange some of the calls, i.e. moved the following to after reading IMEI

    /** Subscribe to customizable non-shadow specific topics
     *  to AWS IoT backend.
     */
    err = app_topics_subscribe();
    if (err) {
    	LOG_ERR("Adding application specific topics failed, error: %d", err);
    }

    Here is my output:

    *** Booting Zephyr OS build v3.2.99-ncs2 ***
    I: Starting bootloader
    I: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Swap type: none
    I: Bootloader chainload address offset: 0x10000
    I: Jumping to the first image slot
    *** Booting Zephyr OS build v3.2.99-ncs2 ***
    I: The AWS IoT sample started, version: v1.0.0
    
    I: Modem IMEI: 350457791991456
    
    +CEREG: 2,"08FF","0212410C",7
    I: LTE cell changed: Cell ID: 34750732, Tracking area: 2303
    +CSCON: 1
    
    I: RRC mode: Connected
    +CEREG: 1,"08FF","0212410C",7,,,"11100000","11100000"
    I: Network registration status: Connected - home network
    I: SI: PSM parameter update: TAU: 3240, Active time: -1
    ent 350457791991456/settings
    I: Sent 350457791991456
    I: Sen%XTIME: "80","32300321716380","01"
    t /settings
    I: Sent my-custom-topic/example_2
    I: Date time obtained
    I: Next connection retry in 30 seconds
    I: AWS_IOT_EVT_CONNECTING
    I: AWS_IOT_EVT_CONNECTED
    
    I: Persistent session enabled
    I: Publishing: {
    "state":{
    "reported":{
    "app_version":"v1.0.0",
    "batv":5117,
    "ts":1680178660424
    }
    }
    } to AWS IoT broker
    I: AWS_IOT_EVT_READY
    +CEREG: 1,"08FF","0212410C",7,,,"00100001","00000110"
    
    I: PSM parameter update: TAU: 3600, Active time: 60
    I: AWS_IOT_EVT_DATA_RECEIVED
    
    I: Data received from AWS IoT console: Topic: $aws/things/350457791991456/shadow/get/accepted Message: {
    "state":{
    "reported":{
    "app_version":"v1.0.0",
    "batv":5117,
    "ts":1680178660424
    }
    },
    
    "metadata":{
    "reported":{
    "app_version":{
    "timestamp":1680178660
    },
    "batv":{
    "timestamp":1680178660
    },
    "ts":{
    "timestamp":1680178660
    }
    }
    },
    "version":272,
    "timestamp":1680178660
    }
    I: AWS_IOT_EVT_PUBACK, message ID: 22170
    +CSCON: 0
    
    I: RRC mode: Idle
    +CEREG: 1,"08FF","0209E216",7,,,"00100001","00000110"
    I: LTE cell changed: Cell ID: 34202134, Tracking area: 2303
    +CSCON: 1
    I: RRC mode: Connected
    I: AWS_IOT_EVT_DATA_RECEIVED
    I: Data received from AWS IoT console: Topic: my-custom-topic/example_2 Message: {
    "message":"Hello from AWS IoT console - my-custom-topic/example_2"
    }
    +CSCON: 0
    I: RRC mode: Idle
    


    I am able to subscribe to custom_topic_2, but not topicString

Related