SkyPortal-plugin/Source/SkyPortal/Public/SkyPortalIO.h

148 lines
3.8 KiB
C++

#pragma once
/*
* This is the bridge between hidapi and unreal and contains all the rawdata of the portal
*/
#include "CoreMinimal.h"
#include "hidapi.h"
#include "SkyPortalFigure.h"
#include "SkyPortalIO.generated.h"
#pragma region Definitions
DECLARE_LOG_CATEGORY_EXTERN(LogHIDApi, Log, All);
DECLARE_LOG_CATEGORY_EXTERN(LogSkyportalIO, Log, All);
constexpr auto write_buf_size = 0x21; //buffer size for all the write command on portal. Should always be 0x21 - 33
constexpr auto TIMEOUT = 30000; //milliseconds
/* Portal physicial device IDs */
const int VendorIds[4] = { 0x12ba, 0x54c, 0x1430, 0x1430 };
const int ProductIds[4] = { 0x150, 0x967, 0x1f17 };
UENUM(BlueprintType)
enum EPortalCommand {
A UMETA(DisplayName = "Activate"),
C UMETA(DisplayName = "Color"),
J UMETA(DisplayName = "Advanced color"),
L UMETA(DisplayName = "Trap color"),
M UMETA(DisplayName = "Music"),
Q UMETA(DisplayName = "Query"),
R UMETA(DisplayName = "Ready"),
S UMETA(DisplayName = "Status")
};
USTRUCT(BlueprintType)
struct FPortalStatusData
{
GENERATED_BODY()
// Array of statuses
UPROPERTY(BlueprintReadOnly, EditFixedSize, Category = "SkyPortal|Figure", meta = (EditFixedOrder))
TArray<EFigureStatus> StatusArray;
// timestamp.
// only one byte long. This means that after the value 0xFF, it overflows back to 0x00.
// Since these are so far apart, it can be assumed that 0x00 is newer than anything in the range 0xF0 - 0xFF.
UPROPERTY(BlueprintReadOnly, Category = "SkyPortal|Figure")
uint8 Counter;
// Should always be true
UPROPERTY(BlueprintReadOnly, Category = "SkyPortal|Figure")
bool bIsReady;
explicit FPortalStatusData(uint8 ArraySize = 16, EFigureStatus DefaultStatus = EFigureStatus::NOT_PRESENT) :
Counter(0),
bIsReady(true)
{
// Initialisation du tableau StatusArray avec 16 éléments par défaut
StatusArray.Init(DefaultStatus, ArraySize);
}
// Overload the == operator
// Different only between
bool operator==(const FPortalStatusData& Other) const
{
if (bIsReady == Other.bIsReady && Counter == Other.Counter) {
if (StatusArray == Other.StatusArray) {
return true;
}
}
return false;
}
// Overload the != operator
bool operator!=(const FPortalStatusData& Other) const
{
return !(*this == Other);
}
};
#pragma endregion
FPortalStatusData ParsePortalStatus(const uint8* StatusResponse);
EPortalCommand GetPortalCommandFromChar(unsigned char Char);
/* Contain all the data that pass inside hidapi write + the number of bytes in case of successful write
*
* @param data all the block data, should be 0x21 sized
* @param BytesTransferred In case of successful write, print the number of byte transfered. Could be used for verifications
*/
USTRUCT()
struct FWriteBlock {
GENERATED_BODY()
unsigned char data[write_buf_size];
int BytesTransferred;
};
/* This class will contain and handle all the low-lewel functions
* Should be able to be called anywhere
*/
UCLASS()
class USkyPortalIO : public UObject
{
GENERATED_BODY()
public:
// Constructor
USkyPortalIO();
/* hidapi will write error message in here*/
UPROPERTY(BlueprintReadOnly)
FString HidError;
/*Portal ready to be listened or to receive commands*/
UPROPERTY(BlueprintReadOnly)
bool bPortalReady = false;
/* Connect to Portal - will write the PortalDevice var if success */
bool OpenPortalHandle();
/* Send block to portal. In windows, don't use the hidapi */
void Write(FWriteBlock* Block);
/* Send raw command to portal */
void WriteRaw(const TArray<uint8>* block);
/* Listen to portal
* @return The data sended by the portal device
*/
uint8* Read();
UFUNCTION()
TArray<uint8> QueryBlock(uint8 characterIndex, uint8 block = 0x00);
/* Close connection to Portal*/
void Close();
private:
/*TODO: Should not be here
bool IsFalsePositive() const;
*/
/* Portal device ref, useful for hidapi commands */
hid_device* PortalDevice;
};