eclipse / paho.mqtt.embedded-c

Paho MQTT C client library for embedded systems. Paho is an Eclipse IoT project (https://iot.eclipse.org/)

Home Page:https://eclipse.org/paho

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Paho.mqtt-c master asyncrounous subscribtion keep alive issue

prashanthk232 opened this issue · comments

When i suscribe in mqtt asyncrounous the controller not come back to my main ( ) function. It stay in keepalive function loop. after subscription i want to do some task on my application but controller is still there in keep alive function. please any one tell me how to run my appliction after subscribe

Hello @prashanthk232,
Could you please give more information's (code example)?
What do you mean by asynchronous subscribe ?

  • You send the subscribe packet and check later the SUBACK (Yield or task main function)?

In my application I had similar behavior (poor network quality) the implementation was something like,
Split the Network received buffer (Socket) with the MQTT receive buffer.
With a period Task i fill the Socket data's received in the Network receive buffer then
call the function MQTTPacket_readnb() (with some timeout inside) .
Based on this if a data frame is completed (check MQTTPacket_readnb return value), I store in the MQTT receive buffer the previous frame.
If the data frame in the Network received buffer is not completed the function MQTTPacket_readnb will let you know .
Note : A timeout mechanism is necessary to don't be locked .

You only call the Yield function once you frame is completed.

For the keep alive i move it out of the cycle function and handle separately with the same asynchronous mechanism.

I could share the code if needed.

Cheers
Yacine

Thank you 😊 please share it

Below the implementation of the function MQTTPacket_readnb()

The structure MQTT transport now include a timer + callback function to reset the input buffer data in case of Timeout

typedef struct {
	void (*ResetReceivedDataTimeout)(void);
	Timer timer;
	int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */
	void *sck;	/* pointer to whatever the system may use to identify the transport */
	int multiplier;
	int rem_len;
	int len;
	char state;
}MQTTTransport; 

``
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp)
{
	int rc = -1, frc;
	MQTTHeader header ={ 0 };

	switch (trp->state) {
	default:
		trp->state = 0;
		/*FALLTHROUGH*/
	case 0:
		/* read the header byte.  This has the packet type in it */
		if ((frc=(*trp->getfn)(trp->sck, buf, 1)) == -1)
			goto exit;
		if (frc == 0)
			return 0;
		trp->len = 0;
		++trp->state;
		/*FALLTHROUGH*/
		/* read the remaining length.  This is variable in itself */
	case 1:
		if ((frc=MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR)
			goto exit;
		if (frc == 0)
			return 0;
		trp->len = 1 + MQTTPacket_encode(buf + 1, trp->rem_len); /* put the original remaining length back into the buffer */
		if ((trp->rem_len + trp->len) > buflen)
			goto exit;
		++trp->state;
		TimerInit(&(trp->timer));
		TimerCountdownMS(&(trp->timer), 120000);
		/*FALLTHROUGH*/
	case 2:
		if (trp->rem_len) {
			if (!TimerIsExpired(&(trp->timer)))
			{
				/* read the rest of the buffer using a callback to supply the rest of the data */
				if ((frc=(*trp->getfn)(trp->sck, buf + trp->len, trp->rem_len)) == -1)
					goto exit;
				if (frc == 0)
					return 0;
				trp->rem_len -= frc;
				trp->len += frc;
				if (trp->rem_len)
					return 0;
			}
			else
			{
				/* Timer expires when waiting for data reset the state */
				/* Callback to restore the received data structure */
				trp->ResetReceivedDataTimeout( );
				trp->state = 0;
				return 0;
			}

		}
		header.byte = buf[0];
		rc = header.bits.type;
		break;
	}

	exit:
	trp->state = 0;
	return rc;
}

Once the function MQTTPacket_readnb() return a value different from 0, the function cycles is called.
NOTE : The function " cycle" has been modified to full support the asynchronous functionality which means the KeepAlive
is commented and call independently of this function