aws-iot-device-sdk-embedded-C icon indicating copy to clipboard operation
aws-iot-device-sdk-embedded-C copied to clipboard

Callback to subscribe is not invoked

Open srnae05 opened this issue 1 year ago • 10 comments

Hi co-developers,

Using the AWS SDK with CC3220sf uC, it is possible to connect to AWS MQTT broker and also subscribe to topics in a named device shadow. However, when something is published to this topic via IOT Console, the callback on the device is not invoked. The device is still connected to the MQTT broker. Any clues ?

Thank you in advance.

srnae05 avatar Jul 29 '22 14:07 srnae05

Hi @srnae05

I'm not sure I understand what the problem is. You are able to connect to AWS MQTT broker on your device, presumably using coreMQTT and shadow demo bundled with this repo, but are not getting callbacks on the device for shadow updates? Is that correct?

Which topic are you publishing to with IoT console, and have you made changes to the MQTT subscriptions made in the demo? For shadow updates you need to publish to a particular topic, as documented here. i.e. Topic:

$aws/things/thingName/shadow/name/shadowName

Also, can you verify whether the MQTT stack is working? This repo houses coreMQTT demos you can try out to verify the MQTT stack individually.

dachalco avatar Jul 29 '22 23:07 dachalco

Hi @dachalco,

Your statement "You are able to connect to AWS MQTT broker on your device, presumably using coreMQTT and shadow demo bundled with this repo, but are not getting callbacks on the device for shadow updates?" is correct. I can see the connect messages and messages that the subscribe is successful in the Cloud Watch of AWS console. However, when I publish a message from AWS IoT console to the same topic, the callback event handler is not trigerred. Maybe Im checking the wrong event handler here ? I also updated the topic name and named shadow to which the device has to connect to. Thank you.

srnae05 avatar Aug 01 '22 05:08 srnae05

All the MQTT messages should route through eventCallback in the demo and fan out from there, so you could put a breakpoint in this function or add a log to see if it's reached. Additionally you can enable debug logs for MQTT by setting LIBRARY_LOG_LEVEL = LOG_DEBUG in the shadow demo's coreMQTT config. You can do the same with the shadow library's config.

Can you verify whether any PUB/SUB messages are working on the device. I understand the subscribe packets are going through fine, but want to know whether MQTT PUB payloads are getting through to the application. Can you post demo log output with MQTT and Shadow debug logs enabled -- instructions above?

Would recommend trying one of the coreMQTT demos, also in this repo, to verify whether the coreMQTT stack port for this device is working properly.

dachalco avatar Aug 01 '22 17:08 dachalco

Hi @dachalco, I tried some fixes in the mean time and the following seems to work. A delay between connect and subscribe ensures that the event call back is always called. The edge device uses 48MHz crystal as a clock, Is there a timing requirement between connect and subscribe messages to AWS ?

eMqttStatus = MQTT_Connect( pxMqttContext,&xConnectInfo, NULL, mqttexampleCONNACK_RECV_TIMEOUT_MS, &sessionPresent ); if( eMqttStatus != MQTTSuccess ) { xReturnStatus = pdFAIL; } usleep(2000 * 1000); //sleep for 2 seconds xReturnStatus = SubscribeToTopic(pxMqttContext, SHADOW_TOPIC_STR_UPDATE_DELTA( THING_NAME, SHADOW_NAME ), SHADOW_TOPIC_LEN_UPDATE_DELTA( THING_NAME_LENGTH, SHADOW_NAME_LENGTH ) );

srnae05 avatar Aug 02 '22 07:08 srnae05

Hi @dachalco : Some more interesting findings are:

  • if an internal PLL is used and reduces the frequency to 24 MHz, sleep is not required.
  • if 48MHz is the clock frequency, between every MQTT operation - connect and subscribe (or) subscribe and publish (or) ping and ping, a sleep is required. Any thoughts on this yet ? Thank you.

srnae05 avatar Aug 05 '22 10:08 srnae05

Hi @srnae05

Glad to learn you've found a solution.

Can't comment on exact timing figures because it depends on the architecture and port setup. However EstablishMqttSession should block such that an immediate subsequent SUB should work. Is the MCU port code for connectToServerWithBackoffRetries working appropriately? Perhaps the port has some async connect logic that returns early before connection is fully established?

An interesting experiment would be to SUB to one topic A immediately after the connect, then do the same delay and SUB to a different topic B, and see whether topic B gets payloads while A does not. If so, I'd strongly suspect the underlying port code for EstablishMqttSession is incorrect.

dachalco avatar Aug 05 '22 17:08 dachalco

Hi @srnae05

In addition, could you also check if you are calling MQTT_ProcessLoop() at regular intervals so that you are processing all incoming messages. The shadow demo provided in this repository assumes the device as the publisher to the shadow document. It calls MQTT_ProcessLoop after every publish and subscribe which yields to processing the incoming packets as well. Since in your setup, if you are publishing from IoT console, then your demo task should also yield periodically to process the incoming messages by calling MQTT_ProcessLoop().

ravibhagavandas avatar Aug 07 '22 19:08 ravibhagavandas

@srnae05 Were the suggestions helpful? Have you been able to resolve the problem?

n9wxu avatar Aug 17 '22 00:08 n9wxu

@dachalco @ravibhagavandas @n9wxu Thank you for the hints. If I tried the sequence that @dachalco indicated, topic B also does not receive a payload. If there is a connect message, followed by a subscribe message without a sleep, any subscribe messages after are also not fulfilled. I checked the function connectToServerWithBackoffRetries for completeness of CONNECT status and this is the case. Subscribe is sent only after a connection is completely successful (no async events). MQTT_ProcessLoop() is called every 250ms in a task. Also, the events on the socket are buffered in order to not miss any events. Interesting finding that I have is - if I separate the task in which socket events are handled and the MQTT_ProcessLoop() is called (with same priorities though), I would have to wait only 250msec between a CONNECT and subscribe message. I would assume it is 250msec + x (task switching time) is sufficient for the broker to react to requests. Could this be valid ?

srnae05 avatar Aug 17 '22 08:08 srnae05

Hi @srnae05

If you're using a modified version of the demo, would you be okay with sharing the non-platform-specific code? With this we could better analyze if there were some sort of library-level race condition and may allow us to repeat the issue on a different platform. If not, could you itemize all the changes you made?

Is shadow_demo_main.c still calling MQTT_ProcessLoop? MQTT_ProcessLoop isn't thread safe, so if the shadow_demo_main.c and a new separate added task are both calling MQTT_ProcessLoop without any sort of thread-sync, that would be a problem. You remedy with mutexes and chain-of-responsibility.

Also can you enable MQTT debug logs and post the output? The debug logs can be configured by defining this to LOG_DEBUG instead.

dachalco avatar Aug 17 '22 15:08 dachalco

closing ticket with due to no activity.

alfred2g avatar Sep 17 '22 22:09 alfred2g