
use std::os::raw::{c_char, c_int, c_void};

pub const CORE_OP_21: u32 = 0x44525421;
pub const CORE_OP_22: u32 = 0x44525422;
pub const CORE_OP_23: u32 = 0x44525423;
pub const CORE_OP_24: u32 = 0x44525424;
pub const CORE_OP_25: u32 = 0x44525425;
pub const CORE_OP_26: u32 = 0x44525426;
pub const CORE_OP_27: u32 = 0x44525427;
pub const CORE_OP_28: u32 = 0x44525428;
pub const CORE_FLAG_01: u32 = 0x00000001;

pub const EC_STATE_INIT: u8 = 0x01;
pub const EC_STATE_PRE_OP: u8 = 0x02;
pub const EC_STATE_BOOT: u8 = 0x03;
pub const EC_STATE_SAFE_OP: u8 = 0x04;
pub const EC_STATE_OPERATIONAL: u8 = 0x08;
pub const EC_STATE_ACK: u8 = 0x10;

pub const TRANS_IP: u8 = 0;
pub const TRANS_PS: u8 = 1;
pub const TRANS_SO: u8 = 2;
pub const TRANS_OS: u8 = 3;
pub const TRANS_SP: u8 = 4;
pub const TRANS_PI: u8 = 5;

pub const TIMING_BEFORE: u8 = 0;
pub const TIMING_AFTER: u8 = 1;

#[repr(C, packed)]
#[derive(Clone, Copy)]
pub struct DllVersionInfo {
    pub major: u16,
    pub minor: u16,
    pub patch: u16,
    pub build: u16,
    pub build_date: [u8; 32],
}

impl std::fmt::Debug for DllVersionInfo {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

        let major = unsafe { std::ptr::addr_of!(self.major).read_unaligned() };
        let minor = unsafe { std::ptr::addr_of!(self.minor).read_unaligned() };
        let patch = unsafe { std::ptr::addr_of!(self.patch).read_unaligned() };
        let build = unsafe { std::ptr::addr_of!(self.build).read_unaligned() };
        let build_date = unsafe { std::ptr::addr_of!(self.build_date).read_unaligned() };
        f.debug_struct("DllVersionInfo")
            .field("major", &major)
            .field("minor", &minor)
            .field("patch", &patch)
            .field("build", &build)
            .field("build_date", &build_date)
            .finish()
    }
}

#[repr(C, packed(4))]
#[derive(Clone, Copy)]
pub struct DriverVersionInfo {
    pub major: u32,
    pub minor: u32,
    pub build: u32,
    pub build_date: [u8; 32],
    pub driver_name: [u8; 32],
    pub available: u32,
    pub error_code: u32,
}

impl std::fmt::Debug for DriverVersionInfo {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let major = unsafe { std::ptr::addr_of!(self.major).read_unaligned() };
        let minor = unsafe { std::ptr::addr_of!(self.minor).read_unaligned() };
        let build = unsafe { std::ptr::addr_of!(self.build).read_unaligned() };
        let available = unsafe { std::ptr::addr_of!(self.available).read_unaligned() };
        let error_code = unsafe { std::ptr::addr_of!(self.error_code).read_unaligned() };
        f.debug_struct("DriverVersionInfo")
            .field("major", &major)
            .field("minor", &minor)
            .field("build", &build)
            .field("available", &available)
            .field("error_code", &error_code)
            .finish()
    }
}

#[repr(C, packed)]
#[derive(Clone, Copy)]
pub struct StartupParam {
    pub index: u16,
    pub sub_index: u8,
    pub data: [u8; 256],
    pub data_len: u16,
    pub transition: u8,
    pub timing: u8,
    pub priority: u16,
    pub complete_access: u8,
    pub is_register_write: u8,
}

impl std::fmt::Debug for StartupParam {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

        let index = unsafe { std::ptr::addr_of!(self.index).read_unaligned() };
        let sub_index = unsafe { std::ptr::addr_of!(self.sub_index).read_unaligned() };
        let data_len = unsafe { std::ptr::addr_of!(self.data_len).read_unaligned() };
        let transition = unsafe { std::ptr::addr_of!(self.transition).read_unaligned() };
        let timing = unsafe { std::ptr::addr_of!(self.timing).read_unaligned() };
        let priority = unsafe { std::ptr::addr_of!(self.priority).read_unaligned() };
        let ca = unsafe { std::ptr::addr_of!(self.complete_access).read_unaligned() };
        let rw = unsafe { std::ptr::addr_of!(self.is_register_write).read_unaligned() };
        f.debug_struct("StartupParam")
            .field("index", &index)
            .field("sub_index", &sub_index)
            .field("data_len", &data_len)
            .field("transition", &transition)
            .field("timing", &timing)
            .field("priority", &priority)
            .field("complete_access", &ca)
            .field("is_register_write", &rw)
            .finish()
    }
}

#[repr(C, packed)]
#[derive(Clone, Copy)]
pub struct SiiGeneralInfo {
    pub group_idx: u8,
    pub image_idx: u8,
    pub order_idx: u8,
    pub name_idx: u8,
    pub coe_details: u8,
    pub foe_details: u8,
    pub eoe_details: u8,
    pub soe_details: u8,
    pub flags: u8,
    pub ebus_current_ma: i16,
    pub physical_port: u16,
    pub reserved: [u8; 8],
}

impl std::fmt::Debug for SiiGeneralInfo {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let group_idx = unsafe { std::ptr::addr_of!(self.group_idx).read_unaligned() };
        let image_idx = unsafe { std::ptr::addr_of!(self.image_idx).read_unaligned() };
        let order_idx = unsafe { std::ptr::addr_of!(self.order_idx).read_unaligned() };
        let name_idx = unsafe { std::ptr::addr_of!(self.name_idx).read_unaligned() };
        let coe = unsafe { std::ptr::addr_of!(self.coe_details).read_unaligned() };
        let foe = unsafe { std::ptr::addr_of!(self.foe_details).read_unaligned() };
        let eoe = unsafe { std::ptr::addr_of!(self.eoe_details).read_unaligned() };
        let soe = unsafe { std::ptr::addr_of!(self.soe_details).read_unaligned() };
        let flags = unsafe { std::ptr::addr_of!(self.flags).read_unaligned() };
        let ebus = unsafe { std::ptr::addr_of!(self.ebus_current_ma).read_unaligned() };
        let port = unsafe { std::ptr::addr_of!(self.physical_port).read_unaligned() };
        f.debug_struct("SiiGeneralInfo")
            .field("group_idx", &group_idx)
            .field("image_idx", &image_idx)
            .field("order_idx", &order_idx)
            .field("name_idx", &name_idx)
            .field("coe_details", &coe)
            .field("foe_details", &foe)
            .field("eoe_details", &eoe)
            .field("soe_details", &soe)
            .field("flags", &flags)
            .field("ebus_current_ma", &ebus)
            .field("physical_port", &port)
            .finish()
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct WatchdogConfig {
    pub wd_divider: u16,
    pub wd_time_pdi: u16,
    pub wd_time_pd: u16,
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct WatchdogStatus {
    pub wd_status: u8,
    pub wd_counter: u8,
    pub wd_divider: u16,
    pub wd_time_pd: u16,
}

#[repr(C, packed)]
#[derive(Clone, Copy)]
pub struct EmcyRecord {

    pub error_code: u16,

    pub error_register: u8,

    pub data: [u8; 5],

    pub slave_index: u16,

    pub timestamp_ms: u32,
}

impl Default for EmcyRecord {
    fn default() -> Self {
        Self {
            error_code: 0,
            error_register: 0,
            data: [0; 5],
            slave_index: 0,
            timestamp_ms: 0,
        }
    }
}

impl std::fmt::Debug for EmcyRecord {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

        let error_code = unsafe { std::ptr::addr_of!(self.error_code).read_unaligned() };
        let error_register = unsafe { std::ptr::addr_of!(self.error_register).read_unaligned() };
        let data = unsafe { std::ptr::addr_of!(self.data).read_unaligned() };
        let slave_index = unsafe { std::ptr::addr_of!(self.slave_index).read_unaligned() };
        let timestamp_ms = unsafe { std::ptr::addr_of!(self.timestamp_ms).read_unaligned() };
        f.debug_struct("EmcyRecord")
            .field("error_code", &error_code)
            .field("error_register", &error_register)
            .field("data", &data)
            .field("slave_index", &slave_index)
            .field("timestamp_ms", &timestamp_ms)
            .finish()
    }
}

#[repr(C, packed)]
#[derive(Clone, Copy)]
pub struct TopologyNode {

    pub slave_index: u16,

    pub config_addr: u16,

    pub parent_index: u16,

    pub entry_port: u8,

    pub active_ports: u8,

    pub topology: u8,

    pub port_type: u8,
}

impl std::fmt::Debug for TopologyNode {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

        let slave_index = unsafe { std::ptr::addr_of!(self.slave_index).read_unaligned() };
        let config_addr = unsafe { std::ptr::addr_of!(self.config_addr).read_unaligned() };
        let parent_index = unsafe { std::ptr::addr_of!(self.parent_index).read_unaligned() };
        let entry_port = unsafe { std::ptr::addr_of!(self.entry_port).read_unaligned() };
        let active_ports = unsafe { std::ptr::addr_of!(self.active_ports).read_unaligned() };
        let topology = unsafe { std::ptr::addr_of!(self.topology).read_unaligned() };
        let port_type = unsafe { std::ptr::addr_of!(self.port_type).read_unaligned() };
        f.debug_struct("TopologyNode")
            .field("slave_index", &slave_index)
            .field("config_addr", &config_addr)
            .field("parent_index", &parent_index)
            .field("entry_port", &entry_port)
            .field("active_ports", &active_ports)
            .field("topology", &topology)
            .field("port_type", &port_type)
            .finish()
    }
}

#[repr(C, packed)]
#[derive(Clone, Copy)]
pub struct FoEOptions {

    pub enable_crc: u8,

    pub strict_mode: u8,

    pub auto_append_crc: u8,

    pub expected_crc: u32,

    pub crc_progress_callback: Option<extern "C" fn(u32, u32, *mut c_void)>,

    pub crc_callback_userdata: *mut c_void,

    pub reserved: [u32; 8],
}

impl std::fmt::Debug for FoEOptions {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {

        let enable_crc = unsafe { std::ptr::addr_of!(self.enable_crc).read_unaligned() };
        let strict_mode = unsafe { std::ptr::addr_of!(self.strict_mode).read_unaligned() };
        let auto_append_crc = unsafe { std::ptr::addr_of!(self.auto_append_crc).read_unaligned() };
        let expected_crc = unsafe { std::ptr::addr_of!(self.expected_crc).read_unaligned() };
        f.debug_struct("FoEOptions")
            .field("enable_crc", &enable_crc)
            .field("strict_mode", &strict_mode)
            .field("auto_append_crc", &auto_append_crc)
            .field("expected_crc", &expected_crc)
            .finish()
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct SlaveIdentity {
    pub vendor_id: u32,
    pub product_code: u32,
    pub revision_no: u32,
    pub serial_no: u32,
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct EsmTimeouts {

    pub ip: u32,

    pub ps: u32,

    pub so: u32,

    pub os: u32,

    pub sp: u32,

    pub pi: u32,

    pub bi: u32,

    pub ib: u32,
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct RedundancyStatus {

    pub state: i32,

    pub primary_link_up: i32,

    pub secondary_link_up: i32,

    pub primary_tx_frames: u32,

    pub primary_rx_frames: u32,

    pub secondary_tx_frames: u32,

    pub secondary_rx_frames: u32,

    pub failover_count: u32,

    pub last_failover_time: u32,
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct CommunicationStats {
    pub total_cycles: u32,
    pub successful_cycles: u32,
    pub failed_cycles: u32,
    pub timeout_cycles: u32,
    pub average_cycle_time_us: f64,
    pub max_cycle_time_us: f64,
    pub min_cycle_time_us: f64,
}

pub type LogCallback = extern "C" fn(category: c_int, message: *const c_char);

pub type CrashNotifyCallback = extern "C" fn(exception_code: c_int, message: *const c_char);

pub type ProcessDataCyclicCallback = extern "C" fn(master_index: u16);

pub type SlaveStateChangeCallback = extern "C" fn(master_index: u16, slave_index: u16, old_state: c_int, new_state: c_int);

pub type EmergencyEventCallback = extern "C" fn(master_index: u16, slave_index: u16, error_code: u16, error_reg: u16, b1: u8, w1: u16, w2: u16);

pub type SlaveDiscoveryCallback = extern "C" fn(master_index: u16, slave_index: u16, is_found: i32);

pub type InputDataChangedCallback = extern "C" fn(master_index: u16, changed_slave_bits: *const u8, changed_count: u16);

pub type RedundancyModeChangedCallback = extern "C" fn(master_index: u16, old_mode: c_int, new_mode: c_int);

pub type PDOFrameLossCallback = extern "C" fn(master_index: u16, group: u8, consecutive_lost: u32, total_lost: u32);

pub type SlavePreOpReconfigCallback = extern "C" fn(master_index: u16, slave_index: u16);

pub type SlaveIdentityMismatchCallback = extern "C" fn(
    master_index: u16,
    slave_index: u16,
    expected_vendor: u32,
    expected_product: u32,
    expected_revision: u32,
    actual_vendor: u32,
    actual_product: u32,
    actual_revision: u32,
);

pub type SlavePortLinkChangedCallback = extern "C" fn(
    master_index: u16,
    slave_index: u16,
    port: u8,
    is_up: i32,
);

pub type FoEProgressCallback = extern "C" fn(slave: u16, packet_number: c_int, data_size: c_int);

pub type FoEBusyCallback = extern "C" fn(
    slave: u16,
    done: u16,
    entire: u16,
    text: *const c_char,
    retry_idx: c_int,
);

pub type DCSyncLostCallback = extern "C" fn(master_index: u16, slave_index: u16, diff_ns: c_int);

pub type AOENotificationCallback = extern "C" fn(
    slave: u16, handle: u32, timestamp: u64,
    data: *const c_void, data_size: u32, user_data: *mut c_void,
);

pub type EOEFrameCallback = unsafe extern "C" fn(
    master_index: u16, slave: u16, frame_data: *const u8, frame_size: c_int,
);

pub type VOENotificationCallback = unsafe extern "C" fn(
    slave: u16, vendor_id: u32, vendor_type: u16,
    data: *const u8, data_size: u32, user_data: *mut c_void,
);

pub type SoENotificationCallback = unsafe extern "C" fn(
    master_index: u16, slave_index: u16, drive_no: u8,
    idn: u16, element_flags: u8, data: *const c_void, data_len: u16,
);

pub type SoEEmergencyCallback = extern "C" fn(
    master_index: u16, slave_index: u16, drive_no: u8, error_code: u16,
);

#[repr(C)]
#[derive(Debug, Clone, Copy, Default)]
pub struct MbgStatsC {

    pub rx_packets: u64,

    pub rx_bytes: u64,

    pub forwarded_ok: u64,

    pub forwarded_failed: u64,

    pub timeout_count: u64,

    pub invalid_frame: u64,

    pub unknown_target: u64,

    pub unsupported_type: u64,

    pub tx_packets: u64,

    pub tx_bytes: u64,

    pub master_requests: u64,

    pub udp_port: u16,

    pub is_running: u8,

    pub reserved: u8,

    pub discovery_requests: u64,

    pub tcp_connections: u64,

    pub tcp_active: u64,

    pub tcp_port: u16,

    pub _pad_tail: [u8; 6],
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct EcMbxTransactionC {

    pub slave: u16,

    pub protocol_type: u8,

    pub reserved0: u8,

    pub timeout_us: u32,

    pub cancel_flag: i32,

    pub _pad_ptr1: u32,

    pub request_frame: *mut u8,

    pub request_len: u16,

    pub reserved1: u16,

    pub _pad_ptr2: u32,

    pub response_frame: *mut u8,

    pub response_cap: u16,

    pub response_len: u16,

    pub status: i32,

    pub error_code: u32,

    pub response_counter: u8,

    pub reserved2_0: u8,

    pub reserved2_1: u8,

    pub reserved2_2: u8,

    pub submit_time_us: u64,

    pub complete_time_us: u64,
}

impl Default for EcMbxTransactionC {
    fn default() -> Self {
        Self {
            slave: 0, protocol_type: 0, reserved0: 0, timeout_us: 0,
            cancel_flag: 0, _pad_ptr1: 0,
            request_frame: core::ptr::null_mut(), request_len: 0, reserved1: 0,
            _pad_ptr2: 0,
            response_frame: core::ptr::null_mut(), response_cap: 0, response_len: 0,
            status: 0, error_code: 0,
            response_counter: 0, reserved2_0: 0, reserved2_1: 0, reserved2_2: 0,
            submit_time_us: 0, complete_time_us: 0,
        }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct MasterIdentity {
    pub vendor_id: u32,
    pub product_code: u32,
    pub revision_no: u32,
    pub serial_no: u32,
    pub device_name: [u8; 64],
    pub hw_version: [u8; 32],
    pub sw_version: [u8; 32],
}

impl Default for MasterIdentity {
    fn default() -> Self {
        Self {
            vendor_id: 0,
            product_code: 0,
            revision_no: 0,
            serial_no: 0,
            device_name: [0; 64],
            hw_version: [0; 32],
            sw_version: [0; 32],
        }
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy, Default)]
pub struct MasterDiagData {
    pub cyclic_lost_frames: u32,
    pub acyclic_lost_frames: u32,
    pub cyclic_frames_per_sec: u32,
    pub acyclic_frames_per_sec: u32,
    pub master_state: u16,
}

#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FsoeState {

    Reset      = 0x100,

    Session    = 0x101,

    Connection = 0x102,

    Parameter  = 0x103,

    Data       = 0x104,

    Failsafe   = 0x105,
}

#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FsoeError {

    None              = 0x0000,

    WrongCommand      = 0x0001,

    UnknownCommand    = 0x0002,

    WrongConnId       = 0x0003,

    Crc               = 0x0004,

    Watchdog          = 0x0005,

    WrongAddress      = 0x0006,

    WrongData         = 0x0007,

    CommParamLength   = 0x0008,

    CommParam         = 0x0009,

    AppParamLength    = 0x000A,

    AppParam          = 0x000B,

    UnexpectedSession = 0x000C,

    FailsafeData      = 0x000D,

    NotInitialized    = 0x0100,

    MaxConnections    = 0x0101,

    InvalidState      = 0x0102,
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct FsoeConfig {

    pub connection_id: u16,

    pub safety_address: u16,

    pub watchdog_time_ms: u32,

    pub safe_input_size: u16,

    pub safe_output_size: u16,

    pub pdo_input_offset: u32,

    pub pdo_output_offset: u32,
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct FsoeStatus {

    pub state: FsoeState,

    pub last_error: FsoeError,

    pub error_count: u32,

    pub frames_sent: u32,

    pub frames_received: u32,

    pub crc_errors: u32,

    pub watchdog_errors: u32,

    pub watchdog_expired: u8,

    pub in_failsafe: u8,

    pub toggle_bit: u8,

    pub initialized: u8,
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct SafeMdpConfig {

    pub connection_id: u16,

    pub safety_address: u16,

    pub watchdog_time_ms: u32,

    pub safe_input_size: u16,

    pub safe_output_size: u16,

    pub pdo_input_offset: u32,

    pub pdo_output_offset: u32,

    pub module_number: u16,

    pub module_profile: u16,

    pub axis_number: u16,

    pub connection_type: u16,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveIoDescBlittable {

    pub bits: u16,

    pub bytes: u32,

    pub ptr: usize,

    pub offset: u32,

    pub startbit: u8,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveFsoeBlittable {

    pub capable: u8,

    pub connection: usize,

    pub sm_context: usize,

    pub connection_id: u16,

    pub safety_address: u16,

    pub safe_input_size: u16,

    pub safe_output_size: u16,

    pub pdo_input_offset: u32,

    pub pdo_output_offset: u32,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveMailboxBlittable {

    pub length: u16,

    pub write_offset: u16,

    pub read_length: u16,

    pub read_offset: u16,

    pub supported_proto: u16,

    pub cnt: u8,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveEepromConfigBlittable {

    pub _reserved_sii: u16,

    pub read_8byte: u8,

    pub pdi: u8,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveHandlerBlittable {

    pub state: i32,

    pub rmp_state: i32,

    pub instate_ex: u16,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveIdentityBlittable {

    pub vendor_id: u32,

    pub product_id: u32,

    pub revision: u32,

    pub serial: u32,

    pub itype: u16,

    pub dtype: u16,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct SlaveMetadataBlittable {

    pub identity: SlaveIdentityBlittable,

    pub group_name: [u8; 41],

    pub device_name: [u8; 41],

    pub sm_count: u16,
}

impl Default for SlaveMetadataBlittable {
    fn default() -> Self {
        Self {
            identity: SlaveIdentityBlittable::default(),
            group_name: [0; 41],
            device_name: [0; 41],
            sm_count: 0,
        }
    }
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveCapabilitiesBlittable {

    pub is_optional: u8,

    pub supports_frame_repeat: u8,

    pub mailbox_side: u8,

    pub coe_details: u8,

    pub foe_details: u8,

    pub eoe_details: u8,

    pub soe_details: u8,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveRuntimeBlittable {

    pub ebus_current: i16,

    pub block_lrw: u8,

    pub group: u8,

    pub is_lost: u8,

    pub freerun_demoted: u8,

    pub mbx_health: u8,

    pub health_alstatuscode: u16,

    pub health_degraded_count: u32,

    pub health_probe_us: u64,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveSmFmmuBlittable {

    pub sm_type: [u8; 8],

    pub sm_app_length: [u16; 8],

    pub fmmu_func: [u8; 4],

    pub fmmu_unused: u8,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveProtoMbxBlittable {

    pub in_ptr: usize,

    pub in_full: u8,

    pub overrun: i32,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlavePdoConfigBlittable {

    pub assignment_enabled: u8,

    pub configuration_enabled: u8,

    pub config_initialized: u8,

    pub supports_complete_access: u8,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveTopologyBlittable {

    pub has_dc: u8,

    pub phy_type: u8,

    pub link_count: u8,

    pub active_ports: u8,

    pub consumed_ports: u8,

    pub parent: u16,

    pub parent_port: u8,

    pub entry_port: u8,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct SlaveDcBlittable {

    pub recvtime: [i32; 4],

    pub propagation_delay: i32,

    pub next: u16,

    pub prev: u16,

    pub cycle0: i32,

    pub cycle1: i32,

    pub shift: i32,

    pub active: u16,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct EcSlaveBlittable {

    pub state: u16,

    pub al_status_code: u16,

    pub config_addr: u16,

    pub alias_addr: u16,

    pub fsoe: SlaveFsoeBlittable,

    pub output: SlaveIoDescBlittable,

    pub input: SlaveIoDescBlittable,

    pub sm_buffer: [u8; 64],

    pub fmmu_buffer: [u8; 64],

    pub sm_fmmu: SlaveSmFmmuBlittable,

    pub mbx: SlaveMailboxBlittable,

    pub topo: SlaveTopologyBlittable,

    pub dc: SlaveDcBlittable,

    pub eeprom_config: SlaveEepromConfigBlittable,

    pub runtime: SlaveRuntimeBlittable,

    pub po2so_config: usize,

    pub handler: SlaveHandlerBlittable,

    pub coe: SlaveProtoMbxBlittable,

    pub soe: SlaveProtoMbxBlittable,

    pub foe: SlaveProtoMbxBlittable,

    pub eoe: SlaveProtoMbxBlittable,

    pub voe: SlaveProtoMbxBlittable,

    pub aoe: SlaveProtoMbxBlittable,

    pub mbx_status: usize,

    pub metadata: SlaveMetadataBlittable,

    pub pdo_config: SlavePdoConfigBlittable,

    pub capabilities: SlaveCapabilitiesBlittable,
}

impl EcSlaveBlittable {

    pub fn group_name_str(&self) -> String {
        let len = self.metadata.group_name.iter().position(|&b| b == 0).unwrap_or(41);
        crate::utils::help::decode_ethercat_string(&self.metadata.group_name[..len])
    }

    pub fn device_name_str(&self) -> String {
        let len = self.metadata.device_name.iter().position(|&b| b == 0).unwrap_or(41);
        crate::utils::help::decode_ethercat_string(&self.metadata.device_name[..len])
    }
}

#[link(name = "Darra.Core")]
extern "C" {

    #[link_name = "D_1547"]
    pub fn Initialize() -> u16;
    #[link_name = "D_1548"]
    pub fn InitializeSpecificMaster(master_index: u16) -> u16;
    #[link_name = "D_1549"]
    pub fn Dispose(master_index: u16);
    #[link_name = "D_1592"]
    pub fn Start(master_index: u16);
    #[link_name = "D_1593"]
    pub fn Stop(master_index: u16);
    #[link_name = "D_1047"]
    pub fn FreeMemory(ptr: *mut c_void);

    #[link_name = "D_1596"]
    pub fn GetDllVersionInfo() -> *const DllVersionInfo;

    #[link_name = "D_1654"]
    pub fn GetDriverVersion() -> *const DriverVersionInfo;

    #[link_name = "D_1655"]
    pub fn InvalidateDriverVersionCache();

    #[link_name = "D_1546"]
    pub fn EnsureDriversRunning() -> c_int;

    #[link_name = "D_1550"]
    pub fn SetNetwork(master_index: u16, adapter: *const c_char, redundant: *const c_char) -> c_int;
    #[link_name = "D_1076"]
    pub fn GetNetworkInfo(is_redundant: i32, need_slaves_num: i32) -> c_int;
    #[link_name = "D_1077"]
    pub fn GetNetworksPointer() -> *const c_void;
    #[link_name = "D_1080"]
    pub fn QuickSlaveCount(adapter_name: *const c_char) -> c_int;
    #[link_name = "D_1084"]
    pub fn ReadSlaveInfo(adapter_name: *const c_char) -> c_int;
    #[link_name = "D_1085"]
    pub fn GetScannedSlaveCount() -> c_int;
    #[link_name = "D_1086"]
    pub fn GetScannedSlaveInfo(
        index: c_int, vendor_id: *mut u32, product_code: *mut u32,
        revision: *mut u32, serial: *mut u32,
        name: *mut c_char, name_size: c_int,
        config_addr: *mut u16, alias_addr: *mut u16,
        parent: *mut u16, topology: *mut u8, activeports: *mut u8,
        entryport: *mut u8, parentport: *mut u8, ptype: *mut u8,
    ) -> i32;
    #[link_name = "D_1082"]
    pub fn GetRingSlaveCount() -> c_int;

    #[link_name = "D_1551"]
    pub fn SetState(master_index: u16, state: c_int) -> i32;
    #[link_name = "D_1092"]
    pub fn SetStateWithTimeout(master_index: u16, state: c_int, timeout_ms: u32) -> i32;
    #[link_name = "D_1093"]
    pub fn SetSlaveStateWithTimeout(master_index: u16, slave_index: u16, state: c_int, timeout_ms: u32) -> i32;
    #[link_name = "D_1132"]
    pub fn SetStateSequence(master_index: u16, target_state: c_int, timeout_ms: u32) -> i32;
    #[link_name = "D_1131"]
    pub fn SetStateWithStartup(master_index: u16, target_state: c_int, timeout_ms: u32) -> i32;
    #[link_name = "D_1553"]
    pub fn GetMasterState(master_index: u16) -> *const c_void;
    #[link_name = "D_1555"]
    pub fn GetMasterStateCache(master_index: u16) -> *const c_void;
    #[link_name = "D_1552"]
    pub fn GetLinkStatus(master_index: u16) -> u8;
    #[link_name = "D_1094"]
    pub fn GetSlaveState(master_index: u16, slave_index: u16) -> u8;
    #[link_name = "D_1095"]
    pub fn GetSlaveALStatusCode(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1700"]
    pub fn GetSlaveStateLive(master_index: u16, slave_index: u16) -> u8;

    #[link_name = "D_1699"]
    pub fn GetSlaveALStatusCodeLive(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1557"]
    pub fn GetIO(master_index: u16, slave: u16, out_byte_size: *mut c_int, out_byte: *mut *mut u8, in_byte_size: *mut c_int, in_byte: *mut *mut u8) -> u8;
    #[link_name = "D_1558"]
    pub fn LockIOmap(master_index: u16);
    #[link_name = "D_1559"]
    pub fn UnlockIOmap(master_index: u16);
    #[link_name = "D_1561"]
    pub fn WriteSlaveOutput(master_index: u16, slave_index: u16, data: *const u8, size: u32);
    #[link_name = "D_1562"]
    pub fn WriteSlaveOutputByte(master_index: u16, slave_index: u16, offset: u32, value: u8);
    #[link_name = "D_1597"]
    pub fn SetMutexProtection(master_index: u16, enable: i32);
    #[link_name = "D_1560"]
    pub fn GetMutexProtection(master_index: u16) -> i32;

    #[link_name = "D_1572"]
    pub fn SDOread(master_index: u16, slave: u16, index: u16, subindex: u8, ca: i32, out_byte_size: *mut c_int) -> *mut u8;
    #[link_name = "D_1571"]
    pub fn SDOwrite_raw(master_index: u16, slave: u16, index: u16, subindex: u8, ca: i32, bytes: *const u8, length: c_int) -> u8;

    #[link_name = "D_1573"]
    pub fn SDOread_ex(master_index: u16, slave: u16, index: u16, subindex: u8, ca: i32,
                      out_byte_size: *mut c_int, out_abort_code: *mut u32, out_wkc: *mut c_int) -> *mut u8;

    #[link_name = "D_1574"]
    pub fn SDOwrite_ex(master_index: u16, slave: u16, index: u16, subindex: u8, ca: i32,
                       bytes: *const u8, length: c_int, out_abort_code: *mut u32, out_wkc: *mut c_int) -> c_int;

    #[link_name = "D_1564"]
    pub fn GetSlaveSDOList(master_index: u16, slave_index: u16) -> *const c_void;
    #[link_name = "D_1563"]
    pub fn GetSlaveSDOListBasic(master_index: u16, slave_index: u16) -> *const c_void;
    #[link_name = "D_1569"]
    pub fn GetSlavePointer_SDO_Value(master_index: u16, slave_index: u16, od_index: u16, oe_index: u8, out_byte_size: *mut c_int) -> *mut u8;
    #[link_name = "D_1570"]
    pub fn GetSlavePointer_SDO_IndexValue(master_index: u16, slave_index: u16, index: u16, subidx: u8, out_byte_size: *mut c_int) -> *mut u8;
    #[link_name = "D_1556"]
    pub fn GetSlave(master_index: u16, slave_index: u16) -> *const c_void;
    #[link_name = "D_1330"]
    pub fn GetSlaveDetailedInfo(master_index: u16, slave_index: u16) -> *const c_void;

    #[link_name = "D_1501"]
    pub fn SoERead(master_index: u16, slave: u16, drive_no: u8, element_flags: u8, idn: u16, data: *mut *mut c_void, data_size: *mut c_int, timeout: c_int) -> i32;
    #[link_name = "D_1502"]
    pub fn SoEWrite(master_index: u16, slave: u16, drive_no: u8, element_flags: u8, idn: u16, data: *const u8, data_size: c_int, timeout: c_int) -> i32;
    #[link_name = "D_1503"]
    pub fn SoEReadAttributes(master_index: u16, slave: u16, drive_no: u8, idn: u16, attributes: *mut u32, timeout: c_int) -> i32;
    #[link_name = "D_1504"]
    pub fn SoEReadName(master_index: u16, slave: u16, drive_no: u8, idn: u16, name: *mut *mut c_void, name_length: *mut c_int, timeout: c_int) -> i32;
    #[link_name = "D_1505"]
    pub fn SoEReadUnit(master_index: u16, slave: u16, drive_no: u8, idn: u16, unit: *mut *mut c_void, unit_length: *mut c_int, timeout: c_int) -> i32;
    #[link_name = "D_1506"]
    pub fn SoEReadIDNList(master_index: u16, slave: u16, drive_no: u8, idn_list: *mut *mut u16, list_count: *mut c_int, timeout: c_int) -> i32;
    #[link_name = "D_1507"]
    pub fn SoEReadMinMax(master_index: u16, slave: u16, drive_no: u8, idn: u16,
                         min_value: *mut *mut c_void, min_size: *mut c_int,
                         max_value: *mut *mut c_void, max_size: *mut c_int,
                         timeout: c_int) -> i32;

    #[link_name = "D_1058"]
    pub fn RegisterSoENotificationCallback(callback: SoENotificationCallback);

    #[link_name = "D_1059"]
    pub fn RegisterSoEEmergencyCallback(callback: SoEEmergencyCallback);

    #[link_name = "D_1649"]
    pub fn UnregisterSoENotificationCallback(callback: SoENotificationCallback);

    #[link_name = "D_1650"]
    pub fn UnregisterSoEEmergencyCallback(callback: SoEEmergencyCallback);

    #[link_name = "D_1476"]
    pub fn FOERead(master_index: u16, slave: u16, filename: *const c_char, password: u32, file_data: *mut *mut c_void, file_size: *mut c_int, timeout: c_int) -> i32;
    #[link_name = "D_1477"]
    pub fn FOEWrite(master_index: u16, slave: u16, filename: *const c_char, password: u32, file_data: *const c_void, file_size: c_int, timeout: c_int) -> i32;
    #[link_name = "D_1480"]
    pub fn FOEReadEx(master_index: u16, slave: u16, filename: *const c_char, password: u32, file_data: *mut *mut c_void, file_size: *mut c_int, timeout: c_int, options: *mut FoEOptions) -> i32;
    #[link_name = "D_1481"]
    pub fn FOEWriteEx(master_index: u16, slave: u16, filename: *const c_char, password: u32, file_data: *const c_void, file_size: c_int, timeout: c_int, options: *mut FoEOptions) -> i32;
    #[link_name = "D_1478"]
    pub fn FOESetProgressHook(master_index: u16, callback: Option<FoEProgressCallback>) -> i32;
    #[link_name = "D_1479"]
    pub fn FOEClearProgressHook(master_index: u16) -> i32;

    #[link_name = "D_1485"]
    pub fn EOESetIP(master_index: u16, slave: u16, port: u8, ip: u32, subnet: u32, gateway: u32, timeout: c_int) -> i32;
    #[link_name = "D_1486"]
    pub fn EOEGetIP(master_index: u16, slave: u16, port: u8, ip: *mut u32, subnet: *mut u32, gateway: *mut u32, timeout: c_int) -> i32;
    #[link_name = "D_1495"]
    pub fn EOESendFrame(master_index: u16, slave: u16, port: u8, frame_data: *const u8, frame_size: c_int, timeout: c_int) -> i32;
    #[link_name = "D_1496"]
    pub fn EOEReceiveFrame(master_index: u16, slave: u16, port: u8, frame_data: *mut *mut c_void, frame_size: *mut c_int, timeout: c_int) -> i32;
    #[link_name = "D_1487"]
    pub fn EOESetMAC(master_index: u16, slave: u16, port: u8, mac: *const u8, timeout: c_int) -> i32;
    #[link_name = "D_1488"]
    pub fn EOEGetMAC(master_index: u16, slave: u16, port: u8, mac: *mut u8, timeout: c_int) -> i32;

    #[link_name = "D_1508"]
    pub fn AOESendCommand(master_index: u16, slave: u16, target_port: u16, command_id: u16, command_data: *const u8, command_size: u32, response_data: *mut *mut c_void, response_size: *mut u32, timeout: c_int) -> i32;
    #[link_name = "D_1509"]
    pub fn AOEReadWrite(master_index: u16, slave: u16, index_group: u32, index_offset: u32, read_length: u32, write_length: u32, write_data: *const u8, read_data: *mut *mut c_void, bytes_read: *mut u32, timeout: c_int) -> i32;
    #[link_name = "D_1510"]
    pub fn AOEReadDeviceInfo(master_index: u16, slave: u16, major_ver: *mut u8, minor_ver: *mut u8, build: *mut u16, device_name: *mut u8, name_size: c_int, timeout: c_int) -> i32;
    #[link_name = "D_1511"]
    pub fn AOEReadState(master_index: u16, slave: u16, ads_state: *mut u16, device_state: *mut u16, timeout: c_int) -> i32;
    #[link_name = "D_1512"]
    pub fn AOEWriteControl(master_index: u16, slave: u16, ads_state: u16, device_state: u16, data: *const u8, data_size: c_int, timeout: c_int) -> i32;
    #[link_name = "D_1513"]
    pub fn AOEAddNotification(master_index: u16, slave: u16,
                              index_group: u32, index_offset: u32, length: u32,
                              trans_mode: u32, max_delay: u32, cycle_time: u32,
                              handle: *mut u32, timeout: c_int) -> i32;
    #[link_name = "D_1514"]
    pub fn AOEDelNotification(master_index: u16, slave: u16, handle: u32, timeout: c_int) -> i32;
    #[link_name = "D_1515"]
    pub fn AOESetConfig(master_index: u16, slave: u16,
                        target_net_id: *const u8, target_port: u16,
                        source_net_id: *const u8, source_port: u16) -> i32;
    #[link_name = "D_1516"]
    pub fn AOEGetConfig(master_index: u16, slave: u16,
                        target_net_id: *mut u8, target_port: *mut u16,
                        source_net_id: *mut u8, source_port: *mut u16) -> i32;

    #[link_name = "D_1062"]
    pub fn AOEGetLastError(master_index: u16, slave: u16,
                           error_code: *mut u32, error_class: *mut u16,
                           error_low: *mut u16, last_command: *mut u16) -> i32;

    #[link_name = "D_1063"]
    pub fn AOEClearLastError(master_index: u16, slave: u16);

    #[link_name = "D_1064"]
    pub fn AOEInitSlaveNetId(master_index: u16, master_net_id: *const u8, timeout: c_int) -> c_int;

    #[link_name = "D_1065"]
    pub fn AOEReadWriteEx(master_index: u16, slave: u16,
                          index_group: u32, index_offset: u32,
                          read_length: u32, write_length: u32, write_data: *const u8,
                          read_data: *mut *mut c_void, actual_read: *mut u32, timeout: c_int) -> i32;

    #[link_name = "D_1066"]
    pub fn AOESendFragmented(master_index: u16, slave: u16,
                             payload: *const u8, payload_len: u32,
                             packet_number: u16, timeout: c_int) -> i32;

    #[link_name = "D_1067"]
    pub fn AOERecvReassemble(master_index: u16, slave: u16,
                             out_buffer: *mut u8, out_cap: u32,
                             packet_number: u16, timeout: c_int, out_len: *mut u32) -> i32;

    #[link_name = "D_1068"]
    pub fn AOEPeekInvokeId(master_index: u16, slave: u16) -> u32;

    #[link_name = "D_1518"]
    pub fn VOESend(master_index: u16, slave: u16, vendor_id: u32, vendor_type: u16, data: *const u8, data_size: c_int, timeout: c_int) -> i32;
    #[link_name = "D_1519"]
    pub fn VOEReceive(master_index: u16, slave: u16, vendor_id: *mut u32, vendor_type: *mut u16, data: *mut *mut c_void, data_size: *mut c_int, timeout: c_int) -> i32;
    #[link_name = "D_1520"]
    pub fn VOESendRaw(master_index: u16, slave: u16, frame_data: *const u8, frame_size: c_int, timeout: c_int) -> i32;
    #[link_name = "D_1521"]
    pub fn VOEReceiveRaw(master_index: u16, slave: u16, frame_data: *mut *mut c_void, frame_size: *mut c_int, timeout: c_int) -> i32;
    #[link_name = "D_1517"]
    pub fn VOEIsSupported(master_index: u16, slave: u16) -> i32;

    #[link_name = "D_1135"]
    pub fn EcInit(json_config: *const c_char) -> u16;
    #[link_name = "D_1136"]
    pub fn EcInitFromFile(json_file_path: *const c_char) -> u16;
    #[link_name = "D_1137"]
    pub fn EcClose(master_index: u16);
    #[link_name = "D_1133"]
    pub fn LoadConfigJson(master_index: u16, json_str: *const c_char) -> c_int;
    #[link_name = "D_1134"]
    pub fn AutoConfigureSM(master_index: u16, slave_index: u16) -> c_int;
    pub fn DarraCoreInvoke(master_index: u16, command: u32, arg0: u32, arg1: u32, arg2: u32) -> c_int;
    pub fn DarraCoreInvokeText(master_index: u16, command: u32, text: *const c_char, arg0: u32, arg1: u32, arg2: u32) -> c_int;

    #[link_name = "D_1125"]
    pub fn AddStartupParameter(master_index: u16, slave_index: u16, param: *const StartupParam) -> c_int;
    #[link_name = "D_1126"]
    pub fn AddStartupParameterBatch(master_index: u16, slave_index: u16, param_array: *const StartupParam, count: c_int) -> c_int;
    #[link_name = "D_1127"]
    pub fn ClearStartupParameters(master_index: u16, slave_index: u16) -> c_int;
    #[link_name = "D_1128"]
    pub fn GetStartupParameterCount(master_index: u16, slave_index: u16) -> c_int;
    #[link_name = "D_1129"]
    pub fn ApplyStartupParameters(master_index: u16, slave_index: u16, transition: u8, timing: u8) -> c_int;
    #[link_name = "D_1130"]
    pub fn ApplyStartupParametersAll(master_index: u16, transition: u8, timing: u8) -> c_int;

    #[link_name = "D_1087"]
    pub fn SetMasterDCCycleTime(master_index: u16, time_ns: u32);
    #[link_name = "D_1088"]
    pub fn SetMasterLoopCycleTime(master_index: u16, time_ns: u32);
    #[link_name = "D_1090"]
    pub fn SetSyncBySlaveIndex(master_index: u16, slave_index: u16, sync0_ns: u32, sync1_ns: u32, shift_ns: i32);
    #[link_name = "D_1278"]
    pub fn ConfigureDCAll(master_index: u16, sync0_ns: u32, sync1_ns: u32) -> c_int;
    #[link_name = "D_1274"]
    pub fn UpdatePropagationDelays(master_index: u16) -> c_int;
    #[link_name = "D_1277"]
    pub fn AutoCalculateDCShift(master_index: u16) -> c_int;
    #[link_name = "D_1275"]
    pub fn GetSlavePropagationDelay(master_index: u16, slave_index: u16) -> i32;
    #[link_name = "D_1276"]
    pub fn GetMaxPropagationDelay(master_index: u16) -> i32;
    #[link_name = "D_1279"]
    pub fn EnableContinuousMeasurement(master_index: u16, enable: i32, interval_sec: u32);
    #[link_name = "D_1280"]
    pub fn EnableDriftCompensation(master_index: u16, enable: i32, threshold_ns: i32, gain: i32);
    #[link_name = "D_1023"]
    pub fn SetDCAutoShiftEnabled(master_index: u16, enable: i32);
    #[link_name = "D_1024"]
    pub fn GetDCAutoShiftEnabled(master_index: u16) -> i32;

    #[link_name = "D_1281"]
    pub fn GetSlaveSyncWindowStatus(master_index: u16, slave_index: u16,
                                    diff_ns: *mut c_int, max_diff_ns: *mut c_int, min_diff_ns: *mut c_int,
                                    in_sync: *mut i32, out_of_sync_count: *mut u32) -> i32;
    #[link_name = "D_1283"]
    pub fn SetSyncWindowThreshold(master_index: u16, threshold_ns: c_int);
    #[link_name = "D_1284"]
    pub fn GetSyncWindowThreshold(master_index: u16) -> c_int;
    #[link_name = "D_1285"]
    pub fn ResetSlaveSyncWindowStats(master_index: u16, slave_index: u16);
    #[link_name = "D_1286"]
    pub fn GetMaxSyncDifference(master_index: u16) -> c_int;
    #[link_name = "D_1289"]
    pub fn IsAllSlavesInSync(master_index: u16) -> i32;

    #[link_name = "D_1016"]
    pub fn GetAvailableCpuCores() -> c_int;
    #[link_name = "D_1017"]
    pub fn SetMasterCpuAffinity(master_index: u16, cpu_core: c_int) -> i32;
    #[link_name = "D_1018"]
    pub fn SetProcessCpuAffinity(cpu_core: c_int) -> i32;
    #[link_name = "D_1021"]
    pub fn SetPDOThreadCpuAffinity(master_index: u16, cpu_core: c_int) -> i32;
    #[link_name = "D_1022"]
    pub fn GetPDOThreadCpuAffinity(master_index: u16) -> c_int;
    #[link_name = "D_1595"]
    pub fn ApplyRealtimeOptimizations() -> i32;
    #[link_name = "D_1019"]
    pub fn RemoveRealtimeOptimizations() -> i32;
    #[link_name = "D_1020"]
    pub fn GetRealtimeOptimizationsStatus() -> i32;
    #[link_name = "D_1089"]
    pub fn GetTimingMode(master_index: u16) -> u32;

    #[link_name = "D_1005"]
    pub fn SetSlaveGroup(master_index: u16, slave_index: u16, group: u8) -> i32;
    #[link_name = "D_1006"]
    pub fn GetSlaveGroup(master_index: u16, slave_index: u16) -> u8;
    #[link_name = "D_1007"]
    pub fn SetGroupCycleDivider(master_index: u16, group: u8, divider: u8) -> i32;
    #[link_name = "D_1008"]
    pub fn GetGroupCycleDivider(master_index: u16, group: u8) -> u8;
    #[link_name = "D_1009"]
    pub fn SetGroupEnabled(master_index: u16, group: u8, enabled: i32) -> i32;
    #[link_name = "D_1010"]
    pub fn GetGroupEnabled(master_index: u16, group: u8) -> i32;
    #[link_name = "D_1011"]
    pub fn GetGroupExpectedWKC(master_index: u16, group: u8) -> u16;
    #[link_name = "D_1014"]
    pub fn GetActiveGroupCount(master_index: u16) -> u8;
    #[link_name = "D_1015"]
    pub fn GetGroupSlaveCount(master_index: u16, group: u8) -> u16;

    #[link_name = "D_1117"]
    pub fn SetSlaveWatchdog(master_index: u16, slave_index: u16, timeout_ms: u32) -> i32;
    #[link_name = "D_1118"]
    pub fn SetSlavePdiWatchdog(master_index: u16, slave_index: u16, timeout_ms: u32) -> i32;
    #[link_name = "D_1119"]
    pub fn GetSlaveWatchdogConfig(master_index: u16, slave_index: u16, config: *mut WatchdogConfig) -> i32;
    #[link_name = "D_1120"]
    pub fn GetSlaveWatchdogStatus(master_index: u16, slave_index: u16, status: *mut WatchdogStatus) -> i32;
    #[link_name = "D_1121"]
    pub fn SetAllSlaveWatchdog(master_index: u16, timeout_ms: u32) -> c_int;
    #[link_name = "D_1122"]
    pub fn SetAllSlavePdiWatchdog(master_index: u16, timeout_ms: u32) -> c_int;

    #[link_name = "D_1103"]
    pub fn GetSlaveIdentity(master_index: u16, slave_index: u16, identity: *mut SlaveIdentity) -> i32;
    #[link_name = "D_1104"]
    pub fn VerifySlaveIdentity(master_index: u16, slave_index: u16, expected: *const SlaveIdentity, check_rev: i32, check_serial: i32) -> i32;
    #[link_name = "D_1113"]
    pub fn SetSlaveOptional(master_index: u16, slave_index: u16, is_optional: i32) -> i32;
    #[link_name = "D_1114"]
    pub fn GetSlaveOptional(master_index: u16, slave_index: u16) -> i32;
    #[link_name = "D_1115"]
    pub fn SetSlaveSupportsFrameRepeat(master_index: u16, slave_index: u16, supports: i32) -> i32;
    #[link_name = "D_1116"]
    pub fn GetSlaveSupportsFrameRepeat(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1101"]
    pub fn GetSlaveEsmTimeouts(master_index: u16, slave_index: u16, timeouts: *mut EsmTimeouts) -> i32;
    #[link_name = "D_1102"]
    pub fn SetSlaveEsmTimeouts(master_index: u16, slave_index: u16, timeouts: *const EsmTimeouts) -> i32;

    #[link_name = "D_1106"]
    pub fn WriteSlaveRegister(master_index: u16, slave_index: u16, reg_addr: u16, data: *const u8, len: u32) -> i32;
    #[link_name = "D_1107"]
    pub fn ReadSlaveRegister(master_index: u16, slave_index: u16, reg_addr: u16, data: *mut u8, len: u32) -> i32;
    #[link_name = "D_1263"]
    pub fn SIIReadWord(master_index: u16, slave_index: u16, word_addr: u16, out_value: *mut u16) -> i32;
    #[link_name = "D_1264"]
    pub fn SIIWriteWord(master_index: u16, slave_index: u16, word_addr: u16, value: u16) -> i32;

    #[link_name = "D_1265"]
    pub fn SIIReadControlReg(master_index: u16, slave_index: u16, out_ctrl: *mut u8) -> i32;

    #[link_name = "D_1266"]
    pub fn SIIAcquire(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1267"]
    pub fn SIIRelease(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1268"]
    pub fn SIIFindCategory(master_index: u16, slave_index: u16, cat_type: u16,
                           out_byte_offset: *mut u32, out_byte_size: *mut u32) -> i32;

    #[link_name = "D_1269"]
    pub fn SIIReadCategory(master_index: u16, slave_index: u16, cat_type: u16,
                           buffer: *mut u8, max_bytes: u32, out_actual_bytes: *mut u32) -> i32;

    #[link_name = "D_1270"]
    pub fn SIIEnumerateCategories(master_index: u16, slave_index: u16,
                                  out_types: *mut u16, max_count: c_int) -> i32;

    #[link_name = "D_1271"]
    pub fn SIIGetStrings(master_index: u16, slave_index: u16, buffer: *mut u8, max_bytes: u32) -> i32;

    #[link_name = "D_1272"]
    pub fn SIIGetStringByIndex(master_index: u16, slave_index: u16, string_index: u8,
                               buffer: *mut u8, max_bytes: u32) -> i32;

    #[link_name = "D_1273"]
    pub fn SIIGetGeneralInfo(master_index: u16, slave_index: u16, out_info: *mut SiiGeneralInfo) -> i32;
    #[link_name = "D_1111"]
    pub fn ConfigureSyncManager(master_index: u16, slave_index: u16,
                                sm_index: u8, start_addr: u16, length: u16,
                                control: u8, enable: i32) -> i32;
    #[link_name = "D_1112"]
    pub fn ConfigureFMMU(master_index: u16, slave_index: u16,
                         fmmu_index: u8, logical_addr: u32, length: u16,
                         logical_start_bit: u8, logical_end_bit: u8,
                         physical_addr: u16, physical_start_bit: u8,
                         fmmu_type: u8, enable: i32) -> i32;

    #[link_name = "D_1538"]
    pub fn SetRedProcessdata(mode: c_int);
    #[link_name = "D_1539"]
    pub fn GetRedProcessdata() -> c_int;
    #[link_name = "D_1534"]
    pub fn EnableRedundancy(master_index: u16, enable: i32) -> i32;
    #[link_name = "D_1535"]
    pub fn GetRedundancyStatus(master_index: u16) -> *const c_void;
    #[link_name = "D_1536"]
    pub fn ForceRedundancyFailover(master_index: u16) -> i32;
    #[link_name = "D_1537"]
    pub fn CheckRedundancyHealth(master_index: u16) -> i32;

    #[link_name = "D_1026"]
    pub fn SetLogCallback(callback: LogCallback);
    #[link_name = "D_1004"]
    pub fn SetCrashCallback(callback: CrashNotifyCallback);
    #[link_name = "D_1028"]
    pub fn SetPDOLogging(enable: i32);
    #[link_name = "D_1029"]
    pub fn SetMailboxLogging(enable: i32);
    #[link_name = "D_1030"]
    pub fn SetDebugLogging(enable: i32);

    #[link_name = "D_1031"]
    pub fn CloseDebugLog();

    #[link_name = "D_1032"]
    pub fn RegisterProcessDataCyclicCallbackSync(callback: ProcessDataCyclicCallback);

    #[link_name = "D_1033"]
    pub fn RegisterProcessDataCyclicCallbackAsync(callback: ProcessDataCyclicCallback);
    #[link_name = "D_1034"]
    pub fn RegisterSlaveStateChangeCallbackSync(callback: SlaveStateChangeCallback);
    #[link_name = "D_1035"]
    pub fn RegisterSlaveStateChangeCallbackAsync(callback: SlaveStateChangeCallback);
    #[link_name = "D_1036"]
    pub fn RegisterEmergencyEventCallback(callback: EmergencyEventCallback);
    #[link_name = "D_1037"]
    pub fn RegisterSlaveDiscoveryCallbackSync(callback: SlaveDiscoveryCallback);
    #[link_name = "D_1038"]
    pub fn RegisterSlaveDiscoveryCallbackAsync(callback: SlaveDiscoveryCallback);

    #[link_name = "D_1043"]
    pub fn RegisterInputDataChangedCallback(callback: InputDataChangedCallback);
    #[link_name = "D_1040"]
    pub fn RegisterRedundancyModeChangedCallback(callback: RedundancyModeChangedCallback);
    #[link_name = "D_1039"]
    pub fn RegisterPDOFrameLossCallback(callback: PDOFrameLossCallback);
    #[link_name = "D_1041"]
    pub fn RegisterSlavePreOpReconfigCallback(callback: SlavePreOpReconfigCallback);

    #[link_name = "D_1042"]
    pub fn RegisterSlaveIdentityMismatchCallback(callback: SlaveIdentityMismatchCallback);

    #[link_name = "D_1044"]
    pub fn RegisterSlavePortLinkChangedCallback(callback: SlavePortLinkChangedCallback);

    #[cfg(any(debug_assertions, feature = "internal-dlport"))]
    #[link_name = "D_1108"]
    pub fn WriteSlaveDLPORT(master_index: u16, slave_index: u16, dlport_value: u8) -> c_int;

    #[cfg(any(debug_assertions, feature = "internal-dlport"))]
    #[link_name = "D_1109"]
    pub fn ReadSlaveDLPORT(master_index: u16, slave_index: u16, dlport_value: *mut u8) -> c_int;
    #[link_name = "D_1282"]
    pub fn SetDCSyncLostCallback(callback: DCSyncLostCallback);

    #[link_name = "D_1313"]
    pub fn GetDetailedDiagnostics(master_index: u16) -> *const c_void;
    #[link_name = "D_1314"]
    pub fn ResetDiagnostics(master_index: u16);
    #[link_name = "D_1312"]
    pub fn GetDiagnosticsPointer(master_index: u16) -> *const c_void;
    #[link_name = "D_1316"]
    pub fn GetSummaryPointer(master_index: u16) -> *const c_void;
    #[link_name = "D_1290"]
    pub fn SetDiagnosticsEnabled(master_index: u16, enable: i32);
    #[link_name = "D_1291"]
    pub fn GetDiagnosticsEnabled(master_index: u16) -> i32;
    #[link_name = "D_1053"]
    pub fn GetCommunicationStats(master_index: u16) -> *const c_void;
    #[link_name = "D_1054"]
    pub fn ResetCommunicationStats(master_index: u16);

    #[link_name = "D_1295"]
    pub fn GetExpectedWKC(master: u16) -> u16;
    #[link_name = "D_1311"]
    pub fn SetExpectedWKC(master: u16, expected_wkc: u16);

    #[link_name = "D_1303"]
    pub fn GetPacketLossRate(master: u16) -> f32;
    #[link_name = "D_1304"]
    pub fn GetLateFrameRate(master: u16) -> f32;
    #[link_name = "D_1315"]
    pub fn GetSlaveLinkQuality(master: u16, slave: u16) -> i16;

    #[link_name = "D_1293"]
    pub fn RecordPDOCycleStart(master: u16);
    #[link_name = "D_1294"]
    pub fn RecordWKC(master: u16, wkc: u16);
    #[link_name = "D_1292"]
    pub fn UpdateDiagnosticsSnapshot(master: u16);
    #[link_name = "D_1320"]
    pub fn ResetSlavePortErrorCounters(master: u16, slave: u16) -> i32;

    #[link_name = "D_1296"]
    pub fn GetPrimaryWKC() -> u16;

    #[link_name = "D_1297"]
    pub fn GetSecondaryWKC() -> u16;

    #[link_name = "D_1623"]
    pub fn IsWdkAvailable(master_index: u16) -> i32;
    #[link_name = "D_1624"]
    pub fn SetWdkMode(master_index: u16, enable: i32) -> i32;
    #[link_name = "D_1625"]
    pub fn GetWdkMode(master_index: u16) -> i32;
    #[link_name = "D_1626"]
    pub fn StartWdkRT(master_index: u16, cycle_us: u32, cpu_index: u32) -> i32;
    #[link_name = "D_1627"]
    pub fn StopWdkRT(master_index: u16) -> i32;

    #[link_name = "D_1543"]
    pub fn SetUdpMode(master_index: u16, enable: i32) -> i32;
    #[link_name = "D_1544"]
    pub fn GetUdpMode(master_index: u16) -> i32;
    #[link_name = "D_1545"]
    pub fn IsUdpAvailable(master_index: u16) -> i32;

    #[link_name = "D_1072"]
    pub fn AbortScan();
    #[link_name = "D_1073"]
    pub fn ResetScanAbort();
    #[link_name = "D_1609"]
    pub fn AbortNetwork();
    #[link_name = "D_1610"]
    pub fn ResetAbortNetwork();
    #[link_name = "D_1612"]
    pub fn EmergencyCloseNics();

    #[link_name = "D_1138"]
    pub fn CiA402_ParseState(statusword: u16) -> i32;
    #[link_name = "D_1139"]
    pub fn CiA402_GetEnableCommand(statusword: u16) -> u16;
    #[link_name = "D_1140"]
    pub fn CiA402_SetMode(master: u16, slave: u16, mode: i8) -> i32;
    #[link_name = "D_1141"]
    pub fn CiA402_GetMode(master: u16, slave: u16) -> i8;
    #[link_name = "D_1142"]
    pub fn CiA402_ReadStatusWord(master: u16, slave: u16) -> u16;
    #[link_name = "D_1143"]
    pub fn CiA402_WriteControlWord(master: u16, slave: u16, cw: u16) -> i32;
    #[link_name = "D_1144"]
    pub fn CiA402_Enable(master: u16, slave: u16, max_retries: i32) -> i32;
    #[link_name = "D_1145"]
    pub fn CiA402_FaultReset(master: u16, slave: u16) -> i32;

    #[link_name = "D_1168"]
    pub fn EmcyGetHistory(master: u16, slave: u16, out: *mut EmcyRecord, max: i32) -> i32;
    #[link_name = "D_1169"]
    pub fn EmcyClearHistory(master: u16, slave: u16);
    #[link_name = "D_1170"]
    pub fn EmcyGetCount(master: u16, slave: u16) -> i32;

    #[link_name = "D_1171"]
    pub fn PDOReadInputU8(master: u16, slave: u16, offset: u32) -> u8;
    #[link_name = "D_1172"]
    pub fn PDOReadInputI16(master: u16, slave: u16, offset: u32) -> i16;
    #[link_name = "D_1173"]
    pub fn PDOReadInputU16(master: u16, slave: u16, offset: u32) -> u16;
    #[link_name = "D_1174"]
    pub fn PDOReadInputI32(master: u16, slave: u16, offset: u32) -> i32;
    #[link_name = "D_1175"]
    pub fn PDOReadInputU32(master: u16, slave: u16, offset: u32) -> u32;
    #[link_name = "D_1176"]
    pub fn PDOReadInputF32(master: u16, slave: u16, offset: u32) -> f32;
    #[link_name = "D_1177"]
    pub fn PDOWriteOutputU8(master: u16, slave: u16, offset: u32, val: u8) -> i32;
    #[link_name = "D_1178"]
    pub fn PDOWriteOutputI16(master: u16, slave: u16, offset: u32, val: i16) -> i32;
    #[link_name = "D_1179"]
    pub fn PDOWriteOutputU16(master: u16, slave: u16, offset: u32, val: u16) -> i32;
    #[link_name = "D_1180"]
    pub fn PDOWriteOutputI32(master: u16, slave: u16, offset: u32, val: i32) -> i32;
    #[link_name = "D_1181"]
    pub fn PDOWriteOutputU32(master: u16, slave: u16, offset: u32, val: u32) -> i32;
    #[link_name = "D_1182"]
    pub fn PDOWriteOutputF32(master: u16, slave: u16, offset: u32, val: f32) -> i32;

    #[link_name = "D_1325"]
    pub fn GetTopology(master: u16, out: *mut TopologyNode, max: c_int) -> c_int;
    #[link_name = "D_1326"]
    pub fn GetSlaveActivePorts(master: u16, slave: u16) -> u8;
    #[link_name = "D_1327"]
    pub fn GetSlaveParent(master: u16, slave: u16) -> u16;
    #[link_name = "D_1183"]
    pub fn TopologyBuild(master: u16, out: *mut TopologyNode, max: c_int) -> c_int;
    #[link_name = "D_1184"]
    pub fn TopologyGetChildren(master: u16, parent_index: u16, out: *mut u16, max: c_int) -> c_int;
    #[link_name = "D_1185"]
    pub fn TopologyGetRoots(master: u16, out: *mut u16, max: c_int) -> c_int;

    #[link_name = "D_1048"]
    pub fn GetSerialNumber() -> *const c_char;

    #[link_name = "D_1049"]
    pub fn GetDeviceName() -> *const c_char;

    #[link_name = "D_1050"]
    pub fn GetUserEmail() -> *const c_char;

    #[link_name = "D_1051"]
    pub fn GetWindowsProductKey() -> *const c_char;

    #[link_name = "D_1052"]
    pub fn GetDriverList() -> *const c_char;

    #[link_name = "D_1586"]
    pub fn VerifyLicense() -> c_int;

    #[link_name = "D_1590"]
    pub fn InvalidateLicense();

    #[link_name = "D_1589"]
    pub fn IsLicenseValid() -> c_int;

    #[link_name = "D_1737"]
    pub fn GetLicenseStatusEx() -> c_int;

    #[link_name = "D_1599"]
    pub fn LicenseActivate(activation_code: *const c_char, err_buf: *mut c_char, err_buf_len: c_int) -> c_int;

    #[link_name = "D_1594"]
    pub fn GetMaxMasterInstances() -> c_int;

    #[link_name = "D_1324"]
    pub fn DumpSlaveStructOffsets();

    #[link_name = "D_1075"]
    pub fn QuickFindRedundantPairBatch(
        adapter_names: *const *const c_char,
        adapter_count: c_int,
        primary_idx: *mut c_int,
        secondary_idx: *mut c_int,
        out_ring_count: *mut c_int,
        out_total_count: *mut c_int,
    ) -> c_int;

    #[link_name = "D_1002"]
    pub fn GetSlaveNeedsStartupReconfig(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1003"]
    pub fn ClearSlaveNeedsStartupReconfig(master_index: u16, slave_index: u16);

    #[link_name = "D_1045"]
    pub fn GetPDOFrameLossStats(
        master_index: u16, group: u8,
        total_lost: *mut u32, consecutive_lost: *mut u32, max_consecutive_lost: *mut u32,
    );

    #[link_name = "D_1046"]
    pub fn ResetPDOFrameLossStats(master_index: u16, group: u8);

    #[link_name = "D_1025"]
    pub fn DarraValidateTimerAccuracy(expected_usec: u32, tolerance_usec: u32) -> c_int;

    #[link_name = "D_1565"]
    pub fn GetMultiSlaveSDOList(
        master_index: u16,
        slave_indices: *const u16,
        count: c_int,
        results: *mut *const c_void,
    ) -> c_int;

    #[link_name = "D_1566"]
    pub fn FreeMultiSlaveSDOList(results: *mut *const c_void, count: c_int);

    #[link_name = "D_1567"]
    pub fn GetSlavePointer_SDO(master_index: u16, slave_index: u16, oe_index: u16) -> *const c_void;

    #[link_name = "D_1568"]
    pub fn GetSlavePointer_SDO_WithODList(
        master_index: u16, slave_index: u16, oe_index: u16, odlist: *const c_void,
    ) -> *const c_void;

    #[link_name = "D_1096"]
    pub fn EnableOutputSyncManager(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1097"]
    pub fn DisableOutputSyncManager(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1098"]
    pub fn GetSlaveOpOnlyFlag(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1099"]
    pub fn SetSlaveErrorAck(master_index: u16, slave_index: u16, set_ack: i32) -> i32;

    #[link_name = "D_1100"]
    pub fn GetSlaveDeviceEmulationFlag(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1105"]
    pub fn VerifyAllSlaveIdentities(
        master_index: u16,
        expected: *const SlaveIdentity,
        slave_count: u32,
        check_revision: i32,
        check_serial: i32,
        mismatch_mask: *mut u64,
    ) -> i32;

    #[link_name = "D_1528"]
    pub fn AOEStartNotificationListener(master_index: u16) -> i32;

    #[link_name = "D_1529"]
    pub fn AOEStopNotificationListener() -> i32;

    #[link_name = "D_1530"]
    pub fn AOEIsNotificationListening() -> i32;

    #[link_name = "D_1531"]
    pub fn AOERegisterNotification(
        slave: u16, handle: u32,
        index_group: u32, index_offset: u32, data_length: u32,
        callback: AOENotificationCallback,
        user_data: *mut c_void,
    ) -> c_int;

    #[link_name = "D_1532"]
    pub fn AOEUnregisterNotification(subscription_index: c_int) -> i32;

    #[link_name = "D_1489"]
    pub fn EOESetDNS(master_index: u16, slave: u16, port: u8, dns_ip: u32, dns_name: *const c_char, timeout: c_int) -> i32;

    #[link_name = "D_1492"]
    pub fn EOEGetDNS(master_index: u16, slave: u16, port: u8, dns_ip: *mut u32, dns_name: *mut c_char, timeout: c_int) -> i32;

    #[link_name = "D_1490"]
    pub fn EOEGetFullParam(
        master_index: u16, slave: u16, port: u8,
        ip: *mut u32, subnet: *mut u32, gateway: *mut u32,
        mac: *mut u8, dns_ip: *mut u32, dns_name: *mut c_char, timeout: c_int,
    ) -> i32;

    #[link_name = "D_1491"]
    pub fn EOESetFullParam(
        master_index: u16, slave: u16, port: u8,
        ip: u32, subnet: u32, gateway: u32,
        mac: *const u8, dns_ip: u32, dns_name: *const c_char, timeout: c_int,
    ) -> i32;

    #[link_name = "D_1493"]
    pub fn EOESetAddressFilter(
        master_index: u16, slave: u16, port: u8,
        filter_count: u8, mac_filters: *const u8, timeout: c_int,
    ) -> i32;

    #[link_name = "D_1494"]
    pub fn EOEGetAddressFilter(
        master_index: u16, slave: u16, port: u8,
        filter_count: *mut u8, mac_filters: *mut u8, max_filters: c_int, timeout: c_int,
    ) -> i32;

    #[link_name = "D_1123"]
    pub fn GetMasterIdentity(master_index: u16, identity: *mut MasterIdentity) -> i32;

    #[link_name = "D_1124"]
    pub fn GetMasterDiagData(master_index: u16, diag: *mut MasterDiagData) -> i32;

    #[link_name = "D_1322"]
    pub fn GetBreakPoints(
        master_index: u16,
        out_slaves: *mut u16, out_ports: *mut u8, out_types: *mut u8,
        max_results: u16,
    ) -> c_int;

    #[link_name = "D_1542"]
    pub fn GetRingMode(master_index: u16) -> c_int;

    #[link_name = "D_1533"]
    pub fn GetSecondaryLinkStatus(master_index: u16) -> i32;

    #[link_name = "D_1370"]
    pub fn ec_validate_config(master_index: u16) -> c_int;

    #[link_name = "D_1371"]
    pub fn ec_perf_export_csv(master_index: u16, filepath: *const c_char) -> c_int;

    #[cfg(any(debug_assertions, feature = "internal-debug-probes"))]
    #[link_name = "D_1091"]
    pub fn DebugSlaveHasDC(master_index: u16, slave_index: u16);

    #[link_name = "D_1317"]
    pub fn ReadSlavePortErrorCounters(
        master_index: u16, slave_index: u16,
        rx_error: *mut u8, invalid_frame: *mut u8, lost_link: *mut u8,
    ) -> i32;

    #[link_name = "D_1318"]
    pub fn ReadAllSlavePortErrorCounters(master_index: u16) -> c_int;

    #[link_name = "D_1319"]
    pub fn GetSlavePortErrorStats(master_index: u16, slave_index: u16) -> *const c_void;

    #[link_name = "D_1321"]
    pub fn UpdateDiagnosticsWithESCErrors(master_index: u16);

    #[link_name = "D_1335"]
    pub fn FSoEInitConnection(master_index: u16, slave_index: u16, config: *mut FsoeConfig) -> i32;

    #[link_name = "D_1336"]
    pub fn FSoECloseConnection(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1337"]
    pub fn FSoEGetStatus(master_index: u16, slave_index: u16, status: *mut FsoeStatus) -> i32;

    #[link_name = "D_1338"]
    pub fn FSoERequestState(master_index: u16, slave_index: u16, target_state: c_int) -> i32;

    #[link_name = "D_1339"]
    pub fn FSoEGetState(master_index: u16, slave_index: u16) -> c_int;

    #[link_name = "D_1340"]
    pub fn FSoEReset(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1341"]
    pub fn FSoEWriteSafeOutput(master_index: u16, slave_index: u16, data: *const u8, size: u32) -> i32;

    #[link_name = "D_1342"]
    pub fn FSoEReadSafeInput(master_index: u16, slave_index: u16, data: *mut u8, size: *mut u32) -> i32;

    #[link_name = "D_1343"]
    pub fn FSoEDownloadParameters(master_index: u16, slave_index: u16, param_data: *const u8, param_size: u32, sra_crc: *mut u32) -> i32;

    #[link_name = "D_1344"]
    pub fn FSoESetFailsafeOutput(master_index: u16, slave_index: u16, data: *const u8, size: u32) -> i32;

    #[link_name = "D_1345"]
    pub fn FSoECheckWatchdog(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1346"]
    pub fn FSoEGetLastError(master_index: u16, slave_index: u16) -> c_int;

    #[link_name = "D_1347"]
    pub fn FSoEClearError(master_index: u16, slave_index: u16);

    #[link_name = "D_1348"]
    pub fn FSoEIsSlaveCapable(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1349"]
    pub fn FSoEGetConnectionCount(master_index: u16) -> u16;

    #[link_name = "D_1350"]
    pub fn FSoEProcessCycle(master_index: u16);

    #[link_name = "D_1351"]
    pub fn SafeMdpInitConnection(master_index: u16, slave_index: u16, connection_index: u16, config: *mut SafeMdpConfig) -> i32;

    #[link_name = "D_1352"]
    pub fn SafeMdpCloseConnection(master_index: u16, slave_index: u16, connection_index: u16) -> i32;

    #[link_name = "D_1353"]
    pub fn SafeMdpGetStatus(master_index: u16, slave_index: u16, connection_index: u16, status: *mut FsoeStatus) -> i32;

    #[link_name = "D_1354"]
    pub fn SafeMdpRequestState(master_index: u16, slave_index: u16, connection_index: u16, target_state: c_int) -> i32;

    #[link_name = "D_1355"]
    pub fn SafeMdpGetState(master_index: u16, slave_index: u16, connection_index: u16) -> c_int;

    #[link_name = "D_1356"]
    pub fn SafeMdpReset(master_index: u16, slave_index: u16, connection_index: u16) -> i32;

    #[link_name = "D_1357"]
    pub fn SafeMdpWriteSafeOutput(master_index: u16, slave_index: u16, connection_index: u16, data: *const u8, size: u32) -> i32;

    #[link_name = "D_1358"]
    pub fn SafeMdpReadSafeInput(master_index: u16, slave_index: u16, connection_index: u16, data: *mut u8, size: *mut u32) -> i32;

    #[link_name = "D_1359"]
    pub fn SafeMdpDownloadParameters(master_index: u16, slave_index: u16, connection_index: u16, param_data: *const u8, param_size: u32, sra_crc: *mut u32) -> i32;

    #[link_name = "D_1360"]
    pub fn SafeMdpSetFailsafeOutput(master_index: u16, slave_index: u16, connection_index: u16, data: *const u8, size: u32) -> i32;

    #[link_name = "D_1361"]
    pub fn SafeMdpCheckWatchdog(master_index: u16, slave_index: u16, connection_index: u16) -> i32;

    #[link_name = "D_1362"]
    pub fn SafeMdpGetLastError(master_index: u16, slave_index: u16, connection_index: u16) -> c_int;

    #[link_name = "D_1363"]
    pub fn SafeMdpClearError(master_index: u16, slave_index: u16, connection_index: u16);

    #[link_name = "D_1364"]
    pub fn SafeMdpGetSlaveConnectionCount(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1365"]
    pub fn SafeMdpDetectConnections(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1366"]
    pub fn SafeMdpGetDeviceAddress(master_index: u16, slave_index: u16, safety_address: *mut u16) -> i32;

    #[link_name = "D_1367"]
    pub fn SafeMdpGetModuleCommParam(master_index: u16, slave_index: u16, module_number: u16, param_data: *mut u8, param_size: *mut u32) -> i32;

    #[link_name = "D_1368"]
    pub fn SafeMdpGetModuleDiagnosis(master_index: u16, slave_index: u16, module_number: u16, connection_state: *mut u16, connection_diagnosis: *mut u16) -> i32;

    #[link_name = "D_1369"]
    pub fn FSoEValidateConnId(conn_id: u16) -> c_int;

    #[link_name = "D_1331"]
    pub fn coe_diag_poll_new_available(
        master_index: u16,
        slave_index: u16,
        out_abort_code: *mut u32,
    ) -> c_int;

    #[link_name = "D_1332"]
    pub fn coe_diag_read_meta(
        master_index: u16,
        slave_index: u16,
        out_max_msgs: *mut u8,
        out_newest: *mut u8,
        out_acknowledged: *mut u8,
        out_flags16: *mut u16,
        out_abort_code: *mut u32,
    ) -> c_int;

    #[link_name = "D_1333"]
    pub fn coe_diag_read_message(
        master_index: u16,
        slave_index: u16,
        msg_subidx: u8,
        out_buf: *mut u8,
        buf_cap: c_int,
        out_len: *mut c_int,
        out_abort_code: *mut u32,
    ) -> c_int;

    #[link_name = "D_1334"]
    pub fn coe_diag_acknowledge(
        master_index: u16,
        slave_index: u16,
        ack_subidx: u8,
        out_abort_code: *mut u32,
    ) -> c_int;

    #[link_name = "D_1575"]
    pub fn coe_get_od_list(master_index: u16, slave_index: u16) -> *const c_void;

    #[link_name = "D_1576"]
    pub fn coe_get_object_desc(
        master_index: u16,
        slave_index: u16,
        index: u16,
    ) -> *const c_void;

    #[link_name = "D_1577"]
    pub fn coe_get_entry_desc(
        master_index: u16,
        slave_index: u16,
        index: u16,
        subindex: u8,
    ) -> *const c_void;

    #[link_name = "D_1578"]
    pub fn coe_free_odlist(p: *const c_void);

    #[link_name = "D_1579"]
    pub fn coe_free_oelist(p: *const c_void);

    #[link_name = "D_1287"]
    pub fn GetMasterDCTime(master_index: u16) -> i64;

    #[link_name = "D_1288"]
    pub fn GetReferenceClockSlaveIndex(master_index: u16) -> u16;

    #[link_name = "D_1482"]
    pub fn FOESetBusyHook(master_index: u16, callback: Option<FoEBusyCallback>) -> c_int;

    #[link_name = "D_1483"]
    pub fn FOERequestCancel(master_index: u16, slave: u16) -> c_int;

    #[link_name = "D_1484"]
    pub fn FOEClearCancel(master_index: u16, slave: u16) -> c_int;

    #[link_name = "D_1240"]
    pub fn GetSlaveHasEsi(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1242"]
    pub fn SetSlaveEsiFile(master_index: u16, slave_index: u16, name: *const c_char) -> i32;

    #[link_name = "D_1243"]
    pub fn GetSlaveEsiVersion(master_index: u16, slave_index: u16, buf: *mut c_char, buf_len: c_int) -> i32;

    #[link_name = "D_1241"]
    pub fn GetSlaveHasMDP(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1244"]
    pub fn GetSlaveVendorName(master_index: u16, slave_index: u16, buf: *mut c_char, buf_len: c_int) -> i32;

    #[link_name = "D_1245"]
    pub fn GetSlaveRedundancyActivated(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1246"]
    pub fn GetSlavePrimaryLinkBroken(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1247"]
    pub fn GetSlaveSecondaryLinkBroken(master_index: u16, slave_index: u16) -> i32;

    #[link_name = "D_1200"]
    pub fn GetSlaveMailboxProto(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1248"]
    pub fn mbx_get_stats_by_master(
        master_index: u16,
        slave_index: u16,
        protocol_type: u8,
        stats: *mut EcMbxStatsC,
    ) -> i32;

    #[link_name = "D_1249"]
    pub fn mbx_reset_stats_by_master(
        master_index: u16,
        slave_index: u16,
        protocol_type: u8,
    );

    #[link_name = "D_1472"]
    pub fn AL_StatusCode_GetDescription(code: u16) -> *const c_char;
    #[link_name = "D_1473"]
    pub fn AL_StatusCode_GetSeverity(code: u16) -> i32;
    #[link_name = "D_1474"]
    pub fn AL_StatusCode_GetRecoveryHint(code: u16) -> *const c_char;
    #[link_name = "D_1475"]
    pub fn AL_StatusCode_IsVendorSpecific(code: u16) -> i32;

    #[link_name = "D_1441"]
    pub fn SDOAbort_GetDescription(abort_code: u32) -> *const c_char;
    #[link_name = "D_1442"]
    pub fn SDOAbort_GetCategory(abort_code: u32) -> i32;
    #[link_name = "D_1443"]
    pub fn SDOAbort_IsRetryable(abort_code: u32) -> i32;
    #[link_name = "D_1444"]
    pub fn SDOAbort_GetHint(abort_code: u32) -> *const c_char;

    #[link_name = "D_1416"]
    pub fn EmcyCode_GetDescription(error_code: u16) -> *const c_char;
    #[link_name = "D_1417"]
    pub fn EmcyCode_GetClass(error_code: u16) -> i32;
    #[link_name = "D_1418"]
    pub fn EmcyCode_GetClassName(class_code: i32) -> *const c_char;
    #[link_name = "D_1419"]
    pub fn EmcyCode_FormatErrorRegister(error_register: u8, buf: *mut u8, buf_size: c_int);
    #[link_name = "D_1420"]
    pub fn EmcyCode_IsRecovery(error_code: u16) -> i32;

    #[link_name = "D_1464"]
    pub fn EcState_IsValidTransition(from: u16, to: u16) -> i32;
    #[link_name = "D_1465"]
    pub fn EcState_GetTransitionType(from: u16, to: u16) -> i32;
    #[link_name = "D_1466"]
    pub fn EcState_GetTransitionPath(from: u16, to: u16, path: *mut u16, path_capacity: c_int) -> i32;
    #[link_name = "D_1467"]
    pub fn EcState_IsBootstrapRequired(state: u16) -> i32;
    #[link_name = "D_1468"]
    pub fn EcState_GetName(state: u16) -> *const c_char;
    #[link_name = "D_1469"]
    pub fn EcState_GetNameEn(state: u16) -> *const c_char;
    #[link_name = "D_1470"]
    pub fn EcState_HasErrorAck(state: u16) -> i32;
    #[link_name = "D_1471"]
    pub fn EcState_StripErrorAck(state: u16) -> u16;

    #[link_name = "D_1426"]
    pub fn EcPdoCodec_DataTypeBitSize(dt: c_int) -> c_int;
    #[link_name = "D_1427"]
    pub fn EcPdoCodec_DataTypeName(dt: c_int) -> *const c_char;
    #[link_name = "D_1428"]
    pub fn EcPdoCodec_ExtractU64(
        src: *const u8,
        src_size: c_int,
        bit_offset: c_int,
        bit_length: c_int,
        out_value: *mut u64,
    ) -> c_int;
    #[link_name = "D_1429"]
    pub fn EcPdoCodec_ExtractI64(
        src: *const u8,
        src_size: c_int,
        bit_offset: c_int,
        bit_length: c_int,
        out_value: *mut i64,
    ) -> c_int;
    #[link_name = "D_1430"]
    pub fn EcPdoCodec_InsertU64(
        dst: *mut u8,
        dst_size: c_int,
        bit_offset: c_int,
        bit_length: c_int,
        value: u64,
    ) -> c_int;
    #[link_name = "D_1431"]
    pub fn EcPdoCodec_InsertI64(
        dst: *mut u8,
        dst_size: c_int,
        bit_offset: c_int,
        bit_length: c_int,
        value: i64,
    ) -> c_int;
    #[link_name = "D_1432"]
    pub fn EcPdoCodec_ExtractReal32(
        src: *const u8,
        src_size: c_int,
        bit_offset: c_int,
        out_value: *mut f32,
    ) -> c_int;
    #[link_name = "D_1433"]
    pub fn EcPdoCodec_ExtractReal64(
        src: *const u8,
        src_size: c_int,
        bit_offset: c_int,
        out_value: *mut f64,
    ) -> c_int;
    #[link_name = "D_1434"]
    pub fn EcPdoCodec_InsertReal32(
        dst: *mut u8,
        dst_size: c_int,
        bit_offset: c_int,
        value: f32,
    ) -> c_int;
    #[link_name = "D_1435"]
    pub fn EcPdoCodec_InsertReal64(
        dst: *mut u8,
        dst_size: c_int,
        bit_offset: c_int,
        value: f64,
    ) -> c_int;
    #[link_name = "D_1436"]
    pub fn EcPdoCodec_CountActivePorts(active_ports: u8) -> c_int;
    #[link_name = "D_1437"]
    pub fn EcPdoCodec_GetTopology(active_ports: u8) -> c_int;
    #[link_name = "D_1438"]
    pub fn EcPdoCodec_GetTopologyName(topo: c_int) -> *const c_char;
    #[link_name = "D_1439"]
    pub fn EcPdoCodec_GetTopologyNameEn(topo: c_int) -> *const c_char;
    #[link_name = "D_1440"]
    pub fn EcPdoCodec_IsPortActive(active_ports: u8, port: c_int) -> c_int;

    #[link_name = "D_1390"]
    pub fn CiA402Modes_ModeToSupportedBit(mode: i8) -> c_int;
    #[link_name = "D_1391"]
    pub fn CiA402Modes_IsModeSupportedInMask(mask: u32, mode: i8) -> c_int;
    #[link_name = "D_1392"]
    pub fn CiA402Modes_ExpandSupportedMask(mask: u32, modes: *mut i8, capacity: c_int) -> c_int;
    #[link_name = "D_1393"]
    pub fn CiA402Modes_GetModeName(mode: i8) -> *const c_char;
    #[link_name = "D_1394"]
    pub fn CiA402Modes_GetModeNameEn(mode: i8) -> *const c_char;
    #[link_name = "D_1395"]
    pub fn CiA402Modes_GetModeDescription(mode: i8) -> *const c_char;
    #[link_name = "D_1396"]
    pub fn CiA402Modes_IsCyclicSyncMode(mode: i8) -> c_int;
    #[link_name = "D_1397"]
    pub fn CiA402Modes_RequiresDC(mode: i8) -> c_int;
    #[link_name = "D_1398"]
    pub fn CiA402Modes_IsStandardHomingMethod(method: i8) -> c_int;
    #[link_name = "D_1399"]
    pub fn CiA402Modes_GetHomingMethodName(method: i8) -> *const c_char;
    #[link_name = "D_1400"]
    pub fn CiA402Modes_GetHomingTrigger(method: i8) -> c_int;
    #[link_name = "D_1401"]
    pub fn CiA402Modes_GetHomingDirection(method: i8) -> c_int;
    #[link_name = "D_1402"]
    pub fn CiA402Modes_ListStandardHomingMethods(array: *mut i8, capacity: c_int) -> c_int;

    #[link_name = "D_1421"]
    pub fn EcMailbox_GetTypeName(mbx_type: u16) -> *const c_char;
    #[link_name = "D_1422"]
    pub fn EcMailbox_GetTypeNameEn(mbx_type: u16) -> *const c_char;
    #[link_name = "D_1423"]
    pub fn EcMailbox_GetErrorDescription(mbx_error_code: u16) -> *const c_char;
    #[link_name = "D_1424"]
    pub fn EcMailbox_NextCounter(current: u8) -> u8;

    #[link_name = "D_1425"]
    pub fn EcSoE_GetErrorDescription(soe_error: u16) -> *const c_char;

    #[link_name = "D_1454"]
    pub fn EcSii_FindCategory(
        sii_data: *const u8,
        sii_size: c_int,
        cat_type: u16,
        out_size_bytes: *mut c_int,
    ) -> c_int;
    #[link_name = "D_1455"]
    pub fn EcSii_EnumerateCategories(
        sii_data: *const u8,
        sii_size: c_int,
        cat_types: *mut u16,
        capacity: c_int,
    ) -> c_int;
    #[link_name = "D_1458"]
    pub fn EcSii_GetStringByIndex(
        cat_data: *const u8,
        cat_size: c_int,
        idx: c_int,
        out_buf: *mut u8,
        buf_size: c_int,
    ) -> c_int;
    #[link_name = "D_1457"]
    pub fn EcSii_GetStringCount(cat_data: *const u8, cat_size: c_int) -> c_int;
    #[link_name = "D_1460"]
    pub fn EcSii_GetVendorId(sii_data: *const u8, sii_size: c_int) -> u32;
    #[link_name = "D_1461"]
    pub fn EcSii_GetProductCode(sii_data: *const u8, sii_size: c_int) -> u32;
    #[link_name = "D_1462"]
    pub fn EcSii_GetRevision(sii_data: *const u8, sii_size: c_int) -> u32;
    #[link_name = "D_1463"]
    pub fn EcSii_GetSerialNumber(sii_data: *const u8, sii_size: c_int) -> u32;
    #[link_name = "D_1459"]
    pub fn EcSii_GetConfiguredAlias(sii_data: *const u8, sii_size: c_int) -> u16;
    #[link_name = "D_1446"]
    pub fn EcSii_CoeEnabled(coe_details: u8) -> c_int;
    #[link_name = "D_1447"]
    pub fn EcSii_CoeSdoInfo(coe_details: u8) -> c_int;
    #[link_name = "D_1448"]
    pub fn EcSii_CoePdoAssign(coe_details: u8) -> c_int;
    #[link_name = "D_1449"]
    pub fn EcSii_CoePdoConfig(coe_details: u8) -> c_int;
    #[link_name = "D_1450"]
    pub fn EcSii_CoeUploadAtStartup(coe_details: u8) -> c_int;
    #[link_name = "D_1451"]
    pub fn EcSii_CoeCompleteAccess(coe_details: u8) -> c_int;
    #[link_name = "D_1452"]
    pub fn EcSii_FoeEnabled(foe_details: u8) -> c_int;
    #[link_name = "D_1453"]
    pub fn EcSii_EoeEnabled(eoe_details: u8) -> c_int;

    #[link_name = "D_1403"]
    pub fn EcCouplerId_DetectDeviceType(vendor_id: u32, product_code: u32) -> c_int;
    #[link_name = "D_1404"]
    pub fn EcCouplerId_IsCoupler(vendor_id: u32, product_code: u32) -> c_int;
    #[link_name = "D_1405"]
    pub fn EcCouplerId_IsTerminal(vendor_id: u32, product_code: u32) -> c_int;
    #[link_name = "D_1406"]
    pub fn EcCouplerId_GetVendorName(vendor_id: u32) -> *const c_char;
    #[link_name = "D_1407"]
    pub fn EcCouplerId_GetVendorNameEn(vendor_id: u32) -> *const c_char;
    #[link_name = "D_1408"]
    pub fn EcCouplerId_GetDeviceTypeName(dtype: c_int) -> *const c_char;

    #[link_name = "D_1412"]
    pub fn EcDiagStrings_TopologyDescription(topo: u8) -> *const c_char;
    #[link_name = "D_1413"]
    pub fn EcDiagStrings_TimingMode(mode: u32) -> *const c_char;
    #[link_name = "D_1414"]
    pub fn EcDiagStrings_BreakpointType(bp: u8) -> *const c_char;
    #[link_name = "D_1415"]
    pub fn EcDiagStrings_FormatBreakpoint(
        slave_idx: u16,
        port: u8,
        bp: u8,
        buf: *mut u8,
        buf_size: c_int,
    );

    #[link_name = "D_1615"]
    pub fn EcEsi_LoadFile(file_path: *const c_char) -> i32;
    #[link_name = "D_1616"]
    pub fn EcEsi_LoadDirectory(dir_path: *const c_char) -> i32;
    #[link_name = "D_1617"]
    pub fn EcEsi_Clear();
    #[link_name = "D_1618"]
    pub fn EcEsi_GetLoadedCount() -> i32;
    #[link_name = "D_1619"]
    pub fn EcEsi_BindToSlave(mi: u16, si: u16, file_path: *const c_char) -> i32;
    #[link_name = "D_1620"]
    pub fn EcEsi_AutoMatchAll(mi: u16) -> i32;
    #[link_name = "D_1621"]
    pub fn EcEsi_RegisterStartupParameters(mi: u16, si: u16) -> i32;
    #[link_name = "D_1622"]
    pub fn EcEsi_ApplyAllSlaves(mi: u16) -> i32;

    #[link_name = "D_1602"]
    pub fn EnumerateDefaultPdo(
        master_index: u16,
        slave_index: u16,
        direction: c_int,
        out_indices: *mut u16,
        max_count: c_int,
    ) -> c_int;

    #[link_name = "D_1600"]
    pub fn SetDcSyncMode(master_index: u16, slave_index: u16, sync_type: u8) -> c_int;

    #[link_name = "D_1601"]
    pub fn GetDcSyncMode(master_index: u16, slave_index: u16) -> u8;

    #[link_name = "D_1603"]
    pub fn EcEsi_GetDevicePdoIndices(
        master_index: u16,
        slave_index: u16,
        direction: c_int,
        out_indices: *mut u16,
        max_count: c_int,
    ) -> c_int;

    #[link_name = "D_1604"]
    pub fn EcEsi_GetDevicePdoSizeBits(master_index: u16, slave_index: u16, pdo_index: u16) -> c_int;

    #[link_name = "D_1605"]
    pub fn EcEsi_GetDeviceSmInfo(
        master_index: u16,
        slave_index: u16,
        sm_idx: u8,
        start_addr: *mut u16,
        default_len: *mut u16,
        control_byte: *mut u8,
    ) -> c_int;

    #[link_name = "D_1606"]
    pub fn EcEsi_GetDeviceDcSyncMode(master_index: u16, slave_index: u16) -> c_int;

    #[link_name = "D_1607"]
    pub fn EcEsi_GetDeviceMailboxTimeout(
        master_index: u16,
        slave_index: u16,
        request_ms: *mut c_int,
        response_ms: *mut c_int,
    ) -> c_int;

    #[link_name = "D_1608"]
    pub fn EcEsi_GetDeviceIdentity(
        master_index: u16,
        slave_index: u16,
        vendor_id: *mut u32,
        product_code: *mut u32,
        revision_no: *mut u32,
        name_buf: *mut u8,
        name_buf_size: c_int,
    ) -> c_int;

    #[link_name = "D_1629"]
    pub fn DarraEcat_KernelProbe() -> c_int;

    #[link_name = "D_1630"]
    pub fn DarraEcat_KernelStatusMessage(status: c_int) -> *const c_char;

    #[link_name = "D_1631"]
    pub fn DarraEcat_KernelInstallerUrl() -> *const c_char;

    #[link_name = "D_1667"]
    pub fn GetSlaveWcState(master_index: u16, slave_index: u16) -> u8;

    #[link_name = "D_1668"]
    pub fn GetSlaveAlStatusMirror(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1669"]
    pub fn GetWcDeficit(master_index: u16) -> u16;

    #[link_name = "D_1670"]
    pub fn GetWcStateSeq(master_index: u16) -> u64;

    #[link_name = "D_1671"]
    pub fn GetMappedSlaveCount(master_index: u16) -> u16;

    #[link_name = "D_1672"]
    pub fn GetWkcActualMirror(master_index: u16) -> u16;

    #[link_name = "D_1673"]
    pub fn GetWkcExpectedMirror(master_index: u16) -> u16;

    #[link_name = "D_1027"]
    pub fn TraceLog(msg: *const c_char);

    #[link_name = "D_1074"]
    pub fn GetLastQFBPerNICSlaves(out_slaves_per_nic: *mut c_int, max_count: c_int) -> c_int;

    #[link_name = "D_1078"]
    pub fn ScanSlaveInfo(primary: *const c_char, secondary: *const c_char) -> c_int;

    #[link_name = "D_1083"]
    pub fn QuickScanAllNICs() -> c_int;

    #[link_name = "D_1110"]
    pub fn RecoverSlaveToOP(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1012"]
    pub fn GetGroupActualWKC(master_index: u16, group: u8) -> u16;

    #[link_name = "D_1013"]
    pub fn GetGroupDiag(
        master_index: u16, group: u8,
        consecutive_miss: *mut u16, total_frames: *mut u32, mismatch_frames: *mut u32,
    ) -> c_int;

    #[link_name = "D_1201"]
    pub fn GetSlaveMailboxWriteLength(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1202"]
    pub fn GetSlaveMailboxWriteOffset(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1203"]
    pub fn GetSlaveMailboxReadLength(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1204"]
    pub fn GetSlaveMailboxReadOffset(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1205"]
    pub fn GetSlaveMbxCount(master_index: u16, slave_index: u16) -> u8;

    #[link_name = "D_1254"]
    pub fn GetSlaveSMLength(master_index: u16, slave_index: u16, sm_idx: u8) -> u16;

    #[link_name = "D_1238"]
    pub fn GetSlaveName(master_index: u16, slave_index: u16, buf: *mut u8, buf_size: c_int) -> c_int;

    #[link_name = "D_1239"]
    pub fn GetSlaveDeviceName(master_index: u16, slave_index: u16, buf: *mut u8, buf_size: c_int) -> c_int;

    #[link_name = "D_1323"]
    pub fn GetSlavePortLinkStatus(
        master_index: u16, out_port_link: *mut u8, out_unreachable: *mut u8, max_slaves: u16,
    ) -> c_int;

    #[link_name = "D_1305"]
    pub fn DiagnoseNicHealth(master_index: u16) -> c_int;

    #[link_name = "D_1306"]
    pub fn VerifyNicHealth(master_index: u16, num_probes: c_int, timeout_ms: c_int) -> c_int;

    #[link_name = "D_1307"]
    pub fn AutoRecoverNic(master_index: u16) -> c_int;

    #[link_name = "D_1298"]
    pub fn GetWdkPrimaryFrameTx(master_index: u16) -> u32;

    #[link_name = "D_1299"]
    pub fn GetWdkPrimaryFrameRx(master_index: u16) -> u32;

    #[link_name = "D_1300"]
    pub fn GetWdkSecondaryFrameTx(master_index: u16) -> u32;

    #[link_name = "D_1301"]
    pub fn GetWdkSecondaryFrameRx(master_index: u16) -> u32;

    #[link_name = "D_1302"]
    pub fn GetWdkPdoIdxDropCount(master_index: u16) -> u32;

    #[link_name = "D_1661"]
    pub fn GetTopoPriIntact(master_index: u16) -> u16;

    #[link_name = "D_1662"]
    pub fn GetTopoSecIntact(master_index: u16) -> u16;

    #[link_name = "D_1693"]
    pub fn GetPrimaryWKCEx(master_index: u16) -> u16;

    #[link_name = "D_1694"]
    pub fn GetSecondaryWKCEx(master_index: u16) -> u16;

    #[link_name = "D_1739"]
    pub fn HotSwapRebuild(master_index: u16) -> i32;

    #[link_name = "D_1733"]
    pub fn GetPrimaryWkcRt(master_index: u16) -> u16;

    #[link_name = "D_1734"]
    pub fn GetSecondaryWkcRt(master_index: u16) -> u16;

    #[link_name = "D_1735"]
    pub fn GetPrimaryPhyLinkUp(master_index: u16) -> i32;

    #[link_name = "D_1736"]
    pub fn GetSecondaryPhyLinkUp(master_index: u16) -> i32;

    #[link_name = "D_1540"]
    pub fn EnablePiggybackDiag(master_index: u16, enable: c_int);

    #[link_name = "D_1541"]
    pub fn IsPiggybackDiagEnabled(master_index: u16) -> c_int;

    #[link_name = "D_1658"]
    pub fn GetMasterAlstatRefresh(
        master_index: u16, refresh_us: *mut u64, aggregate: *mut u16, wkc_match: *mut u16,
    );

    #[link_name = "D_1659"]
    pub fn GetPiggybackDiagCounters(
        master_index: u16, brd_tx: *mut u64, brd_rx: *mut u64, brd_miss: *mut u64,
    );

    #[link_name = "D_1660"]
    pub fn GetPiggybackDiagCounters2(
        master_index: u16, alstat_changes: *mut u64, last_alstat: *mut u16, last_slave: *mut u16,
    );

    #[link_name = "D_1632"]
    pub fn GetCycleEventHandle(master_index: u16) -> *mut c_void;

    #[link_name = "D_1633"]
    pub fn GetCycleEventName(master_index: u16) -> *const c_char;

    #[link_name = "D_1634"]
    pub fn WaitForCycleEvent(master_index: u16, timeout_ms: u32) -> c_int;

    #[link_name = "D_1635"]
    pub fn GetCycleCount(master_index: u16) -> u64;

    #[link_name = "D_1656"]
    pub fn AL_StatusCode_GetDescriptionChinese(code: u16) -> *const c_char;

    #[link_name = "D_1657"]
    pub fn AL_StatusCode_GetRecoveryHintChinese(code: u16) -> *const c_char;

    #[link_name = "D_1636"]
    pub fn UnregisterProcessDataCyclicCallbackSync(callback: ProcessDataCyclicCallback);

    #[link_name = "D_1637"]
    pub fn UnregisterProcessDataCyclicCallbackAsync(callback: ProcessDataCyclicCallback);

    #[link_name = "D_1638"]
    pub fn UnregisterSlaveStateChangeCallbackSync(callback: SlaveStateChangeCallback);

    #[link_name = "D_1639"]
    pub fn UnregisterSlaveStateChangeCallbackAsync(callback: SlaveStateChangeCallback);

    #[link_name = "D_1640"]
    pub fn UnregisterEmergencyEventCallback(callback: EmergencyEventCallback);

    #[link_name = "D_1641"]
    pub fn UnregisterSlaveDiscoveryCallbackSync(callback: SlaveDiscoveryCallback);

    #[link_name = "D_1642"]
    pub fn UnregisterSlaveDiscoveryCallbackAsync(callback: SlaveDiscoveryCallback);

    #[link_name = "D_1643"]
    pub fn UnregisterPDOFrameLossCallback(callback: PDOFrameLossCallback);

    #[link_name = "D_1644"]
    pub fn UnregisterRedundancyModeChangedCallback(callback: RedundancyModeChangedCallback);

    #[link_name = "D_1645"]
    pub fn UnregisterSlavePreOpReconfigCallback(callback: SlavePreOpReconfigCallback);

    #[link_name = "D_1646"]
    pub fn UnregisterSlaveIdentityMismatchCallback(callback: SlaveIdentityMismatchCallback);

    #[link_name = "D_1647"]
    pub fn UnregisterInputDataChangedCallback(callback: InputDataChangedCallback);

    #[link_name = "D_1648"]
    pub fn UnregisterSlavePortLinkChangedCallback(callback: SlavePortLinkChangedCallback);

    #[link_name = "D_1651"]
    pub fn UnsetLogCallback(callback: LogCallback);

    #[link_name = "D_1652"]
    pub fn UnsetCrashCallback(callback: CrashNotifyCallback);

    #[link_name = "D_1653"]
    pub fn UnsetDCSyncLostCallback(callback: DCSyncLostCallback);

    #[link_name = "D_1055"]
    pub fn StartPerformanceMonitoring(master_index: u16) -> c_int;

    #[link_name = "D_1056"]
    pub fn StopPerformanceMonitoring(master_index: u16) -> c_int;

    #[link_name = "D_1057"]
    pub fn GetRealtimeStats(master_index: u16, stats: *mut c_void) -> c_int;

    #[link_name = "D_1146"]
    pub fn CiA402_GetTransitionCommand(current: c_int, target: c_int) -> u16;

    #[link_name = "D_1147"]
    pub fn CiA402_RequestTransition(master_index: u16, slave_index: u16, target: c_int) -> u8;

    #[link_name = "D_1148"]
    pub fn CiA402_FaultResetStep(master_index: u16, slave_index: u16, step: c_int) -> u8;

    #[link_name = "D_1149"]
    pub fn CiA402_GetSupportedDriveModes(master_index: u16, slave_index: u16) -> u32;

    #[link_name = "D_1150"]
    pub fn CiA402_IsModeSupported(master_index: u16, slave_index: u16, mode: c_int) -> u8;

    #[link_name = "D_1151"]
    pub fn CiA402_GetQuickStopOption(master_index: u16, slave_index: u16) -> i16;

    #[link_name = "D_1152"]
    pub fn CiA402_SetQuickStopOption(master_index: u16, slave_index: u16, value: i16) -> u8;

    #[link_name = "D_1153"]
    pub fn CiA402_GetShutdownOption(master_index: u16, slave_index: u16) -> i16;

    #[link_name = "D_1154"]
    pub fn CiA402_SetShutdownOption(master_index: u16, slave_index: u16, value: i16) -> u8;

    #[link_name = "D_1155"]
    pub fn CiA402_GetDisableOperationOption(master_index: u16, slave_index: u16) -> i16;

    #[link_name = "D_1156"]
    pub fn CiA402_SetDisableOperationOption(master_index: u16, slave_index: u16, value: i16) -> u8;

    #[link_name = "D_1157"]
    pub fn CiA402_GetHaltOption(master_index: u16, slave_index: u16) -> i16;

    #[link_name = "D_1158"]
    pub fn CiA402_SetHaltOption(master_index: u16, slave_index: u16, value: i16) -> u8;

    #[link_name = "D_1159"]
    pub fn CiA402_GetFaultReactionOption(master_index: u16, slave_index: u16) -> i16;

    #[link_name = "D_1160"]
    pub fn CiA402_SetFaultReactionOption(master_index: u16, slave_index: u16, value: i16) -> u8;

    #[link_name = "D_1161"]
    pub fn CiA402_GetErrorCode(master_index: u16, slave_index: u16) -> u16;

    #[link_name = "D_1162"]
    pub fn CiA402_GetErrorHistory(
        master_index: u16, slave_index: u16, out_codes: *mut u32, max_count: c_int,
    ) -> c_int;

    #[link_name = "D_1163"]
    pub fn CiA402_ClearErrorHistory(master_index: u16, slave_index: u16) -> u8;

    #[link_name = "D_1164"]
    pub fn CiA402_SetHomingMethod(master_index: u16, slave_index: u16, method: i8) -> u8;

    #[link_name = "D_1165"]
    pub fn CiA402_GetHomingMethod(master_index: u16, slave_index: u16) -> i8;

    #[link_name = "D_1166"]
    pub fn CiA402_GetSupportedHomingMethods(
        master_index: u16, slave_index: u16, out_methods: *mut i8, max_count: c_int,
    ) -> c_int;

    #[link_name = "D_1167"]
    pub fn CiA402_IsStandardHomingMethod(method: i8) -> u8;

    #[link_name = "D_1580"]
    pub fn EsmIsLegalTransition(from: c_int, to: c_int) -> c_int;

    #[link_name = "D_1581"]
    pub fn EsmGetLegalTransitions(from: c_int, out_states: *mut u8, max_count: c_int) -> c_int;

    #[link_name = "D_1582"]
    pub fn EsmGetDefaultTimeoutMs(from: c_int, to: c_int) -> u32;

    #[link_name = "D_1583"]
    pub fn EsmIsKnownAlStatusCode(al_status_code: u16) -> c_int;

    #[link_name = "D_1584"]
    pub fn EsmClassifyAlStatusCode(al_status_code: u16) -> c_int;

    #[link_name = "D_1585"]
    pub fn EsmGetMasterClass(master_index: u16) -> u8;

    #[link_name = "D_1259"]
    pub fn MDPGetConfigModuleList(
        master_index: u16, slave_index: u16, out_idents: *mut u32, max_count: c_int,
    ) -> c_int;

    #[link_name = "D_1260"]
    pub fn MDPGetDetectedModuleList(
        master_index: u16, slave_index: u16, out_idents: *mut u32, max_count: c_int,
    ) -> c_int;

    #[link_name = "D_1261"]
    pub fn MDPCheckModuleMatch(
        master_index: u16, slave_index: u16, out_first_mismatch: *mut c_int,
    ) -> c_int;

    #[link_name = "D_1262"]
    pub fn MDPAutoEnumerate(master_index: u16) -> c_int;

    #[link_name = "D_1372"]
    pub fn MBGStart(master_index: u16, udp_port: u16) -> c_int;

    #[link_name = "D_1373"]
    pub fn MBGStop(master_index: u16) -> c_int;

    #[link_name = "D_1374"]
    pub fn MBGIsRunning(master_index: u16) -> c_int;

    #[link_name = "D_1375"]
    pub fn MBGGetStats(master_index: u16, stats: *mut MbgStatsC) -> c_int;

    #[link_name = "D_1376"]
    pub fn MBGResetStats(master_index: u16);

    #[link_name = "D_1377"]
    pub fn MBGGetPort(master_index: u16) -> u16;

    #[link_name = "D_1378"]
    pub fn MBGStartTcp(master_index: u16, tcp_port: u16) -> c_int;

    #[link_name = "D_1379"]
    pub fn MBGStopTcp(master_index: u16) -> c_int;

    #[link_name = "D_1380"]
    pub fn MBGTcpIsRunning(master_index: u16) -> c_int;

    #[link_name = "D_1381"]
    pub fn MBGGetTcpPort(master_index: u16) -> u16;

    #[link_name = "D_1382"]
    pub fn MBGGetSelectedMaster(master_index: u16) -> u16;

    #[link_name = "D_1383"]
    pub fn MBGSetSelectedMaster(master_index: u16, selected: u16) -> c_int;

    #[link_name = "D_1384"]
    pub fn HotConnectAddGroup(
        master_index: u16, group_id: u16, alias: u16, vendor_id: u32, product_code: u32,
    ) -> c_int;

    #[link_name = "D_1385"]
    pub fn HotConnectRemoveGroup(master_index: u16, group_id: u16) -> c_int;

    #[link_name = "D_1386"]
    pub fn HotConnectGetGroupStatus(master_index: u16, group_id: u16) -> c_int;

    #[link_name = "D_1387"]
    pub fn HotConnectEnumerate(master_index: u16, out_buf: *mut c_void, max: c_int) -> c_int;

    #[link_name = "D_1388"]
    pub fn HotConnectClearAll(master_index: u16);

    #[link_name = "D_1389"]
    pub fn HotConnectGetGroupCount(master_index: u16) -> c_int;

    #[link_name = "D_1497"]
    pub fn EOESendFrameEx(
        master_index: u16, slave: u16, port: u8,
        frame_data: *const u8, frame_size: c_int, timeout: c_int,
    ) -> i32;

    #[link_name = "D_1498"]
    pub fn EOESetAddressFilterFull(
        master_index: u16, slave: u16, port: u8,
        mac_filter: *const u8, mac_mask: *const u8, timeout: c_int,
    ) -> i32;

    #[link_name = "D_1499"]
    pub fn EOESetReceiveHook(master_index: u16, callback: Option<EOEFrameCallback>) -> c_int;

    #[link_name = "D_1500"]
    pub fn EOEClearReceiveHook(master_index: u16) -> c_int;

    #[link_name = "D_1522"]
    pub fn VOEGetLastErrorCode(master_index: u16, slave: u16) -> u32;

    #[link_name = "D_1523"]
    pub fn VOEStartNotificationListener(master_index: u16) -> c_int;

    #[link_name = "D_1524"]
    pub fn VOEStopNotificationListener() -> c_int;

    #[link_name = "D_1525"]
    pub fn VOEIsNotificationListening() -> c_int;

    #[link_name = "D_1526"]
    pub fn VOERegisterNotification(
        slave: u16, vendor_id: u32, vendor_type: u16,
        callback: Option<VOENotificationCallback>, user_data: *mut c_void,
    ) -> c_int;

    #[link_name = "D_1527"]
    pub fn VOEUnregisterNotification(subscription_index: c_int) -> c_int;

    #[link_name = "D_1250"]
    pub fn mbx_submit_async_by_master(
        master_index: u16, txn: *mut EcMbxTransactionC, out_ticket: *mut u32,
    ) -> c_int;

    #[link_name = "D_1251"]
    pub fn mbx_wait_by_master(master_index: u16, ticket: u32, timeout_ms: c_int) -> c_int;

    #[link_name = "D_1252"]
    pub fn mbx_cancel_by_master(master_index: u16, ticket: u32) -> c_int;

    #[link_name = "D_1253"]
    pub fn mbx_get_result_by_master(
        master_index: u16, ticket: u32, txn: *mut EcMbxTransactionC,
    ) -> c_int;

    #[link_name = "D_1587"]
    pub fn GetCachePoolStatus(master_index: u16) -> c_int;

    #[link_name = "D_1588"]
    pub fn GetCachePoolMode(master_index: u16) -> c_int;

    #[link_name = "D_1591"]
    pub fn GetCachePoolError(master_index: u16) -> c_int;

    #[link_name = "D_1554"]
    pub fn CopyMasterState(master_index: u16, out_state: *mut c_void) -> c_int;

    #[link_name = "D_1598"]
    pub fn GetDiagnosticsSnapshot(master_index: u16) -> *const c_void;

    #[link_name = "D_1308"]
    pub fn LockExpectedWKC(master_index: u16) -> c_int;

    #[link_name = "D_1309"]
    pub fn UnlockExpectedWKC(master_index: u16) -> c_int;

    #[link_name = "D_1310"]
    pub fn EnforceExpectedWkcLock(master_index: u16) -> c_int;

    #[link_name = "D_1069"]
    pub fn SetWdkPdOffloadExtraGroup(master_index: u16, group: u8) -> c_int;

    #[link_name = "D_1070"]
    pub fn DisableWdkPdOffloadExtraGroup(master_index: u16, group: u8) -> c_int;

    #[link_name = "D_1071"]
    pub fn UpdateWdkWkcExpected(master_index: u16, expected: u16) -> c_int;

    #[link_name = "D_1000"]
    pub fn RegisterExtraGroupMapping(master_index: u16, group: u8, slave_index: u16) -> c_int;

    #[link_name = "D_1001"]
    pub fn ClearExtraGroupMapping(master_index: u16) -> c_int;

    #[link_name = "D_1663"]
    pub fn GetSlaveFreeRunDemoted(master_index: u16, slave_index: u16) -> u8;

    #[link_name = "D_1664"]
    pub fn GetSlaveMailboxHealth(master_index: u16, slave_index: u16) -> u8;

    #[link_name = "D_1665"]
    pub fn GetSlaveHealthDegradedCount(master_index: u16, slave_index: u16) -> u32;

    #[link_name = "D_1666"]
    pub fn RecoverSlaveMailboxHealth(master_index: u16, slave_index: u16) -> c_int;

    #[link_name = "D_1674"]
    pub fn GetRtPreemptCount(master_index: u16) -> u64;

    #[link_name = "D_1675"]
    pub fn GetRtPreemptPeakNs(master_index: u16) -> u32;

    #[link_name = "D_1676"]
    pub fn GetBigGapUnknownCount(master_index: u16) -> u64;

    #[link_name = "D_1677"]
    pub fn GetSmiMsrAvailable(master_index: u16) -> u32;

    #[link_name = "D_1678"]
    pub fn GetWdkRtCpuIndex(master_index: u16) -> c_int;

    #[link_name = "D_1679"]
    pub fn GetWdkRxCpuIndex(master_index: u16) -> c_int;

    #[link_name = "D_1680"]
    pub fn GetWdkJitterInstrumentVer(master_index: u16) -> u32;

    #[link_name = "D_1681"]
    pub fn GetWdkJitterHistBin(master_index: u16, bin_index: u32) -> u32;

    #[link_name = "D_1682"]
    pub fn GetWdkJitterTotalSamples(master_index: u16) -> u64;

    #[link_name = "D_1683"]
    pub fn GetWdkJitterMinNs(master_index: u16) -> u32;

    #[link_name = "D_1684"]
    pub fn GetWdkJitterLastWakeDeltaNs(master_index: u16) -> c_int;

    #[link_name = "D_1685"]
    pub fn GetWdkPathCountFast(master_index: u16) -> u32;

    #[link_name = "D_1686"]
    pub fn GetWdkPathCountMed(master_index: u16) -> u32;

    #[link_name = "D_1687"]
    pub fn GetWdkPathCountSlow(master_index: u16) -> u32;

    #[link_name = "D_1688"]
    pub fn GetWdkKtimerWakeNormalCnt(master_index: u16) -> u32;

    #[link_name = "D_1689"]
    pub fn GetWdkKtimerWakeOverrunCnt(master_index: u16) -> u32;

    #[link_name = "D_1690"]
    pub fn GetWdkDispatchCycleMaxJitterNs(master_index: u16) -> u32;

    #[link_name = "D_1691"]
    pub fn GetWdkDrainCycleMaxJitterNs(master_index: u16) -> u32;

    #[link_name = "D_1692"]
    pub fn GetWdkDiagCounter(master_index: u16, counter_id: u32) -> u32;

    #[link_name = "D_1695"]
    pub fn AcknowledgeSlaveReplacement(master_index: u16, slave_index: u16) -> c_int;

    #[link_name = "D_1696"]
    pub fn EnablePDOMonitoring(enable: u8);

    #[link_name = "D_1697"]
    pub fn GetPDOMapping(
        master_index: u16, slave_index: u16, pdo_type: u16,
        mapping_buffer: *mut c_void, buffer_size: u32, mapping_count: *mut u32,
    ) -> u8;

    #[link_name = "D_1698"]
    pub fn GetPDOStats(master_index: u16, slave_index: u16) -> *const c_void;

    #[link_name = "D_1701"]
    pub fn IsPDOMonitoringEnabled() -> u8;

    #[link_name = "D_1702"]
    pub fn PDOBatchRead(
        master_index: u16, slave_indices: *const u16, slave_count: u32,
        data_buffers: *mut *mut c_void, buffer_sizes: *const u32, bytes_read: *mut u32,
    ) -> u32;

    #[link_name = "D_1703"]
    pub fn PDOBatchWrite(
        master_index: u16, slave_indices: *const u16, slave_count: u32,
        data_buffers: *const *const c_void, data_sizes: *const u32,
    ) -> u32;

    #[link_name = "D_1704"]
    pub fn PDOReadDirect(
        master_index: u16, slave_index: u16, pdo_index: u16,
        data_buffer: *mut c_void, buffer_size: u32, bytes_read: *mut u32,
    ) -> u8;

    #[link_name = "D_1705"]
    pub fn PDOWriteDirect(
        master_index: u16, slave_index: u16, pdo_index: u16,
        data_buffer: *const c_void, data_size: u32,
    ) -> u8;

    #[link_name = "D_1720"]
    pub fn ResetPDOStats(master_index: u16, slave_index: u16);
}

#[repr(C)]
#[derive(Debug, Clone, Copy, Default)]
pub struct EcMbxStatsC {

    pub total_sent: u64,

    pub total_received: u64,

    pub total_timeout: u64,

    pub total_mbx_error: u64,

    pub total_proto_error: u64,

    pub total_cancelled: u64,

    pub last_error_code: u32,

    pub _pad1: u32,

    pub last_error_time_us: u64,

    pub total_latency_us: u64,
}
