This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MQTT: Failing to detect broker disconnect

Other Parts Discussed in Thread: CC3200

Hi,

I am building an MQTT application on my CC3200 following this example (using Paho client): https://github.com/stellascapes/mqtt-examples/blob/master/mqtt

I now have the problem that whenever the broker-connection gets disconnected by the broker, my application gets stuck in the do-while-loop of the read-function:

int cc3200_read(Network* n, unsigned char* buffer, int len, int timeout_ms) {
	SlTimeval_t timeVal;
	SlFdSet_t fdset;
	int rc = 0;
	int recvLen = 0;

	SL_FD_ZERO(&fdset);
	SL_FD_SET(n->my_socket, &fdset);

	timeVal.tv_sec = 0;
	timeVal.tv_usec = timeout_ms * 1000;
	if (sl_Select(n->my_socket + 1, &fdset, NULL, NULL, &timeVal) == 1) {
		do {
			rc = sl_Recv(n->my_socket, buffer + recvLen, len - recvLen, 0);
			recvLen += rc;
		} while(recvLen < len);
	}
	return recvLen;
}

The problem is, that sl_Recv is returning "0", so the (recLen < len) condition will always stay true. Is it correct to say that whenever sl_Rescv returns 0 the connection is broken? Shouldn't it then be a negative return value to indicate an error?

Also my Socket-Error-Handler does not through any error, even though the socket gets terminated.

Thanks for you help,

Henry

  • Hi Henry,

    Can you try the mqtt example from the SDK and see if that works?

    Regards,
    Gigi Joseph.
  • Dear Gigi,

    Is the MQTT client from the example working stable? I did try this in the beginning but found that the socket was closed remotely due to the client timing out (read from the MQTT server logs).

    Is the SDK MQTT sample also based on the Paho client?

    Thanks
    Henry
  • Dear Gigi,

    I just ran the MQTT SDK example and received the following output:

    Version: Client LIB 1.0.3, Common LIB 1.1.1.
    C: FH-B1 0x10 to net 17, Sent (45 Bytes) [@ 15]
    C: Rcvd msg Fix-Hdr (Byte1) 0x20 from net 17 [@ 15]
    C: Cleaning session for net 17
    C: Msg w/ ID 0x0000, processing status: Good
    
    Success: conn to Broker no. 1
     C: FH-B1 0x82 to net 17, Sent (79 Bytes) [@ 15]
    C: Rcvd msg Fix-Hdr (Byte1) 0x90 from net 17 [@ 15]
    C: Msg w/ ID 0x0001, processing status: Good
    Client subscribed on following topics:
    /cc3200/ToggleLEDCmdL1
    /cc3200/ToggleLEDCmdL2
    /cc3200/ToggleLEDCmdL3
    C: FH-B1 0xc0 to net 17, Sent (2 Bytes) [@ 40]
    C: Rcvd msg Fix-Hdr (Byte1) 0x30 from net 17 [@ 40]
    
    Publish Message Received
    Topic: /cc3200/ToggleLEDCmdL1 [Qos: 0]
    Data is: test
    C: Msg w/ ID 0x0000, processing status: Good
    C: Rcvd msg Fix-Hdr (Byte1) 0xd0 from net 17 [@ 40]
    C: Msg w/ ID 0x0000, processing status: Good
    C: Net 17, Raw Error -1, Time Out: N
    C: RX closing Net 17 [-1]
    C: Cleaning session for net 17
    C: Net 17 now closed

    I send one "test" message to the subscribed topic "ToggleLEDCmdL1" and it arrived as one can see. Afterwards I remotely disconnected the CC3200 Client from the broker.

    The MQTT SDK example does recognize the connection loss (see last 4 lines). But how can I act upon those messages? Are they thrown from the library?

    Again, the Socket Event Handler does not get triggered. Where do these "C: [..]" messages actually come from? I could not find them in the source of the example.

    Thanks for your help!

    Henry

  • Quick add-on:

    I did a dirty work-around for identifying the connection loss by changing the UART_PRINT debug output to a different function "mqtt_msg_handler":

    /* library configuration */
    SlMqttClientLibCfg_t Mqtt_Client={
        1882,
        TASK_PRIORITY,
        30,
        false,
        (long(*)(const char *, ...))mqtt_msg_handler
    };

    And the this function simply does a string compare:

    void mqtt_msg_handler(const char *msg) {
    
    	const char *find = "C: Net";
    	if (strncmp(msg, find, sizeof(find)) == 0) {
    
    		UART_PRINT("Connection loss detected.");
    	}
    }

    I guess this is not meant to be the way this should be done, so please could someone tell me what would be the proper way to handle connection losses?

    Thanks

    Henry

  • Hi Henry,

    The TCP socket recv returns 0 if the connection is closed from the remote side.

    Socket recv may also return the -ve value indicating the various errors with the exception of -11 (SL_EAGAIN) in case of non blocking socket notifying application to try again.

    Regards,
    Ankur
  • Dear Ankur,

    That is very helpful input, thanks.

    In regards to my approach of catching the debug messages of the TI MQTT example, is this the correct way to do it (see my recent posts)?

    Henry

  • Hi Henry,

    Handling of disconnection from the server depends upon the application and use case. In the SDK example application exit upon disconnection. You can very well modify the example to attempt reconnection with the server.

    MQTT library call the registered callback (sl_MqttDisconnect() in sdk example) upon detecting a disconnection.

    Regards,
    Ankur
  • Dear Ankur,

    I have just double checked with the MQTT example from the SDK but the sl_MqttDisconnect() is not called when the socket is broken (e.g. broker gets unavailable).

    Am I doing something wrong?

    Thanks
    Henry
  • Hi ,

    This is SDK 1.1.0 known issue, you may patch the solution from this site:

    This

    Rebuild mqtt lib and your example

    And please also note that do not call sl_ExtLib_MqttClientCtxDelete in sl_MqttDisconnect to avoid 

    system hang.

  • Henry,

    As suggested by Johnson please incorporate the changes mentioned on the known issue wiki (processors.wiki.ti.com/.../CC32xx_Summary_of_Known_Issues) and let us know the results.

    Johnson,

    Thanks for the response.

    Regards,
    Ankur
  • Hi Henry,

    I am closing this thread, if you are still seeing this issue please open a new thread and add a link to this one for reference.

    Regards,
    Ankur