File:  [ELWIX - Embedded LightWeight unIX -] / mqtt / src / Attic / aitmqtt.c
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Fri Jan 27 15:05:38 2012 UTC (12 years, 5 months ago) by misho
Branches: MAIN
CVS tags: mqtt1_1, HEAD
added new files

#include "global.h"


#pragma GCC visibility push(hidden)

int mqtt_Errno;
char mqtt_Error[STRSIZ];

#pragma GCC visibility pop

//
// Error maintenance functions ...
//

// mqtt_GetErrno() Get error code of last operation
inline int
mqtt_GetErrno()
{
	return mqtt_Errno;
}

// mqtt_GetError() Get error text of last operation
inline const char *
mqtt_GetError()
{
	return mqtt_Error;
}

// mqtt_SetErr() Set error to variables for internal use!!!
inline void
mqtt_SetErr(int eno, char *estr, ...)
{
	va_list lst;

	mqtt_Errno = eno;
	memset(mqtt_Error, 0, sizeof mqtt_Error);
	va_start(lst, estr);
	vsnprintf(mqtt_Error, sizeof mqtt_Error, estr, lst);
	va_end(lst);
}

#pragma GCC visibility push(hidden)
// _mqtt_readHEADER() read fixed header from MQTT message
inline struct mqtthdr *
_mqtt_readHEADER(mqtt_msg_t * __restrict buf, u_char cmd, int *bytes, int *len)
{
	struct mqtthdr *hdr;

	if (!buf || !buf->msg_base || !buf->msg_len)
		return NULL;

	hdr = (struct mqtthdr*) buf->msg_base;
	if (hdr->mqtt_msg.type != cmd) {
		mqtt_SetErr(EINVAL, "Error:: wrong command #%d should be %d", 
				hdr->mqtt_msg.type, cmd);
		return NULL;
	}

	*len = mqtt_decodeLen(hdr->mqtt_len, bytes);
	return hdr;
}
#pragma GCC visibility pop

// ----------------------------------------------------------

/*
 * mqtt_msgFree() Free MQTT message
 *
 * @msg = Message buffer
 * @all = !=0 Destroy entire message, if MQTT Message allocated with mqtt_msgAlloc()
 * return: none
 */
inline void
mqtt_msgFree(mqtt_msg_t ** __restrict msg, int all)
{
	if (msg && *msg) {
		if ((*msg)->msg_base) {
			free((*msg)->msg_base);
			(*msg)->msg_base = NULL;
		}
		if (all) {
			free(*msg);
			*msg = NULL;
		} else
			(*msg)->msg_len ^= (*msg)->msg_len;
	}
}

/*
 * mqtt_msgAlloc() Allocate memory for MQTT Message
 *
 * @len = >0 Allocate buffer with length
 * return: NULL error or Message, after use must call mqtt_msgFree() with all!=0
 */
inline mqtt_msg_t *
mqtt_msgAlloc(u_short len)
{
	mqtt_msg_t *m = NULL;

	m = malloc(sizeof(mqtt_msg_t));
	if (!m) {
		LOGERR;
		return NULL;
	} else
		memset(m, 0, sizeof(mqtt_msg_t));

	if (len) {
		m->msg_len = len;
		m->msg_base = malloc(m->msg_len);
		if (!m->msg_base) {
			LOGERR;
			free(m);
			return NULL;
		} else
			memset(m->msg_base, 0, m->msg_len);
	}

	return m;
}

/*
 * mqtt_msgRealloc() Reallocate MQTT message buffer
 *
 * @msg = MQTT message
 * @len = new length
 * return: -1 error or >-1 old buffer length
 */
inline int
mqtt_msgRealloc(mqtt_msg_t * __restrict msg, u_short len)
{
	void *p = NULL;
	int ret = 0;

	if (!msg)
		return -1;

	if (len == msg->msg_len)
		return len;

	p = realloc(msg->msg_base, len);
	if (!p) {
		LOGERR;
		return -1;
	}

	ret = msg->msg_len;
	msg->msg_len = len;
	msg->msg_base = p;

	return ret;
}

/*
 * mqtt_encodeLen() Encode number to MQTT length field
 *
 * @num = number for encode
 * return: -1 error or >-1 length
 */
inline u_int
mqtt_encodeLen(u_int num)
{
	register u_int dig, i;
	u_int ret = 0;

	if (num > 268435455)
		return (u_int) -1;

	for (i = 0; i < sizeof ret && num > 0; i++) {
		dig = num % 0x80;
		num /= 0x80;
		if (num > 0)
			dig |= 0x80;

		*((u_char*) &ret + i) = (u_char) dig;
	}

	return ret;
}

/*
 * mqtt_decodeLen() Decode length from MQTT packet
 *
 * @len = length from MQTT header
 * @n = sizeof bytes, if !=NULL
 * return: -1 error, >-1 length of message
 */
inline u_int
mqtt_decodeLen(void * __restrict len, int * __restrict n)
{
	register u_int i, dig, mul;
	u_int ret = 0;
	u_char *p = (u_char*) len;

	if (!len)
		return (u_int) -1;

	for (mul = 1, i = 0; i < sizeof ret; i++, mul *= 0x80) {
		dig = p[i];
		ret += (dig & 0x7f) * mul;

		if (!(dig & 0x80))
			break;
	}

	if (n)
		*n = (char) (i & 0x7f) + 1;
	return ret;
}

/*
 * mqtt_sizeLen Return sizeof len field
 *
 * @len = length
 * return: -1 error, >-1 sizeof len in bytes
 */
inline char
mqtt_sizeLen(u_int len)
{
	register char i;
	u_char *p = (u_char*) &len;

	if (len > 0xffffff7f)
		return -1;

	for (i = 0; i < sizeof len; i++)
		if (!(*(p + i) & 0x80))
			break;

	return ++i;
}

/*
 * mqtt_str2sub Create MQTT subscribe variable from string(s)
 *
 * @csStr = strings
 * @strnum = number of strings elements
 * @qoses = QoS elements applied to subscribe variable, 
 * 		count of elements must be equal with csStr elements
 * return: NULL error or != subscribe variables array, must be free after use with mqtt_freeSub()
 */
inline mqtt_subscr_t *
mqtt_str2sub(const char **csStr, u_short strnum, u_char *qoses)
{
	mqtt_subscr_t *v;
	register int i, items;
	const char **strs;

	if (!csStr)
		return NULL;
	for (items = 0, strs = csStr; *strs; items++, strs++)
		if (strnum && items >= strnum) {
			items = strnum;
			break;
		}

	if (!(v = malloc((items + 1) * sizeof(mqtt_subscr_t)))) {
		LOGERR;
		return NULL;
	} else
		memset(v, 0, (items + 1) * sizeof(mqtt_subscr_t));

	for (i = 0; i < items; i++) {
		v[i].sub_topic._size = strlen(csStr[i]);
		v[i].sub_topic._base = (u_char*) strdup(csStr[i]);
		if (qoses && qoses[i] < MQTT_QOS_RESERVED)
			v[i].sub_ret = qoses[i];
	}

	return v;
}

/*
 * mqtt_subFree() Free array from subscribe variables
 *
 * @subs = Subscribe variables
 * return: none
 */
inline void
mqtt_subFree(mqtt_subscr_t ** __restrict subs)
{
	mqtt_subscr_t *v;

	if (!subs)
		return;

	for (v = *subs; v->sub_topic._base; v++) {
		free(v->sub_topic._base);
		v->sub_topic._base = NULL;
		v->sub_topic._size = 0;

		if (v->sub_value._base) {
			free(v->sub_value._base);
			v->sub_value._base = NULL;
			v->sub_value._size = 0;
		}
	}

	free(*subs);
	*subs = NULL;
}

/*
 * mqtt_subAlloc() Create array from subscribe variables
 *
 * @num = Number of elements
 * return: NULL error or subscribe array, after use must call mqtt_subFree()
 */
inline mqtt_subscr_t *
mqtt_subAlloc(u_short num)
{
	mqtt_subscr_t *s = NULL;

	s = malloc((num + 1) * sizeof(mqtt_subscr_t));
	if (!s) {
		LOGERR;
		return NULL;
	} else
		memset(s, 0, (num + 1) * sizeof(mqtt_subscr_t));

	return s;
}

/*
 * mqtt_subRealloc() Reallocate array from subscribe variables
 *
 * @subs = Subscribe array
 * @num = Number of elements
 * return: NULL error or subscribe array, after use must call mqtt_subFree()
 */
inline mqtt_subscr_t *
mqtt_subRealloc(mqtt_subscr_t * __restrict subs, u_short num)
{
	mqtt_subscr_t *s = NULL;

	s = realloc(subs, (num + 1) * sizeof(mqtt_subscr_t));
	if (!s) {
		LOGERR;
		return NULL;
	}

	return s;
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>