int MQTTSProtocol_handlePubrecs(void* pack, int sock, char* clientAddr, Clients* client) { int rc = 0; MQTTS_PubRec* pubrec = (MQTTS_PubRec*)pack; FUNC_ENTRY; Log(LOG_PROTOCOL, 15, NULL, pubrec->msgId, client->clientID); /* look for the message by message id in the records of outbound messages for this client */ client->outboundMsgs->current = NULL; if (ListFindItem(client->outboundMsgs, &(pubrec->msgId), messageIDCompare) == NULL) { /* No Dupe flag in MQTTs if (pubrec->header.dup == 0) */ Log(LOG_WARNING, 50, NULL, "PUBREC", client->clientID, pubrec->msgId); } else { Messages* m = (Messages*)(client->outboundMsgs->current->content); if (m->qos != 2) { /* No Dupe flag in MQTTs if (pubrec->header.dup == 0) */ Log(LOG_WARNING, 51, NULL, "PUBREC", client->clientID, pubrec->msgId, m->qos); } else if (m->nextMessageType != PUBREC) { /* No Dupe flag in MQTTs if (pubrec->header.dup == 0) */ Log(LOG_WARNING, 52, NULL, "PUBREC", client->clientID, pubrec->msgId); } else { rc = MQTTSPacket_send_pubrel(client, pubrec->msgId); m->nextMessageType = PUBCOMP; time(&(m->lastTouch)); } } MQTTSPacket_free_packet(pack); FUNC_EXIT_RC(rc); return rc; }
/** * MQTT retry processing per client * @param now current time * @param client - the client to which to apply the retry processing */ void MQTTProtocol_retries(time_t now, Clients* client) { ListElement* outcurrent = NULL; FUNC_ENTRY; #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTTS) { if (client->pendingRegistration != NULL && difftime(now, client->pendingRegistration->sent) > bstate->retry_interval) { Registration* reg = client->pendingRegistration->registration; time(&client->pendingRegistration->sent); /* NB: no dup bit for these packets */ if (MQTTSPacket_send_register(client, reg->id, reg->topicName, client->pendingRegistration->msgId) == SOCKET_ERROR) { client->good = 0; //TODO: update message Log(LOG_WARNING, 29, NULL, client->clientID, client->socket); MQTTProtocol_closeSession(client, 1); client = NULL; } } #if !defined(NO_BRIDGE) if (client->pendingSubscription != NULL && difftime(now, client->pendingSubscription->sent) > bstate->retry_interval) { time(&client->pendingSubscription->sent); if (MQTTSPacket_send_subscribe(client, client->pendingSubscription->topicName,client->pendingSubscription->qos, client->pendingSubscription->msgId) == SOCKET_ERROR) { client->good = 0; //TODO: update message Log(LOG_WARNING, 29, NULL, client->clientID, client->socket); MQTTProtocol_closeSession(client, 1); client = NULL; } } #endif } #endif while (client && ListNextElement(client->outboundMsgs, &outcurrent) && client->connected && client->good && /* client is connected and has no errors */ Socket_noPendingWrites(client->socket)) /* there aren't any previous packets still stacked up on the socket */ { Messages* m = (Messages*)(outcurrent->content); if (difftime(now, m->lastTouch) > bstate->retry_interval) { if (m->qos == 1 || (m->qos == 2 && m->nextMessageType == PUBREC)) { Publish publish; int rc; Log(LOG_INFO, 28, NULL, client->clientID, client->socket, m->msgid); publish.msgId = m->msgid; publish.topic = m->publish->topic; publish.payload = m->publish->payload; publish.payloadlen = m->publish->payloadlen; #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTTS) { if (MQTTSProtocol_startPublishCommon(client, &publish, 1, m->qos, m->retain) == SOCKET_ERROR) { client->good = 0; Log(LOG_WARNING, 29, NULL, client->clientID, client->socket); MQTTProtocol_closeSession(client, 1); client = NULL; } else time(&(m->lastTouch)); } else { #endif rc = MQTTPacket_send_publish(&publish, 1, m->qos, m->retain, client->socket, client->clientID); if (rc == SOCKET_ERROR) { client->good = 0; Log(LOG_WARNING, 29, NULL, client->clientID, client->socket); MQTTProtocol_closeSession(client, 1); client = NULL; } else { if (m->qos == 0 && rc == TCPSOCKET_INTERRUPTED) MQTTProtocol_storeQoS0(client, &publish); time(&(m->lastTouch)); } #if defined(MQTTS) } #endif } else if (m->qos && m->nextMessageType == PUBCOMP) { Log(LOG_WARNING, 30, NULL, client->clientID, m->msgid); #if defined(MQTTS) if (client->protocol == PROTOCOL_MQTTS) { /* NB: no dup bit for PUBREL */ if (MQTTSPacket_send_pubrel(client, m->msgid) == SOCKET_ERROR) { client->good = 0; Log(LOG_WARNING, 18, NULL, client->clientID, client->socket, Socket_getpeer(client->socket)); MQTTProtocol_closeSession(client, 1); client = NULL; } else time(&(m->lastTouch)); } else #endif if (MQTTPacket_send_pubrel(m->msgid, 1, client->socket, client->clientID) != TCPSOCKET_COMPLETE) { client->good = 0; Log(LOG_WARNING, 18, NULL, client->clientID, client->socket, Socket_getpeer(client->socket)); MQTTProtocol_closeSession(client, 1); client = NULL; } else time(&(m->lastTouch)); } /* break; why not do all retries at once? */ } } FUNC_EXIT; }