#include <string.h>
#include "radio.h"
#include "encryption.h"
#include "crc.h"

bool Send_Message(PACKET * packet, uint64_t * salt);

bool Send_Get_Salt_Message(PACKET * packet, uint64_t * salt)
{
	memset((uint8_t*)packet, 0, PACKET_LENGTH); //Reinitialize the buffer with zeros

	packet->payload.reportData.packetIdentifier.elementCount = 0;
	packet->payload.reportData.packetIdentifier.packetType = PACKET_TYPE_GET_SALT;

	return Send_Message(packet, salt);
}

bool Send_Report_Message(PACKET * packet, uint64_t * salt, struct bme280_data * sensorData)
{
	packet->payload.reportData.packetIdentifier.elementCount = 3;
	packet->payload.reportData.packetIdentifier.packetType = PACKET_TYPE_REPORT;

	/* Fill in the payload */
	packet->payload.reportData.valueTypeTemperature = VALUE_TYPE_TEMPERATURE;
	packet->payload.reportData.temperature = sensorData->temperature/10;
	packet->payload.reportData.valueTypePressure = VALUE_TYPE_PRESSURE;
	packet->payload.reportData.pressure = sensorData->pressure;
	packet->payload.reportData.valueTypeHumidity = VALUE_TYPE_HUMIDITY;
	packet->payload.reportData.humidity = sensorData->humidity * 100/1024;

	return Send_Message(packet, salt);
}

bool Send_Message(PACKET * packet, uint64_t * salt)
{
	bool success;

	uint16_t crc;
	(*salt) &= ~(1ull<<63); /* Set the most significant bit to 0 to indicate a packet from the device to the base station */

	packet->salt = *salt;

	/* Calculate the CRC */
	crc = Calculate_Crc(packet->payload.buffer, PACKET_PAYLOAD_BUFFER_LENGTH);
	packet->crc = crc;

	Encrypt((uint32_t*) packet->payload.buffer,
	        PACKET_PAYLOAD_BUFFER_LENGTH + sizeof(crc),
	        *salt);

	success = NRF24L01_Send_Message((uint8_t*)packet, PACKET_LENGTH);

	/* Increment salt */
	(*salt) += (1 << 8);

	return success;
}

bool Read_Salt_Message(PACKET * packet, uint64_t * salt)
{
	uint16_t crcRemainder = 0xFFFF;
	uint64_t baseStationSalt = 0x0;

	baseStationSalt = packet->salt;
	Decrypt((uint32_t*)packet->payload.buffer,
	        PACKET_PAYLOAD_BUFFER_LENGTH + sizeof(packet->crc),
	        baseStationSalt);

	crcRemainder = Calculate_Crc(packet->payload.buffer,
	                             PACKET_PAYLOAD_BUFFER_LENGTH + sizeof(packet->crc));
	if (crcRemainder != 0)
	{
		return false;
	}

	if ((packet->payload.saltData.packetIdentifier.packetType != PACKET_TYPE_SALT) ||
	    (packet->payload.saltData.packetIdentifier.elementCount != 0))
	{
		return false;
	}

	memcpy((uint8_t*)salt, packet->payload.saltData.salt, 7);
	*salt = (*salt) << 8;

	return true;
}
