
#ifndef ETHERCAT_MASTER_CORE_H
#define ETHERCAT_MASTER_CORE_H

#include "../ethercat_types.h"
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

#ifndef DYNAMIC_LOAD

uint16_t Initialize(void);

uint16_t InitializeSpecificMaster(uint16_t master_index);

void     Dispose(uint16_t master_index);

void     Start(uint16_t master_index);

void     Stop(uint16_t master_index);

int      GetMaxMasterInstances(void);

uint16_t SetNetwork(uint16_t master_index, const char* ifPrimary, const char* ifSecondary);

BOOL     SetState(uint16_t master_index, int state);

BOOL     SetStateWithTimeout(uint16_t master_index, int state, uint32_t timeout_ms);

BOOL     SetSlaveStateWithTimeout(uint16_t master_index, uint16_t slave_index, int state, uint32_t timeout_ms);

BOOL     SetStateSequence(uint16_t master_index, int target_state, uint32_t timeout_ms);

BOOL     SetStateWithStartup(uint16_t master_index, int target_state, uint32_t timeout_ms);

uint8_t  GetLinkStatus(uint16_t master_index);

uint8_t  GetSlaveState(uint16_t master_index, uint16_t slave_index);

uint16_t GetSlaveALStatusCode(uint16_t master_index, uint16_t slave_index);

uint8_t  GetIO(uint16_t master_index, uint16_t slave_index,
               int32_t* out_byte_size, uint8_t** out_byte,
               int32_t* in_byte_size, uint8_t** in_byte);

void     LockIOmap(uint16_t master_index);
void     UnlockIOmap(uint16_t master_index);

void     WriteSlaveOutput(uint16_t master_index, uint16_t slave_index,
                          const uint8_t* data, uint32_t size);
void     WriteSlaveOutputByte(uint16_t master_index, uint16_t slave_index,
                              uint32_t offset, uint8_t value);

void     SetMutexProtection(uint16_t master_index, BOOL enable);
BOOL     GetMutexProtection(uint16_t master_index);

BOOL     SetSlaveGroup(uint16_t master_index, uint16_t slave_index, uint8_t group);
uint8_t  GetSlaveGroup(uint16_t master_index, uint16_t slave_index);
BOOL     SetGroupCycleDivider(uint16_t master_index, uint8_t group, uint8_t divider);
uint8_t  GetGroupCycleDivider(uint16_t master_index, uint8_t group);
BOOL     SetGroupEnabled(uint16_t master_index, uint8_t group, BOOL enabled);
BOOL     GetGroupEnabled(uint16_t master_index, uint8_t group);
uint16_t GetGroupExpectedWKC(uint16_t master_index, uint8_t group);
uint8_t  GetActiveGroupCount(uint16_t master_index);
uint16_t GetGroupSlaveCount(uint16_t master_index, uint8_t group);

void     FreeMemory(void* ptr);

void     SetPDOLogging(BOOL enable);
void     SetMailboxLogging(BOOL enable);
void     SetDebugLogging(BOOL enable);

BOOL     IsWdkAvailable(uint16_t master_index);
BOOL     SetWdkMode(uint16_t master_index, BOOL enable);
BOOL     GetWdkMode(uint16_t master_index);
BOOL     StartWdkRT(uint16_t master_index, uint32_t cycle_us, uint32_t cpu_index);
BOOL     StopWdkRT(uint16_t master_index);

BOOL     SetUdpMode(uint16_t master_index, BOOL enable);
BOOL     GetUdpMode(uint16_t master_index);
BOOL     IsUdpAvailable(uint16_t master_index);

void     AbortScan(void);
void     ResetScanAbort(void);
void     AbortNetwork(void);
void     ResetAbortNetwork(void);
void     EmergencyCloseNics(void);

int      GetAvailableCpuCores(void);
BOOL     SetMasterCpuAffinity(uint16_t master_index, int cpu_core);
BOOL     SetProcessCpuAffinity(int cpu_core);
BOOL     SetPDOThreadCpuAffinity(uint16_t master_index, int cpu_core);
int      GetPDOThreadCpuAffinity(uint16_t master_index);
BOOL     ApplyRealtimeOptimizations(void);
BOOL     RemoveRealtimeOptimizations(void);
BOOL     GetRealtimeOptimizationsStatus(void);
uint32_t GetTimingMode(uint16_t master_index);

int      DarraValidateTimerAccuracy(uint32_t expected_usec, uint32_t tolerance_usec);

void     SetRedProcessdata(int mode);
int      GetRedProcessdata(void);
BOOL     EnableRedundancy(uint16_t master_index, BOOL enable);

void*    GetRedundancyStatus(uint16_t master_index);
BOOL     ForceRedundancyFailover(uint16_t master_index);
BOOL     CheckRedundancyHealth(uint16_t master_index);

#endif

#ifdef __cplusplus
}
#endif

#endif
