Exemple #1
0
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;
}
Exemple #2
0
/**
 * 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;
}