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