/** * Process an incoming pubrel packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePubrels(void* pack, int sock, Clients* client) { Pubrel* pubrel = (Pubrel*)pack; //Clients* client = (Clients*)(TreeFind(bstate->clients, &sock)->content); int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; Log(LOG_PROTOCOL, 17, NULL, sock, client->clientID, pubrel->msgId); /* look for the message by message id in the records of inbound messages for this client */ if (ListFindItem(client->inboundMsgs, &(pubrel->msgId), messageIDCompare) == NULL) { if (pubrel->header.bits.dup == 0) Log(LOG_WARNING, 50, NULL, "PUBREL", client->clientID, pubrel->msgId); /* Apparently this is "normal" behaviour, so we don't need to issue a warning */ rc = MQTTPacket_send_pubcomp(pubrel->msgId, sock, client->clientID); } else { Messages* m = (Messages*)(client->inboundMsgs->current->content); if (m->qos != 2) Log(LOG_WARNING, 51, NULL, "PUBREL", client->clientID, pubrel->msgId, m->qos); else if (m->nextMessageType != PUBREL) Log(LOG_WARNING, 52, NULL, "PUBREL", client->clientID, pubrel->msgId); else { Publish publish; char* saved_clientid = malloc(strlen(client->clientID) + 1); strcpy(saved_clientid, client->clientID); /* send pubcomp before processing the publications because a lot of return publications could fill up the socket buffer */ rc = MQTTPacket_send_pubcomp(pubrel->msgId, sock, client->clientID); publish.header.bits.qos = m->qos; publish.header.bits.retain = m->retain; publish.msgId = m->msgid; publish.topic = m->publish->topic; publish.payload = m->publish->payload; publish.payloadlen = m->publish->payloadlen; ++(bstate->msgs_received); bstate->bytes_received += m->publish->payloadlen; Protocol_processPublication(&publish, client->clientID); /* The client structure might have been removed in processPublication, on error */ if (TreeFind(bstate->clients, &sock) || TreeFind(bstate->disconnected_clients, saved_clientid)) { ListRemove(client->inboundMsgs, m); MQTTProtocol_removePublication(m->publish); } free(saved_clientid); } } free(pack); FUNC_EXIT_RC(rc); return rc; }
/** * Process an incoming pubrel packet for a socket * @param pack pointer to the publish packet * @param sock the socket on which the packet was received * @return completion code */ int MQTTProtocol_handlePubrels(void* pack, int sock) { Pubrel* pubrel = (Pubrel*)pack; Clients* client = NULL; int rc = TCPSOCKET_COMPLETE; FUNC_ENTRY; client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content); Log(LOG_PROTOCOL, 17, NULL, sock, client->clientID, pubrel->msgId); /* look for the message by message id in the records of inbound messages for this client */ if (ListFindItem(client->inboundMsgs, &(pubrel->msgId), messageIDCompare) == NULL) { if (pubrel->header.bits.dup == 0) Log(TRACE_MIN, 3, NULL, "PUBREL", client->clientID, pubrel->msgId); else /* Apparently this is "normal" behaviour, so we don't need to issue a warning */ rc = MQTTPacket_send_pubcomp(pubrel->msgId, &client->net, client->clientID); } else { Messages* m = (Messages*)(client->inboundMsgs->current->content); if (m->qos != 2) Log(TRACE_MIN, 4, NULL, "PUBREL", client->clientID, pubrel->msgId, m->qos); else if (m->nextMessageType != PUBREL) Log(TRACE_MIN, 5, NULL, "PUBREL", client->clientID, pubrel->msgId); else { Publish publish; /* send pubcomp before processing the publications because a lot of return publications could fill up the socket buffer */ rc = MQTTPacket_send_pubcomp(pubrel->msgId, &client->net, client->clientID); publish.header.bits.qos = m->qos; publish.header.bits.retain = m->retain; publish.msgId = m->msgid; publish.topic = m->publish->topic; publish.topiclen = m->publish->topiclen; publish.payload = m->publish->payload; publish.payloadlen = m->publish->payloadlen; Protocol_processPublication(&publish, client); #if !defined(NO_PERSISTENCE) rc += MQTTPersistence_remove(client, PERSISTENCE_PUBLISH_RECEIVED, m->qos, pubrel->msgId); #endif ListRemove(&(state.publications), m->publish); ListRemove(client->inboundMsgs, m); ++(state.msgs_received); } } free(pack); FUNC_EXIT_RC(rc); return rc; }