This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Last will message does not update attribute on cloud side on disconnection

Hello,

I'm currently looking at using a last will message that updates an attribute on the cloud if the device disconnects from the broker. The broker and client agrees on the message on initial connection handshake. The attribute I want to change for now is "connected", which is set to true by publishing from the device when it connects, and then it should be false again if it disconnects, set and agreed on by the last will message.

I cannot use modem trace logs since UARTE1 is in use by an external device, but I do have LOG_DBGs from mqtt and aws_iot libraries. Firstly, we can see it parses the last will message correctly on initial connection:

[00:00:05.294,036] <dbg> net_mqtt_enc.pack_utf8_str: (0x20016d28): >> str_size:0000000a cur:0x2002144d, end:0x20021c3e
[00:00:05.294,036] <dbg> net_mqtt_enc.pack_uint16: (0x20016d28): >> val:0008 cur:0x2002144d, end:0x20021c3e
[00:00:05.294,067] <dbg> net_mqtt_enc: Encoding Will Topic.
                                       74 63 78 6e 2f 74 68 69  6e 67 73 2f 30 30 30 30 |tcxn/thi ngs/0000
                                       30 30 31 36 2f 73 68 61  64 6f 77 2f 75 70 64 61 |0016/sha dow/upda
                                       74 65                                            |te
[00:00:05.294,067] <dbg> net_mqtt_enc.pack_utf8_str: (0x20016d28): >> str_size:00000024 cur:0x20021457, end:0x20021c3e
[00:00:05.294,097] <dbg> net_mqtt_enc.pack_uint16: (0x20016d28): >> val:0022 cur:0x20021457, end:0x20021c3e
[00:00:05.294,097] <dbg> net_mqtt_enc: Encoding Will Message.
                                       7b 22 73 74 61 74 65 22  3a 7b 22 72 65 70 6f 72 |{"state" :{"repor
                                       74 65 64 22 3a 7b 22 63  6f 6e 6e 65 63 74 65 64 |ted":{"c onnected
                                       22 3a 22 66 61 6c 73 65  22 7d 7d 7d             |":"false "}}}
[00:00:05.294,128] <dbg> net_mqtt_enc.pack_utf8_str: (0x20016d28): >> str_size:0000002e cur:0x2002147b, end:0x20021c3e
[00:00:05.294,128] <dbg> net_mqtt_enc.pack_uint16: (0x20016d28): >> val:002c cur:0x2002147b, end:0x20021c3e
[00:00:05.294,189] <dbg> net_mqtt_enc.mqtt_encode_fixed_header: (0x20016d28): << msg type:0x10 length:0x00000066
[00:00:05.294,219] <dbg> net_mqtt_enc.packet_length_encode: (0x20016d28): >> length:0x00000066 cur:(nil), end:(nil)
[00:00:05.294,250] <dbg> net_mqtt_enc.mqtt_encode_fixed_header: (0x20016d28): Fixed header length = 02
[00:00:05.294,281] <dbg> net_mqtt_enc.pack_uint8: (0x20016d28): >> val:10 cur:0x20021441, end:0x20021c3e
[00:00:05.294,311] <dbg> net_mqtt_enc.packet_length_encode: (0x20016d28): >> length:0x00000066 cur:0x20021442, end:0x20021c3e
[00:00:05.310,028] <dbg> net_mqtt.client_connect: (0x20016d28): Connect completed

Then, the device sets connected to true on given topic:

[00:00:05.989,593] <inf> cloud_api_aws: Publishing: {"state":{"reported":{"connected":"true"}}} to AWS IoT broker topic tcxn/things/00000016/shadow/update
[00:00:05.989,624] <dbg> aws_iot.aws_iot_send: Publishing to topic: tcxn/things/00000016/shadow/update
[00:00:05.989,624] <dbg> net_mqtt.mqtt_publish: (0x20014f98): [CID 0x200187a0]:[State 0x06]: >> Topic size 0x00000022, Data size 0x0000002b
[00:00:05.989,868] <dbg> net_mqtt_enc.pack_utf8_str: (0x20014f98): >> str_size:00000024 cur:0x20021443, end:0x20021c3e
[00:00:05.989,898] <dbg> net_mqtt_enc.pack_uint16: (0x20014f98): >> val:0022 cur:0x20021443, end:0x20021c3e
[00:00:05.989,929] <dbg> net_mqtt_enc.pack_uint16: (0x20014f98): >> val:feab cur:0x20021467, end:0x20021c3e
[00:00:05.989,929] <dbg> net_mqtt_enc.mqtt_encode_fixed_header: (0x20014f98): << msg type:0x32 length:0x00000051
[00:00:05.989,959] <dbg> net_mqtt_enc.packet_length_encode: (0x20014f98): >> length:0x00000051 cur:(nil), end:(nil)
[00:00:05.989,959] <dbg> net_mqtt_enc.mqtt_encode_fixed_header: (0x20014f98): Fixed header length = 02
[00:00:05.989,990] <dbg> net_mqtt_enc.pack_uint8: (0x20014f98): >> val:32 cur:0x20021441, end:0x20021c3e
[00:00:05.989,990] <dbg> net_mqtt_enc.packet_length_encode: (0x20014f98): >> length:0x00000051 cur:0x20021442, end:0x20021c3e
[00:00:05.989,990] <dbg> net_mqtt.client_write_msg: (0x20014f98): [0x200187a0]: Transport writing message.
[00:00:05.991,119] <dbg> net_mqtt.client_write_msg: (0x20014f98): [0x200187a0]: Transport write complete.

And when I try to disconnect by calling aws_iot_disconnect() from the aws_iot.h library:

[00:00:18.932,189] <dbg> net_mqtt.client_write: (0x20014f98): [0x200187a0]: Transport writing 2 bytes.
[00:00:18.941,345] <dbg> net_mqtt.client_write: (0x20014f98): [0x200187a0]: Transport write complete.
[00:00:18.941,375] <dbg> net_mqtt_sock_tls.mqtt_client_tls_disconnect: (0x20014f98): Closing socket 1
[00:00:18.941,406] <dbg> net_sock.z_impl_zsock_close: (0x20014f98): close: ctx=0x20018474, fd=1
[00:00:18.942,749] <dbg> aws_iot.mqtt_evt_handler: MQTT_EVT_DISCONNECT: result = 0
[00:00:18.942,779] <inf> cloud_api_aws: AWS_IOT_EVT_DISCONNECTED: 0
[00:00:18.942,779] <inf> cloud_api_aws: AWS_IOT_DISCONNECT_USER_REQUEST
[00:00:18.942,810] <inf> lte_main: Reconnect attempts to AWS broker disabled, idling with LTE modem online...
[00:00:18.942,901] <dbg> aws_iot.aws_iot_cloud_poll: Socket error: POLLNVAL
[00:00:18.942,901] <dbg> aws_iot.aws_iot_cloud_poll: The cloud socket was unexpectedly closed.

Nothing happens in the cloud..

Helpful info:

  • Modem Firmware: mfw_nrf9160_1.3.0
  • SDK version: 1.6.0
  • I am setting CONFIG_AWS_IOT_LAST_WILL=y in prj.conf
  • Last will topic (set by CONFIG_AWS_IOT_LAST_WILL_TOPIC in prj.conf): "tcxn/things/00000016/shadow/update"
  • Last will message (set by CONFIG_AWS_IOT_LAST_WILL_MESSAGE in prj.conf): {\"state\":{\"reported\":{\"connected\":\"false\"}}}"
  • Library begin used: aws_iot, based on nrf\samples\nrf9160\aws_iot
  • Using custom board file of 9160_ns

The topic has to be non-reserved (not $) in order for the broker to forward the last will message, hence "tcxn" is being used, more info: (Topics - Managed IoT Cloud (telenorconnexion.com)). The device is able to publish to this topic with basic mqtt_publish call, but is not updated on disconnection. I've talked with support at Telenorconnnexion, and they could not see any immediate errors in my topic/message formatting, so the error is mostly on my implementation side on 9160 chip using aws_iot.

Another thing I faced when reading about mqtt and the modem: Why is nrf_modem_lib in the non-secure region, why are the bsd-sockets non-secure, why not have everything secure? Most of the information I've found says the modem has to be non-secure, but never why it is. I.e: (Nordic Semiconductor Infocenter) (Same could be asked about of other peripherals). I've read an example of how TrustZone works briefly, seen with a mobile payment app. The user interface has to be available and non-secure for the user to see, but the payment and user info has to be secure, would this be a good analogy?

Thanks in advance,

EivindTH

Parents
  • Hi,

     

    Why is nrf_modem_lib in the non-secure region, why are the bsd-sockets non-secure, why not have everything secure?

     Because the modem/application can be attacked from the internet, it is limited to the non-secure domain. You can then use the secure domain to keep secrets, so that an attack will have less consequences.

    When it comes to the last will issue: Are you able to see if the device has set a last will message in the cloud?

    I can't remember hearing about anyone else with similar issues. And, as the log states that it is creating the last will message, and you do not get any errors, it does not look like the problem is on the device side.

    Best regards,

    Didrik

Reply
  • Hi,

     

    Why is nrf_modem_lib in the non-secure region, why are the bsd-sockets non-secure, why not have everything secure?

     Because the modem/application can be attacked from the internet, it is limited to the non-secure domain. You can then use the secure domain to keep secrets, so that an attack will have less consequences.

    When it comes to the last will issue: Are you able to see if the device has set a last will message in the cloud?

    I can't remember hearing about anyone else with similar issues. And, as the log states that it is creating the last will message, and you do not get any errors, it does not look like the problem is on the device side.

    Best regards,

    Didrik

Children
  • Hello,

    Sorry for the late reply. This looks to be resolved now, everything was correct on the device. The issue was parameters set on the device that was incompatible with the cloud service, such as the keep alive timer which handles when the broker detects a device has disconnected ungracefully. (1.5 times the keep alive time). Another thing to mention is that I also tested using aws_iot_disconnect(), which in turn sends a DISCONNECT flag to cloud causing a graceful disconnect, which doesn't update LWT.

    Thanks,

    Eivind

Related