Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [paho-dev] Embedded MQTT C Client

Sure Ian,
so far MQTT transport API, ported from MQTT-SN, and fitting the current
MQTT samples is:

int transport_open(char* host, int port);
int transport_sendPacketBuffer(int sock, unsigned char* buf, int buflen);
/* block until requested data is there, or socket timeout (-1) */
int transport_getdata(unsigned char* buf, int count);
int transport_close(int sock);

MQTT-SN transport API (as recently uploaded) is a little bit different
because of the UDP transport nature:
int transport_open(void);
int transport_sendPacketBuffer(char* host, int port, unsigned char* buf,
int buflen);
/* may return -1 if no data or block, the packet reader is friendly to
UDP */
int transport_getdata(unsigned char* buf, int count);
int transport_close(void);

So, to accomodate TCPs stream nature and the fact that sometimes links
are slow and all that stuff, and bare bones embedded systems can't block
waiting for the whole data to be present, I slightly modified the
required behaviour with a newcomer in the MQTT transport API:

/* return available data, 0 if none, -1 on error */
int transport_getdatanb(unsigned char* buf, int count);

powered by a couple state machines to wait for and collect the data in
MQTTPacket.c. The newcomer to the MQTTPacket API would be:

int MQTTPacket_readnb(unsigned char* buf, int buflen,
MQTTTransportObject *trp);

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

I basically copied MQTTPacket_read() and MQTTPacket_decode and turned
them into state machines (so the variables in the network object), so
they can safely wait for data coming in an ordered fashion but with no
logical separation, as per TCP.
The user gets to write his transport_getdatanb() and can choose to peek
the transport or build an intermediate buffer. The demo as it is now
runs on top of the sockets api and actually blocks, I thought it is more
clear to leave this to the user and not complicate the issue by toying
with a socket interface which won't be used on a bare metal system. I
plan to write some samples for the lwIP raw API later.

I can submit these changes to Gerrick but I would like to extensively
test the code first (maybe submit the API ?), so far it runs on my setup
but I'd like to actually send it data in conditions closer to the ones
it is supposed to handle.


Back to the top