/**
  * Deserializes the supplied (wire) buffer into unsubscribe data
  * @param dup integer returned - the MQTT dup flag
  * @param packetid integer returned - the MQTT packet identifier
  * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
  * @param count - number of members in the topicFilters and requestedQoSs arrays
  * @param topicFilters - array of topic filter names
  * @param buf the raw buffer data, of the correct length determined by the remaining length field
  * @param buflen the length in bytes of the data in the supplied buffer
  * @return the length of the serialized data.  <= 0 indicates error
  */
int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
		unsigned char* buf, int len)
{
	MQTTHeader header = {0};
	unsigned char* curdata = buf;
	unsigned char* enddata = NULL;
	int rc = 0;
	int mylen = 0;

	header.byte = readChar(&curdata);
	if (header.bits.type != UNSUBSCRIBE)
		goto exit;
	*dup = header.bits.dup;

	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
	enddata = curdata + mylen;

	*packetid = readInt(&curdata);

	*count = 0;
	while (curdata < enddata)
	{
		if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
			goto exit;
		(*count)++;
	}

	rc = 1;
exit:
	return rc;
}
Ejemplo n.º 2
0
/**
  * Deserializes the supplied (wire) buffer into publish data
  * @param dup returned integer - the MQTT dup flag
  * @param qos returned integer - the MQTT QoS value
  * @param retained returned integer - the MQTT retained flag
  * @param packetid returned integer - the MQTT packet identifier
  * @param topicName returned MQTTString - the MQTT topic in the publish
  * @param payload returned byte buffer - the MQTT publish payload
  * @param payloadlen returned integer - the length of the MQTT payload
  * @param buf the raw buffer data, of the correct length determined by the remaining length field
  * @param buflen the length in bytes of the data in the supplied buffer
  * @return error code.  1 is success
  */
int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
		unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen)
{
	MQTTHeader header = {0};
	unsigned char* curdata = buf;
	unsigned char* enddata = NULL;
	int rc = 0;
	int mylen = 0;

	header.byte = readChar(&curdata);
	if (header.bits.type != PUBLISH)
		goto exit;
	*dup = header.bits.dup;
	*qos = header.bits.qos;
	*retained = header.bits.retain;

	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
	enddata = curdata + mylen;

	if (!readMQTTLenString(topicName, &curdata, enddata) ||
		enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
		goto exit;

	if (*qos > 0)
		*packetid = readInt(&curdata);

	*payloadlen = enddata - curdata;
	*payload = curdata;
	rc = 1;
exit:
	return rc;
}
/**
  * Deserializes the supplied (wire) buffer into unsubscribe data
  * @param dup integer returned - the MQTT dup flag
  * @param packetid integer returned - the MQTT packet identifier
  * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
  * @param count - number of members in the topicFilters and requestedQoSs arrays
  * @param topicFilters - array of topic filter names
  * @param buf the raw buffer data, of the correct length determined by the remaining length field
  * @param buflen the length in bytes of the data in the supplied buffer
  * @return the length of the serialized data.  <= 0 indicates error
  */
int MQTTDeserialize_unsubscribe(int* dup, int* packetid, int maxcount, int* count, MQTTString topicFilters[], char* buf, int len)
{
	MQTTHeader header;
	char* curdata = buf;
	char* enddata = NULL;
	int rc = 0;
	int mylen = 0;

	FUNC_ENTRY;
	header.byte = readChar(&curdata);
	*dup = header.bits.dup;

	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
	enddata = curdata + mylen;

	*packetid = readInt(&curdata);

	*count = 0;
	while (curdata < enddata)
	{
		if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
			goto exit;
		(*count)++;
	}

	rc = 1;
exit:
	FUNC_EXIT_RC(rc);
	return rc;
}
Ejemplo n.º 4
0
/**
 * Deserializes the supplied (wire) buffer into connect data structure
 * @param data the connect data structure to be filled out
 * @param buf the raw buffer data, of the correct length determined by the remaining length field
 * @param len the length in bytes of the data in the supplied buffer
 * @return error code.  1 is success, 0 is failure
 */
int MQTTDeserialize_connect( MQTTPacket_connectData* data, unsigned char* buf, int len )
{
    MQTTHeader header =
    { 0 };
    MQTTConnectFlags flags =
    { 0 };
    unsigned char* curdata = buf;
    unsigned char* enddata = &buf[ len ];
    int rc = 0;
    MQTTString Protocol;
    int version;
    int mylen = 0;

    FUNC_ENTRY;
    header.byte = readChar( &curdata );
    if ( header.bits.type != CONNECT )
        goto exit;

    curdata += MQTTPacket_decodeBuf( curdata, &mylen ); /* read remaining length */

    if ( !readMQTTLenString( &Protocol, &curdata, enddata ) || enddata - curdata < 0 ) /* do we have enough data to read the protocol version byte? */
        goto exit;

    version = (int) readChar( &curdata ); /* Protocol version */
    /* If we don't recognize the protocol version, we don't parse the connect packet on the
     * basis that we don't know what the format will be.
     */
    if ( MQTTPacket_checkVersion( &Protocol, version ) )
    {
        flags.all = readChar( &curdata );
        data->cleansession = flags.bits.cleansession;
        data->keepAliveInterval = readInt( &curdata );
        if ( !readMQTTLenString( &data->clientID, &curdata, enddata ) )
            goto exit;
        data->willFlag = flags.bits.will;
        if ( flags.bits.will )
        {
            data->will.qos = flags.bits.willQoS;
            data->will.retained = flags.bits.willRetain;
            if ( !readMQTTLenString( &data->will.topicName, &curdata, enddata ) || !readMQTTLenString( &data->will.message, &curdata, enddata ) )
                goto exit;
        }
        if ( flags.bits.username )
        {
            if ( enddata - curdata < 3 || !readMQTTLenString( &data->username, &curdata, enddata ) )
                goto exit;
            /* username flag set, but no username supplied - invalid */
            if ( flags.bits.password && ( enddata - curdata < 3 || !readMQTTLenString( &data->password, &curdata, enddata ) ) )
                goto exit;
            /* password flag set, but no password supplied - invalid */
        }
        else if ( flags.bits.password )
            goto exit;
        /* password flag set without username - invalid */
        rc = 1;
    }
    exit: FUNC_EXIT_RC(rc);
    return rc;
}
Ejemplo n.º 5
0
int MQTTDeserialize_publish(MQTTFixedHeaderPlusMsgId *fixedHeaderPlusMsgId,
                            MQTTString* topicName,
                            unsigned char** payload,
                            int* payloadlen,
                            unsigned char* buf,
                            int buflen)
{
	MQTTHeader header = {0};
	unsigned char* curdata = buf;
	unsigned char* enddata = NULL;
	int rc = FAILURE;
	int mylen = 0;

	FUNC_ENTRY;
	header.byte = readChar(&curdata);
	if (header.bits.type != PUBLISH)
		goto exit;

    fillFixedHeaderFieldsFromPacketHeader(&(fixedHeaderPlusMsgId->fixedHeader), &header);

	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
	enddata = curdata + mylen;

	if (!readMQTTLenString(topicName, &curdata, enddata) ||
		enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
		goto exit;

	if ((fixedHeaderPlusMsgId->fixedHeader).qos > 0)
		fixedHeaderPlusMsgId->msgId = readInt(&curdata);

	*payloadlen = enddata - curdata;
	*payload = curdata;

	rc = SUCCESS;

exit:
	FUNC_EXIT_RC(rc);
	return rc;
}
/**
  * Deserializes the supplied (wire) buffer into subscribe data
  * @param dup integer returned - the MQTT dup flag
  * @param packetid integer returned - the MQTT packet identifier
  * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
  * @param count - number of members in the topicFilters and requestedQoSs arrays
  * @param topicFilters - array of topic filter names
  * @param requestedQoSs - array of requested QoS
  * @param buf the raw buffer data, of the correct length determined by the remaining length field
  * @param buflen the length in bytes of the data in the supplied buffer
  * @return the length of the serialized data.  <= 0 indicates error
  */
int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
	int requestedQoSs[], unsigned char* buf, int buflen)
{
	MQTTHeader header = {0};
	unsigned char* curdata = buf;
	unsigned char* enddata = NULL;
	int rc = -1;
	int mylen = 0;

	FUNC_ENTRY;
	header.byte = readChar(&curdata);
	if (header.bits.type != SUBSCRIBE)
		goto exit;
	*dup = header.bits.dup;

	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
	enddata = curdata + mylen;

	*packetid = readInt(&curdata);

	*count = 0;
	while (curdata < enddata)
	{
		if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
			goto exit;
		if (curdata >= enddata) /* do we have enough data to read the req_qos version byte? */
			goto exit;
		requestedQoSs[*count] = readChar(&curdata);
		(*count)++;
	}

	rc = 1;
exit:
	FUNC_EXIT_RC(rc);
	return rc;
}
Ejemplo n.º 7
0
/**
  * Deserializes the supplied (wire) buffer into publish data
  * @param dup returned integer - the MQTT dup flag
  * @param qos returned integer - the MQTT QoS value
  * @param retained returned integer - the MQTT retained flag
  * @param packetid returned integer - the MQTT packet identifier
  * @param topicName returned MQTTString - the MQTT topic in the publish
  * @param payload returned byte buffer - the MQTT publish payload
  * @param payloadlen returned integer - the length of the MQTT payload
  * @param buf the raw buffer data, of the correct length determined by the remaining length field
  * @param buflen the length in bytes of the data in the supplied buffer
  * @return error code.  1 is success
  */
MQTTReturnCode MQTTDeserialize_publish(unsigned char *dup, QoS *qos,
									   unsigned char *retained, uint16_t *packetid,
									   MQTTString* topicName, unsigned char **payload,
									   uint32_t *payloadlen, unsigned char *buf, size_t buflen) {
        MQTTHeader header = {0};
        unsigned char *curdata = buf;
        unsigned char *enddata = NULL;
        MQTTReturnCode rc = FAILURE;
        uint32_t decodedLen = 0;
        uint32_t readBytesLen = 0;

	FUNC_ENTRY;
	if(NULL == dup || NULL == qos || NULL == retained || NULL == packetid) {
		FUNC_EXIT_RC(FAILURE);
		return FAILURE;
	}

	/* Publish header size is at least four bytes.
	 * Fixed header is two bytes.
	 * Variable header size depends on QoS And Topic Name.
	 * QoS level 0 doesn't have a message identifier (0 - 2 bytes)
	 * Topic Name length fields decide size of topic name field (at least 2 bytes)
	 * MQTT v3.1.1 Specification 3.3.1 */
	if(4 > buflen) {
		FUNC_EXIT_RC(MQTTPACKET_BUFFER_TOO_SHORT);
		return MQTTPACKET_BUFFER_TOO_SHORT;
	}

	header.byte = readChar(&curdata);
	if(PUBLISH != header.bits.type) {
		FUNC_EXIT_RC(FAILURE);
		return FAILURE;
	}

	*dup = header.bits.dup;
	*qos = (QoS)header.bits.qos;
	*retained = header.bits.retain;

	/* read remaining length */
	rc = MQTTPacket_decodeBuf(curdata, &decodedLen, &readBytesLen);
	if(SUCCESS != rc) {
		FUNC_EXIT_RC(rc);
		return rc;
	}
	curdata += (readBytesLen);
	enddata = curdata + decodedLen;

	/* do we have enough data to read the protocol version byte? */
	if(SUCCESS != readMQTTLenString(topicName, &curdata, enddata) || (0 > (enddata - curdata))) {
		FUNC_EXIT_RC(FAILURE);
		return FAILURE;
	}

	if(QOS0 != *qos) {
		*packetid = readPacketId(&curdata);
	}

	*payloadlen = (uint32_t)(enddata - curdata);
	*payload = curdata;

	FUNC_EXIT_RC(SUCCESS);
	return SUCCESS;
}