//////////////////////////////////////////////////////////////////
//
// App:			Support
// Author:		Milan Korinek
// Version:		1.0
// Notice:		Loging (only for debug!) and support functions
//////////////////////////////////////////////////////////////////

#include "support.h"
#include "string.h"


const DeviceStateInternal_t DEVICE_STATE_INTERNAL_DEFAULT = _DEVICE_STATE_INTERNAL_DEFAULT;

DeviceStateInternal_t DeviceStateInt = _DEVICE_STATE_INTERNAL_DEFAULT;

uint8_t buffer_control[EP_CONTROL_BUFFER_SIZE];
bool buffer_control_lock = false;



void PrintRawPacket(_In_ UINT8 * payload, _In_ UINT payload_length)
{
	#ifndef DIO_NDEBUG
	UINT i;

	debug_func_begin(DIO_SEVERITY_CRITICAL, "Packet dump (lenght = %d):\n", (int)payload_length);
	for (i = 0; i < payload_length; i++) {
		debug_printf(DIO_SEVERITY_CRITICAL, "0x%02X ", (unsigned int)payload[i]);
	}
	debug_printf(DIO_SEVERITY_CRITICAL, "\n");

	#endif
}


void Parse_Copy(_In_ UINT8 * source, _Inout_ UINT * sourcePos, _Out_ void * dest, _In_ size_t size)
{
	memcpy(dest, &source[*sourcePos], size);
	*sourcePos += size;
}

void Serialize_Copy(_In_ void * source, _In_ size_t size, _Out_ UINT8 * dest, _Inout_ UINT * destPos)
{
	memcpy(&dest[*destPos], source, size);
	*destPos += size;
}


void Parse_DIO_Behavior_t(_In_ UINT8 * buffer, _Inout_ UINT * buffPos, _Out_ DIO_Behavior_t * structure)
{
	structure->Mode = to_enum(buffer[(*buffPos)++], DIO_E_Mode_t);
}

void Serialize_DIO_Behavior_t(_In_ DIO_Behavior_t * structure, _Out_ UINT8 * buffer, _Inout_ UINT * buffPos)
{
	buffer[(*buffPos)++] = (UINT8)structure->Mode;
}

void Parse_DIO_PortConfig_t(_In_ UINT8 * buffer, _Inout_ UINT * buffPos, _Out_ DIO_PortConfig_t * structure)
{
	Parse_Copy(buffer, buffPos, &structure->OutputDefault, sizeof(structure->OutputDefault));
	structure->PortDirection = to_enum(buffer[(*buffPos)++], DIO_E_PortDir_t);
	structure->PullResistors = to_enum(buffer[(*buffPos)++], DIO_E_PullRes_t);
}

void Serialize_DIO_PortConfig_t(_In_ DIO_PortConfig_t * structure, _Out_ UINT8 * buffer, _Inout_ UINT * buffPos)
{
	Serialize_Copy(&structure->OutputDefault, sizeof(structure->OutputDefault), buffer, buffPos);
	buffer[(*buffPos)++] = (UINT8)structure->PortDirection;
	buffer[(*buffPos)++] = (UINT8)structure->PullResistors;
}


BOOL ParseDeviceConfigurationPacket(_In_ UINT8 * payload,
_In_ UINT payload_length,
_Out_ E_DeviceState_t * DeviceState,
_Out_ DIO_Behavior_t * DeviceBehavior,
_Out_ DIO_PortConfig_t PortsConfiguration[DIO_MAX_PORTS])
{
	UINT buffPos = 0;
	int i;

	*DeviceState = to_enum(payload[buffPos++], E_DeviceState_t); // Only host read
	Parse_DIO_Behavior_t(payload, &buffPos, DeviceBehavior);
	
	for (i = 0; i < DIO_MAX_PORTS; i++) {
		Parse_DIO_PortConfig_t(payload, &buffPos, &PortsConfiguration[i]);
	}

	return TRUE;
}

BOOL CreateDeviceConfigurationPacket(		_In_ E_DeviceState_t DeviceState,
_In_ DIO_Behavior_t * DeviceBehavior,
_In_ DIO_PortConfig_t PortsConfiguration[DIO_MAX_PORTS],
_Out_ UINT8 * payload,
_Out_ UINT * payload_length)
{
	int i;
	*payload_length = 0;
	payload[(*payload_length)++] = (UINT8)DeviceState;		// From device to host only
	Serialize_DIO_Behavior_t(DeviceBehavior, payload, payload_length);

	for (i = 0; i < DIO_MAX_PORTS; i++) {
		Serialize_DIO_PortConfig_t(&PortsConfiguration[i], payload, payload_length);
	}

	return TRUE;
}
