/** * 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; }
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; }