/**
 * MQTT protocol keepAlive processing.  Sends PINGREQ packets as required.
 * @param now current time
 */
void MQTTProtocol_keepalive(time_t now)
{
	ListElement* current = NULL;

	FUNC_ENTRY;
	ListNextElement(bstate->clients, &current);
	while (current)
	{
		Clients* client =	(Clients*)(current->content);
		ListNextElement(bstate->clients, &current);
#if !defined(NO_BRIDGE)
		if (client->outbound)
		{
			if (client->connected && client->keepAliveInterval > 0
					&& (difftime(now, client->lastContact) >= client->keepAliveInterval))
			{
				if (client->ping_outstanding)
				{
					Log(LOG_INFO, 143, NULL, client->keepAliveInterval, client->clientID);
					MQTTProtocol_closeSession(client, 1);
				}
				else
				{
#if defined(MQTTS)
					if (client->protocol == PROTOCOL_MQTTS)
					{
						int rc = MQTTSPacket_send_pingReq(client);
						if (rc == SOCKET_ERROR)
							MQTTProtocol_closeSession(client, 1);
					}
					else
#endif
						MQTTPacket_send_pingreq(client->socket, client->clientID);
					client->lastContact = now;
					client->ping_outstanding = 1;
				}
			}
		}
		else
#endif
		if (client->connected && client->keepAliveInterval > 0)
		{ /* zero keepalive interval means never disconnect */
			int threshold = client->keepAliveInterval + min((client->keepAliveInterval / 2), 60);
					
			if (difftime(now, client->lastContact) > threshold)
			{
				Log(LOG_INFO, 24, NULL, client->keepAliveInterval, client->clientID);
#if defined(MQTTMP)
				if (client->protocol == PROTOCOL_MQTT_MP)
					MQTTMPProtocol_closeSession(client,1);
#endif
				MQTTProtocol_closeSession(client, 1);
			}
		}
	}
	FUNC_EXIT;
}
/**
 * MQTT protocol keepAlive processing.  Sends PINGREQ packets as required.
 * @param now current time
 */
void MQTTProtocol_keepalive(time_t now)
{
	ListElement* current = NULL;

	FUNC_ENTRY;
	ListNextElement(bstate->clients, &current);
	while (current)
	{
		Clients* client =	(Clients*)(current->content);
		ListNextElement(bstate->clients, &current); 
		if (client->connected && client->keepAliveInterval > 0 &&
			(difftime(now, client->net.lastSent) >= client->keepAliveInterval ||
					difftime(now, client->net.lastReceived) >= client->keepAliveInterval))
		{
			if (client->ping_outstanding == 0)
			{
				if (Socket_noPendingWrites(client->net.socket))
				{
					if (MQTTPacket_send_pingreq(&client->net, client->clientID) != TCPSOCKET_COMPLETE)
					{
						Log(TRACE_PROTOCOL, -1, "Error sending PINGREQ for client %s on socket %d, disconnecting", client->clientID, client->net.socket);
						MQTTProtocol_closeSession(client, 1);
					}
					else
					{
						client->net.lastSent = now;
						client->ping_outstanding = 1;
					}
				}
			}
			else
			{
				Log(TRACE_PROTOCOL, -1, "PINGRESP not received in keepalive interval for client %s on socket %d, disconnecting", client->clientID, client->net.socket);
				MQTTProtocol_closeSession(client, 1);
			}
		}
	}
	FUNC_EXIT;
}