Example #1
0
/**
 * Reads one MQTT packet from a socket.
 * @param socket a socket from which to read an MQTT packet
 * @param error pointer to the error code which is completed if no packet is returned
 * @return the packet structure or NULL if there was an error
 */
void* MQTTPacket_Factory(int socket, int* error)
{
	char* data = NULL;
	static Header header;
	int remaining_length, ptype;
	void* pack = NULL;
	int actual_len = 0;

	FUNC_ENTRY;
	*error = SOCKET_ERROR;  /* indicate whether an error occurred, or not */

	/* read the packet data from the socket */
	if ((*error = Socket_getch(socket, &(header.byte))) != TCPSOCKET_COMPLETE)   /* first byte is the header byte */
		goto exit; /* packet not read, *error indicates whether SOCKET_ERROR occurred */

	/* now read the remaining length, so we know how much more to read */
	if ((*error = MQTTPacket_decode(socket, &remaining_length)) != TCPSOCKET_COMPLETE)
		goto exit; /* packet not read, *error indicates whether SOCKET_ERROR occurred */

	/* now read the rest, the variable header and payload */
	if ((data = Socket_getdata(socket, remaining_length, &actual_len)) == NULL)
	{
		*error = SOCKET_ERROR;
		goto exit; /* socket error */
	}

	if (actual_len != remaining_length)
		*error = TCPSOCKET_INTERRUPTED;
	else
	{
		ptype = header.bits.type;
		if (ptype < CONNECT || ptype > DISCONNECT || new_packets[ptype] == NULL)
			Log(TRACE_MIN, 2, NULL, ptype);
		else
		{
			if ((pack = (*new_packets[ptype])(header.byte, data, remaining_length)) == NULL)
				*error = BAD_MQTT_PACKET;
#if !defined(NO_PERSISTENCE)
			else if (header.bits.type == PUBLISH && header.bits.qos == 2)
			{
				int buf0len;
				char *buf = malloc(10);
				buf[0] = header.byte;
				buf0len = 1 + MQTTPacket_encode(&buf[1], remaining_length);
				*error = MQTTPersistence_put(socket, buf, buf0len, 1,
					&data, &remaining_length, header.bits.type, ((Publish *)pack)->msgId, 1);
				free(buf);
			}
#endif
		}
	}
exit:
	FUNC_EXIT_RC(*error);
	return pack;
}
Example #2
0
void* MQTTPacket_Factory(networkHandles* net, int* error)
{
	static Header header;
	int ptype;
	void* pack = NULL;

	FUNC_ENTRY;
	*error = SOCKET_ERROR;  // Indicate whether an error occurred, or not

	/* read the packet data from the socket */
    #if defined(OPENSSL)
	*error = (net->ssl) ? SSLSocket_getch(net->ssl, net->socket, &header.byte) : Socket_getch(net->socket, &header.byte); 
    #else
	*error = Socket_getch(net->socket, &header.byte);
    #endif
    
	if (*error != TCPSOCKET_COMPLETE)
    {   // First byte is the header byte
        goto exit;  // packet not read, *error indicates whether SOCKET_ERROR occurred.
    }

	// Now read the remaining length, so we know how much more to read
    size_t remaining_length;
    
    if ((*error = MQTTPacket_decode(net, &remaining_length)) != TCPSOCKET_COMPLETE) {
        goto exit; // Packet not read, *error indicates whether SOCKET_ERROR occurred.
    }

	// Now read the rest, the variable header and payload.
    size_t actual_len = 0;
    
    #if defined(OPENSSL)
	char* data = (net->ssl) ? SSLSocket_getdata(net->ssl, net->socket, remaining_length, &actual_len) :  Socket_getdata(net->socket, remaining_length, &actual_len);
    #else
	char* data = Socket_getdata(net->socket, remaining_length, &actual_len);
    #endif
    
	if (data == NULL)
	{
		*error = SOCKET_ERROR;
		goto exit; // Socket error
	}

	if (actual_len != remaining_length)
    {
		*error = TCPSOCKET_INTERRUPTED;
    }
	else
	{
		ptype = header.bits.type;
		if (ptype < CONNECT || ptype > DISCONNECT || new_packets[ptype] == NULL)
			Log(TRACE_MIN, 2, NULL, ptype);
		else
		{
			if ((pack = (*new_packets[ptype])(header.byte, data, remaining_length)) == NULL)
				*error = BAD_MQTT_PACKET;
            #if !defined(NO_PERSISTENCE)
			else if (header.bits.type == PUBLISH && header.bits.qos == 2)
			{
				int buf0len;
				char *buf = malloc(10);
				buf[0] = header.byte;
				buf0len = 1 + MQTTPacket_encode(&buf[1], remaining_length);
				size_t remaining_length_new = remaining_length;
				*error = MQTTPersistence_put(net->socket, buf, buf0len, 1, &data, &remaining_length_new, header.bits.type, ((Publish *)pack)->msgId, 1);
				free(buf);
			}
            #endif
		}
	}
	if (pack)
		time(&(net->lastReceived));
exit:
	FUNC_EXIT_RC(*error);
	return pack;
}