nRF9160 resets with aws_iot_send

If you improve the AWS_IoT sample and send a message to Device Shadow, the nRF9160 will reset.

I am using nRF9160DK.

I got the debug logs, but couldn't figure out the cause.

The source code and execution status are attached below.

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>
#include <dk_buttons_and_leds.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>
#if defined(CONFIG_AWS_IOT_SAMPLE_DEVICE_ID_USE_HW_ID)
#include <hw_id.h>
#endif


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            shadow_update_work;
static struct k_work            reported_work;
static struct k_work_delayable  connect_work;

static bool cloud_connected;
static bool ledState = false;

static K_SEM_DEFINE( lte_connected, 0, 1 );

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 report ) {

	int err;
	char *message;

	cJSON *root_obj     = cJSON_CreateObject( );
	cJSON *state_obj    = cJSON_CreateObject( );
	cJSON *reported_obj = cJSON_CreateObject( );
	cJSON *desired_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 );
        cJSON_Delete( desired_obj );
		err = -ENOMEM;
		return err;
	}

    if ( ledState ) {
        err += json_add_str( reported_obj, "led", "ON" );
        if ( !report )  err += json_add_str( desired_obj, "led", "ON" );
    } else {
        err += json_add_str( reported_obj, "led", "OFF" );
        if ( !report )  err += json_add_str( desired_obj, "led", "OFF" );
    }
	err += json_add_obj( state_obj, "reported", reported_obj );
    if ( !report ) err += json_add_obj( state_obj, "desired", desired_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 );
    cJSON_Delete( state_obj );
    cJSON_Delete( reported_obj );
    cJSON_Delete( desired_obj );
	return err;
}

static void connect_work_fn( struct k_work *work ) {

	int err;

    // 出力できていたら終了
	if ( cloud_connected )  return;

    LOG_INF( "Start AWS IoT Connect" );
	err = aws_iot_connect( NULL );
	if ( err ) LOG_ERR("aws_iot_connect, error: %d", err);

	LOG_INF( "Next connection retry in %d seconds", CONFIG_AWS_IOT_SAMPLE_CONNECTION_RETRY_TIMEOUT_SECONDS );

	k_work_schedule( &connect_work, K_SECONDS( CONFIG_AWS_IOT_SAMPLE_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);
}

static void reported_work_fn( struct k_work *work ) {

	int err;

    // 接続できていなかったら終了
	if ( !cloud_connected ) return;

	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 ) {

    // subscribe受診時の処理

    if ( strcmp( topic, "$aws/things/cts-lte-sample/shadow/update/delta" ) != 0 )   return;

	char *str = NULL;
	cJSON *root_obj = NULL;
    cJSON *state_obj = NULL;
    cJSON *led_obj = NULL;

	LOG_INF( "Data received from AWS IoT console: Topic: %s", topic );

	root_obj = cJSON_Parse( buf );
	str = cJSON_Print( root_obj );
	if ( str == NULL ) {
		LOG_ERR( "Failed to print JSON object" );
		goto clean_exit;
	}

	LOG_INF( "Message: %s", str );

    state_obj = cJSON_GetObjectItem( root_obj, "state" );
    led_obj = cJSON_GetObjectItem( state_obj, "led" );
	if (( root_obj == NULL ) || ( state_obj == NULL ) || ( led_obj == NULL )) {
		LOG_ERR( "cJSON Parse failure" );
		return;
	}
    ledState = strcmp( cJSON_GetStringValue( led_obj ), "ON" ) == 0;
    dk_set_led( DK_LED1, ledState );
    k_work_submit( &reported_work );

	cJSON_FreeString( str );

clean_exit:
	cJSON_Delete( root_obj );
    cJSON_Delete( state_obj );
    cJSON_Delete( led_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;
		( void )k_work_cancel_delayable( &connect_work );

        dk_set_led( DK_LED2, true );

		k_work_submit( &shadow_update_work );

#if defined( CONFIG_NRF_MODEM_LIB )
        LOG_INF( "Setting Power Saving Mode" );
		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;
		k_work_schedule( &connect_work, K_NO_WAIT );
        dk_set_led( DK_LED2, false );
		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_ERROR:
		LOG_INF( "AWS_IOT_EVT_ERROR, %d", evt->data.err );
		break;

	default:
		LOG_WRN( "Unknown AWS IoT event type: %d", evt->type );
		break;
	}
}

static void work_init( void ) {

	k_work_init( &shadow_update_work, shadow_update_work_fn );
    k_work_init( &reported_work, reported_work_fn );
	k_work_init_delayable( &connect_work, connect_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;
	}
}

#endif

// static int app_topics_subscribe( void ) {

// 	int err;
// 	static char custom_topic[75] = "my-custom-topic/example";
// 	static char custom_topic_2[75] = "my-custom-topic/example_2";

// 	const struct aws_iot_topic_data topics_list[ APP_TOPICS_COUNT ] = {
// 		[0].str = custom_topic,
// 		[0].len = strlen(custom_topic),
// 		[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 button_handler( uint32_t button_state, uint32_t has_changed ) {

	switch ( has_changed ) {
        case DK_BTN1_MSK:
            if ( button_state & DK_BTN1_MSK ) {
                // ボタンの変化に伴ってメッセージを送信する
                ledState = !ledState;
                dk_set_led( DK_LED1, ledState );
                k_work_submit( &shadow_update_work );
            }
            break;
	}
}

int main( void ) {

	int err;

	LOG_INF( "The AWS IoT sample started, version: %s", CONFIG_AWS_IOT_SAMPLE_APP_VERSION );

	cJSON_Init( );

    if ( dk_leds_init( ) != 0 ) LOG_ERR( "Failed to initialize the LED library" );
    if ( dk_buttons_init( button_handler ) != 0 ) LOG_ERR( "Failed to initialize the button library" );

#if defined( CONFIG_NRF_MODEM_LIB )
	err = nrf_modem_lib_init( );
	if ( err ) {
		LOG_ERR( "Modem library initialization failed, error: %d", err );
		return 0;
	}

#endif

    LOG_INF( "AWS IoT Init" );
	err = aws_iot_init( NULL, aws_iot_event_handler );

	if ( err ) LOG_ERR("AWS IoT library could not be initialized, error: %d", err );

	// err = app_topics_subscribe( );
	// if ( err )  LOG_ERR( "Adding application specific topics failed, error: %d", err );

    LOG_INF( "Work Init" );
	work_init( );

#if defined( CONFIG_NRF_MODEM_LIB )

    LOG_INF( "Start LTE Connect" );
	err = lte_lc_init_and_connect_async( lte_handler );
	if ( err ) {
		LOG_ERR( "Modem could not be configured, error: %d", err );
		return 0;
	}

	err = modem_info_init( );
	if ( err ) LOG_ERR( "Failed initializing modem info module, error: %d", err );

	k_sem_take( &lte_connected, K_FOREVER );
#endif

	k_work_schedule( &connect_work, K_NO_WAIT );

	return 0;
}



prj.conf

CONFIG_NCS_SAMPLES_DEFAULTS=y
CONFIG_REBOOT=y

# Button and LED support
CONFIG_DK_LIBRARY=y

# NEWLIB C
CONFIG_NEWLIB_LIBC=y
CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y

# Log
CONFIG_LOG=y
# CONFIG_AWS_IOT_SAMPLE_LOG_LEVEL_INF=y
CONFIG_LOG_DEFAULT_LEVEL=4
CONFIG_AWS_IOT_SAMPLE_LOG_LEVEL_DBG=y

# Network
CONFIG_NETWORKING=y
CONFIG_NET_NATIVE=n

# LTE link control
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_NETWORK_MODE_LTE_M=y

# Modem library
CONFIG_NRF_MODEM_LIB=y

# AT Host
CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_AT_HOST_LIBRARY=y

# AWS IoT library
CONFIG_AWS_IOT=y
CONFIG_AWS_IOT_CLIENT_ID_STATIC="cts-lte-sample"
CONFIG_AWS_IOT_BROKER_HOST_NAME="a2dv87z16ohdau-ats.iot.ap-northeast-1.amazonaws.com"
CONFIG_AWS_IOT_SEC_TAG=24
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

# Modem information
CONFIG_MODEM_INFO=y

# Heap and stacks
CONFIG_HEAP_MEM_POOL_SIZE=16384
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096

# CJSON
CONFIG_CJSON_LIB=y

log(Excerpt)

*** Booting Zephyr OS build v3.3.99-ncs1-1 ***
I: The AWS IoT sample started, version: v1.0.0
I: AWS IoT Init
I: Work Init
I: Start LTE Connect
+CEREG: 2,"63E3","06F12505",7
I: LTE cell changed: Cell ID: 116466949, Tracking area: 25571
+CSCON: 1
I: RRC mode: Connected
+CEREG: 5,"63E3","06F12505",7,,,"11100000","11100000"
I: Network registration status: Connected - roaming
I: PSM parameter update: TAU: 3240, Active time: -1
I: Start AWS IoT Connect
I: Next connection retry in 30 seconds
I: AWS_IOT_EVT_CONNECTING
D: IPv4 Address found 52.196.86.12
D: Using send socket timeout of 60 seconds
D: AWS IoT broker connection request sent
D: MQTT client connected!
I: AWS_IOT_EVT_CONNECTED
I: Publishing: {
        "state":        {
                "reported":     {
                        "led":  "OFF"
                },
                "desired":      {
                        "led":  "OFF"
                }
        }
} to AWS IoT broker
D: Using message ID 35279 set by the library
D: Publishing to topic: $aws/things/cts-lte-sample/shadow/update
I: Setting Po*** Booting Zephyr OS build v3.3.99-ncs1-1 ***
I: The AWS IoT sample started, version: v1.0.0
I: AWS IoT Init
I: Work Init
I: Start LTE Connect

  • Hi Nobumasa,

    I just read your codes, and suspect that you may need to add some delay time between "k_work_submit( &shadow_update_work );" and  "Setting Power Saving Mode".

    I suggest you keep shadow_update_work defined as k_work_delayable and use k_work_schedule( &shadow_update_work, K_NO_WAIT ); if you want and can run this task immediately.

    Please provide the NCS and MFW versions if you need more help.

    Best regards,

    Charlie

  • Thank you for your reply.

    As you pointed out, I changed "k_work_submit( &shadow_update_work );" to "k_work_schedule( &shadow_update_work, K_NO_WAIT );", but the result did not change.

    I also tried "k_work_schedule( &shadow_update_work, K_MSEC( 1000 ));" but it was the same.

    I also thought that the cause was that a shadow get request was being sent when connecting to AWS IoT, so I added the following settings. However, the result was the same.

    The MFW and NCS versions I'm using are shown below.
    NCS:Ver2.5.0
    MFW:Ver1.3.5

    Is there anything else you can think of?
    thank you.

    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>
    #include <dk_buttons_and_leds.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>
    #if defined(CONFIG_AWS_IOT_SAMPLE_DEVICE_ID_USE_HW_ID)
    #include <hw_id.h>
    #endif
    
    
    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  reported_work;
    static struct k_work_delayable  connect_work;
    
    static bool cloud_connected;
    static bool ledState = false;
    
    static K_SEM_DEFINE( lte_connected, 0, 1 );
    
    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 report ) {
    
    	int err;
    	char *message;
    
    	cJSON *root_obj     = cJSON_CreateObject( );
    	cJSON *state_obj    = cJSON_CreateObject( );
    	cJSON *reported_obj = cJSON_CreateObject( );
    	cJSON *desired_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 );
            cJSON_Delete( desired_obj );
    		err = -ENOMEM;
    		return err;
    	}
    
        if ( ledState ) {
            err += json_add_str( reported_obj, "led", "ON" );
            if ( !report )  err += json_add_str( desired_obj, "led", "ON" );
        } else {
            err += json_add_str( reported_obj, "led", "OFF" );
            if ( !report )  err += json_add_str( desired_obj, "led", "OFF" );
        }
    	err += json_add_obj( state_obj, "reported", reported_obj );
        if ( !report ) err += json_add_obj( state_obj, "desired", desired_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 );
        cJSON_Delete( state_obj );
        cJSON_Delete( reported_obj );
        cJSON_Delete( desired_obj );
    	return err;
    }
    
    static void connect_work_fn( struct k_work *work ) {
    
    	int err;
    
        // 出力できていたら終了
    	if ( cloud_connected )  return;
    
        LOG_INF( "Start AWS IoT Connect" );
    	err = aws_iot_connect( NULL );
    	if ( err ) LOG_ERR("aws_iot_connect, error: %d", err);
    
    	LOG_INF( "Next connection retry in %d seconds", CONFIG_AWS_IOT_SAMPLE_CONNECTION_RETRY_TIMEOUT_SECONDS );
    
    	k_work_schedule( &connect_work, K_SECONDS( CONFIG_AWS_IOT_SAMPLE_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);
    }
    
    static void reported_work_fn( struct k_work *work ) {
    
    	int err;
    
        // 接続できていなかったら終了
    	if ( !cloud_connected ) return;
    
    	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 ) {
    
        // subscribe受診時の処理
    
        if ( strcmp( topic, "$aws/things/cts-lte-sample/shadow/update/delta" ) != 0 )   return;
    
    	char *str = NULL;
    	cJSON *root_obj = NULL;
        cJSON *state_obj = NULL;
        cJSON *led_obj = NULL;
    
    	LOG_INF( "Data received from AWS IoT console: Topic: %s", topic );
    
    	root_obj = cJSON_Parse( buf );
    	str = cJSON_Print( root_obj );
    	if ( str == NULL ) {
    		LOG_ERR( "Failed to print JSON object" );
    		goto clean_exit;
    	}
    
    	LOG_INF( "Message: %s", str );
    
        state_obj = cJSON_GetObjectItem( root_obj, "state" );
        led_obj = cJSON_GetObjectItem( state_obj, "led" );
    	if (( root_obj == NULL ) || ( state_obj == NULL ) || ( led_obj == NULL )) {
    		LOG_ERR( "cJSON Parse failure" );
    		return;
    	}
        ledState = strcmp( cJSON_GetStringValue( led_obj ), "ON" ) == 0;
        dk_set_led( DK_LED1, ledState );
        k_work_schedule( &reported_work, K_NO_WAIT );
    
    	cJSON_FreeString( str );
    
    clean_exit:
    	cJSON_Delete( root_obj );
        cJSON_Delete( state_obj );
        cJSON_Delete( led_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;
    		( void )k_work_cancel_delayable( &connect_work );
    
            dk_set_led( DK_LED2, true );
    
    		k_work_schedule( &shadow_update_work, K_MSEC( 1000 ));
    
    #if defined( CONFIG_NRF_MODEM_LIB )
            LOG_INF( "Setting Power Saving Mode" );
    		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;
    		k_work_schedule( &connect_work, K_NO_WAIT );
            dk_set_led( DK_LED2, false );
    		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_ERROR:
    		LOG_INF( "AWS_IOT_EVT_ERROR, %d", evt->data.err );
    		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( &reported_work, reported_work_fn );
    	k_work_init_delayable( &connect_work, connect_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;
    	}
    }
    
    #endif
    
    // static int app_topics_subscribe( void ) {
    
    // 	int err;
    // 	static char custom_topic[75] = "my-custom-topic/example";
    // 	static char custom_topic_2[75] = "my-custom-topic/example_2";
    
    // 	const struct aws_iot_topic_data topics_list[ APP_TOPICS_COUNT ] = {
    // 		[0].str = custom_topic,
    // 		[0].len = strlen(custom_topic),
    // 		[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 button_handler( uint32_t button_state, uint32_t has_changed ) {
    
    	switch ( has_changed ) {
            case DK_BTN1_MSK:
                if ( button_state & DK_BTN1_MSK ) {
                    // ボタンの変化に伴ってメッセージを送信する
                    ledState = !ledState;
                    dk_set_led( DK_LED1, ledState );
                    k_work_schedule( &shadow_update_work, K_NO_WAIT );
                }
                break;
    	}
    }
    
    int main( void ) {
    
    	int err;
    
    	LOG_INF( "The AWS IoT sample started, version: %s", CONFIG_AWS_IOT_SAMPLE_APP_VERSION );
    
    	cJSON_Init( );
    
        if ( dk_leds_init( ) != 0 ) LOG_ERR( "Failed to initialize the LED library" );
        if ( dk_buttons_init( button_handler ) != 0 ) LOG_ERR( "Failed to initialize the button library" );
    
    #if defined( CONFIG_NRF_MODEM_LIB )
    	err = nrf_modem_lib_init( );
    	if ( err ) {
    		LOG_ERR( "Modem library initialization failed, error: %d", err );
    		return 0;
    	}
    
    #endif
    
        LOG_INF( "AWS IoT Init" );
    	err = aws_iot_init( NULL, aws_iot_event_handler );
    
    	if ( err ) LOG_ERR("AWS IoT library could not be initialized, error: %d", err );
    
    	// err = app_topics_subscribe( );
    	// if ( err )  LOG_ERR( "Adding application specific topics failed, error: %d", err );
    
        LOG_INF( "Work Init" );
    	work_init( );
    
    #if defined( CONFIG_NRF_MODEM_LIB )
    
        LOG_INF( "Start LTE Connect" );
    	err = lte_lc_init_and_connect_async( lte_handler );
    	if ( err ) {
    		LOG_ERR( "Modem could not be configured, error: %d", err );
    		return 0;
    	}
    
    	err = modem_info_init( );
    	if ( err ) LOG_ERR( "Failed initializing modem info module, error: %d", err );
    
    	k_sem_take( &lte_connected, K_FOREVER );
    #endif
    
    	k_work_schedule( &connect_work, K_NO_WAIT );
    
    	return 0;
    }
    

    prj.conf

    #
    # Copyright (c) 2020 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    # General config
    CONFIG_NCS_SAMPLES_DEFAULTS=y
    CONFIG_REBOOT=y
    
    # Button and LED support
    CONFIG_DK_LIBRARY=y
    
    # NEWLIB C
    CONFIG_NEWLIB_LIBC=y
    CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y
    
    # Log
    CONFIG_LOG=y
    CONFIG_AWS_IOT_LOG_LEVEL_DBG=y
    # CONFIG_AWS_IOT_SAMPLE_LOG_LEVEL_DBG=y
    
    # Network
    CONFIG_NETWORKING=y
    CONFIG_NET_NATIVE=n
    
    # LTE link control
    CONFIG_LTE_LINK_CONTROL=y
    CONFIG_LTE_NETWORK_MODE_LTE_M=y
    
    # Modem library
    CONFIG_NRF_MODEM_LIB=y
    
    # AT Host
    CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_AT_HOST_LIBRARY=y
    
    # AWS IoT library
    CONFIG_AWS_IOT=y
    CONFIG_AWS_IOT_CLIENT_ID_STATIC="cts-lte-sample"
    CONFIG_AWS_IOT_BROKER_HOST_NAME="a2dv87z16ohdau-ats.iot.ap-northeast-1.amazonaws.com"
    CONFIG_AWS_IOT_SEC_TAG=24
    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
    CONFIG_AWS_IOT_AUTO_DEVICE_SHADOW_REQUEST=n
    
    # MQTT - Maximum MQTT keepalive timeout specified by AWS IoT Core
    CONFIG_MQTT_KEEPALIVE=1200
    
    # Modem information
    CONFIG_MODEM_INFO=y
    
    # Heap and stacks
    CONFIG_HEAP_MEM_POOL_SIZE=16384
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
    
    # CJSON
    CONFIG_CJSON_LIB=y
    

    log

    *** Booting nRF Connect SDK v2.5.0 ***
    I: The AWS IoT sample started, version: v1.0.0
    I: AWS IoT Init
    I: Work Init
    I: Start LTE Connect
    +CEREG: 2,"63E3","06F12505",7
    I: LTE cell changed: Cell ID: 116466949, Tracking area: 25571
    +CSCON: 1
    I: RRC mode: Connected
    +CEREG: 5,"63E3","06F12505",7,,,"11100000","11100000"
    I: Network registration status: Connected - roaming
    I: PSM parameter update: TAU: 3240, Active time: -1
    I: Start AWS IoT Connect
    I: Next connection retry in 30 seconds
    I: AWS_IOT_EVT_CONNECTING
    D: IPv4 Address found 3.114.143.109
    D: Using send socket timeout of 60 seconds
    D: AWS IoT broker connection request sent
    D: MQTT client connected!
    I: AWS_IOT_EVT_CONNECTED
    I: Setting Power Saving Mode
    I: AWS_IOT_EVT_READY
    +CEREG: 5,"63E3","06F12505",7,,,"00011110","11100000"
    I: PSM parameter update: TAU: 3240, Active time: 60
    I: Publishing: {
            "state":        {
                    "reported":     {
                            "led":  "OFF"
                    },
                    "desired":      {
                            "led":  "OFF"
                    }
            }
    } to AWS IoT broker
    D: Using message ID 22087 set by the library
    D: Publishing to topic: $aws/things/cts-lte-sample/shadow/update
    *** Booting nRF Connect SDK v2.5.0 ***
    I: The AWS IoT sample started, version: v1.0.0
    I: AWS IoT Init
    I: Work Init
    I: Start LTE Connect

  • Hi Nobumasa,

    I feel your project is modified from NCS\v2.4.2\nrf\samples\nrf9160\aws_iot originally, is this correct?

    The AWS iot sample in NCS\v2.5.0\nrf\samples\net\aws_iot has a big modification to also fit for Wi-Fi connection. I suggest we try to make it work with the original NCS version first in case some other compatibility issues happen.

    Best regards,

    Charlie

  • Hi,

    When child object is added to a parent object it is only needed to delete the root object to free up all the memory. The reason why the device resets is because the sample tries to delete an associated child node after its memory has been freed via the root.

    sample:126

    cleanup:

            cJSON_Delete( root_obj );

            remove -> cJSON_Delete( state_obj );

            remove -> cJSON_Delete( reported_obj );

            remove -> cJSON_Delete( desired_obj );

            return err;

    }

    Best regards,

    Charlie

  • Hi Charlie,

    Thank you for your reply.

    >> I feel your project is modified from NCS\v2.4.2\nrf\samples\nrf9160\aws_iot originally, is this correct?

    As you pointed out, the project was generated with Ver2.4.2 and changed to Ver2.5.0 midway through.

    After changing cJSON to delete only the root object, I was able to execute it successfully.

    Thank you very much !!

Related