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

Parents
  • 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

Reply
  • 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

Children
No Data
Related