/*
Copyright (c) 2009-2021 Roger Light <roger@atchoo.org>

All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License 2.0
and Eclipse Distribution License v1.0 which accompany this distribution.

The Eclipse Public License is available at
   https://www.eclipse.org/legal/epl-2.0/
and the Eclipse Distribution License is available at
  http://www.eclipse.org/org/documents/edl-v10.php.

SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause

Contributors:
   Roger Light - initial implementation and documentation.
*/

#include "config.h"

#include <assert.h>
#include <stdio.h>
#include <string.h>

#ifdef WITH_BROKER
#  include "mosquitto_broker_internal.h"
#endif

#include "mosquitto.h"
#include "logging_mosq.h"
#include "messages_mosq.h"
#include "mosquitto/mqtt_protocol.h"
#include "net_mosq.h"
#include "packet_mosq.h"
#include "read_handle.h"
#include "send_mosq.h"
#include "util_mosq.h"


int handle__pingreq(struct mosquitto *mosq)
{
	assert(mosq);

	if(mosquitto__get_state(mosq) != mosq_cs_active){
#ifdef WITH_BROKER
		log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PINGREQ before session is active.", mosq->id);
#endif
		return MOSQ_ERR_PROTOCOL;
	}
	if(mosq->in_packet.command != CMD_PINGREQ || mosq->in_packet.remaining_length != 0){
		return MOSQ_ERR_MALFORMED_PACKET;
	}

#ifdef WITH_BROKER
	log__printf(NULL, MOSQ_LOG_DEBUG, "Received PINGREQ from %s", SAFE_PRINT(mosq->id));
	return send__pingresp(mosq);
#else
	return MOSQ_ERR_PROTOCOL;
#endif
}


int handle__pingresp(struct mosquitto *mosq)
{
	assert(mosq);

	if(mosquitto__get_state(mosq) != mosq_cs_active){
#ifdef WITH_BROKER
		log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PINGRESP before session is active.", mosq->id);
#endif
		return MOSQ_ERR_PROTOCOL;
	}
	if(mosq->in_packet.command != CMD_PINGRESP || mosq->in_packet.remaining_length != 0){
		return MOSQ_ERR_MALFORMED_PACKET;
	}

	mosq->ping_t = 0; /* No longer waiting for a PINGRESP. */
#ifdef WITH_BROKER
	if(mosq->bridge == NULL){
		log__printf(NULL, MOSQ_LOG_INFO, "Protocol error from %s: PINGRESP when not a bridge.", mosq->id);
		return MOSQ_ERR_PROTOCOL;
	}
	log__printf(NULL, MOSQ_LOG_DEBUG, "Received PINGRESP from %s", SAFE_PRINT(mosq->id));
#else
	log__printf(mosq, MOSQ_LOG_DEBUG, "Client %s received PINGRESP", SAFE_PRINT(mosq->id));
#endif
	return MOSQ_ERR_SUCCESS;
}

