namespace io

namespace io {

// typedefs

typedef uint8_t U8;
typedef uint32_t U32;
typedef void cdecl JLINK_LOG(char const thin* sErr);

typedef int cdecl JLINK_FUNC_MRU_GETLIST(
    io.U32 Group,
    char thin* sList,
    io.U32 BufferSize
);

typedef io.ModbusWriteSingleParams ModbusWriteSingleReplyParams;
typedef io.ModbusReadReplyParams ModbusReadWriteFileRecordParams;
typedef io.ModbusReadReplyPdu ModbusReadWriteFileRecordPdu;
typedef io.ModbusMaskWriteParams ModbusMaskWriteReplyParams;
typedef io.ModbusReadReplyParams ModbusReadWriteMultipleRegistersReplyParams;
typedef io.ModbusReadReplyParams ModbusReportServerIdReplyParams;
typedef io.ModbusWriteSinglePdu ModbusWriteSingleReplyPdu;
typedef io.ModbusMaskWritePdu ModbusMaskWriteReplyPdu;
typedef io.ModbusReadReplyPdu ModbusReadWriteMultipleRegistersReplyPdu;

// enums

enum {
    ModbusDigestValueCount = 3,
};

enum {
    JLINKARM_RTTERMINAL_BUFFER_DIR_UP   = 0,
    JLINKARM_RTTERMINAL_BUFFER_DIR_DOWN = 1,
};

enum {
    ModbusFileReferenceType = 6,
    ModbusMaxPduSize        = 253,
    ModbusMaxRtuAduSize     = sizeof(ModbusRtuAduHdr) + ModbusMaxPduSize + 2,
    ModbusMaxAsciiAduSize   = 1 +(sizeof(ModbusRtuAduHdr) + ModbusMaxPduSize)* 2 + 4,
    ModbusMaxTcpAduSize     = sizeof(ModbusTcpAduHdr) + ModbusMaxPduSize,
};

enum {
    JLINKARM_RTTERMINAL_CMD_START     = 0,
    JLINKARM_RTTERMINAL_CMD_STOP      = 1,
    JLINKARM_RTTERMINAL_CMD_GETDESC   = 2,
    JLINKARM_RTTERMINAL_CMD_GETNUMBUF = 3,
    JLINKARM_RTTERMINAL_CMD_GETSTAT   = 4,
};

enum {
    JLINK_MRU_GROUP_DEVICE       = 0,
    JLINK_MRU_GROUP_SETTINGSFILE = 1,
    JLINK_MRU_GROUP_SCRIPTFILE   = 2,
};

enum {
    JLINKARM_TIF_JTAG         = 0,
    JLINKARM_TIF_SWD          = 1,
    JLINKARM_TIF_BDM3         = 2,
    JLINKARM_TIF_FINE         = 3,
    JLINKARM_TIF_ICSP         = 4,
    JLINKARM_TIF_SPI          = 5,
    JLINKARM_TIF_C2           = 6,
    JLINKARM_TIF_CJTAG        = 7,
    JLINKARM_TIF_SWIM         = 8,
    JLINKARM_TIF_PDI          = 9,
    JLINKARM_TIF_MC2WJTAG_TDI = 10,
    JLINKARM_TIF_NUMTIFS      = 11,
};

enum {
    JLINKARM_DEVICE_MAX_NUM_FLASH_BANKS = 16,
};

enum {
    PcapFileSignature    = '\xa1\xb2\xc3\xd4',
    PcapFileMajorVersion = 2,
    PcapFileMinorVersion = 4,
};

enum {
    RpdFileSignature = ':dpr',
};

enum ArpHardwareType;
enum ArpOpcode;
enum Df1Char;
enum Df1ChecksumKind;
enum Df1CmdDirection;
enum Df1CmdFnc;
enum Df1CmdPrefix;
enum Df1CmdPriority;
enum Df1CpuMode;
enum Df1FileProtection;
enum Df1FileType;
enum Df1LocalStatus;
enum Df1Mode;
enum Df1PlcMode;
enum Df1RemoteStatus;
enum DhcpCookie;
enum DhcpFlags;
enum DhcpHardwareType;
enum DhcpMessageType;
enum DhcpOpcode;
bitflag enum DhcpOptionOverload;
enum DhcpOptionType;
enum DnsClass;
bitflag enum DnsFlags;
enum DnsOpcode;
enum DnsResponseCode;
enum DnsType;
enum EthernetType;
bitflag enum HwcEthernetTapPacketFlag;
enum HwcMsgCode;
enum I2cDecodeResult;
enum Icmp6Type;
enum IcmpType;
enum IgmpType;
bitflag enum IpFlags;
enum IpOptionNumber;
enum IpOptionType;
bitflag enum IpOptionTypeFlag;
enum IpProtocol;
enum JLINK_FUNC_INDEX;
enum LoopbackProtocolFamily;
enum Lsap;
enum ModbusChecksumKind;
enum ModbusDiagnosticSubFunc;
enum ModbusException;
enum ModbusFunc;
enum ModbusProtocol;
enum ModbusRole;
enum SpiDecodeResult;
bitflag enum TcpFlags;
enum UartDecodeResult;

// structs

struct ArpHdr;
struct Df1AppMsgHdr;
struct Df1ApplyPortConfiguration;
struct Df1ChangeMode;
struct Df1CloseFile;
struct Df1FileReadWrite;
struct Df1ModifyPlc2CompatibilityFile;
struct Df1OpenFile;
struct Df1PhysicalRead;
struct Df1PhysicalWrite;
struct Df1ProtectedTypedLogicalReadWrite;
struct Df1ProtectedTypedReadWrite;
struct Df1Read;
struct Df1SetCpuMode;
struct Df1SetEnqs;
struct Df1SetNaks;
struct Df1SetTimeout;
struct Df1SetVariables;
struct Df1Write;
struct DhcpHdr;
struct DhcpOptionHdr;
struct DnsAnswerRrSuffix;
struct DnsHdr;
struct DnsQuestionRrSuffix;
struct EthernetAddress;
struct EthernetHdr;
struct EthernetHdr_ieee8023;
struct HwcEthernetTapPacketHdr;
struct HwcMsgHdr;
struct HwcSerialConfig;
struct Icmp6Hdr;
struct IcmpHdr;
struct IgmpHdr;
struct Ip6Hdr;
struct IpHdr;
struct IpPseudoHdr;
struct JLINKARM_DEVICE_INFO;
struct JLINK_FLASH_AREA_INFO;
struct JLINK_FLASH_BANK_INFO;
struct JLINK_FLASH_BANK_INFO_EXT;
struct JLINK_PCODE_INFO;
struct JLINK_RAM_AREA_INFO;
struct JLINK_RTTERMINAL_BUFDESC;
struct JLINK_RTTERMINAL_START;
struct JLINK_RTTERMINAL_STATUS;
struct JLINK_RTTERMINAL_STOP;
struct LlcHdr;
struct LlcHdr16;
struct LoopbackHdr;
struct ModbusBitBank;
struct ModbusDiagnosticsParams;
struct ModbusExceptionParams;
struct ModbusExceptionPdu;
struct ModbusFileRecord;
struct ModbusGetCommEventCounterReplyParams;
struct ModbusGetCommEventCounterReplyPdu;
struct ModbusGetCommEventLogReplyParams;
struct ModbusGetCommEventLogReplyPdu;
struct ModbusMaskWriteParams;
struct ModbusMaskWritePdu;
struct ModbusPduHdr;
struct ModbusReadExceptionStatusReplyParams;
struct ModbusReadExceptionStatusReplyPdu;
struct ModbusReadFifoQueueParams;
struct ModbusReadFifoQueuePdu;
struct ModbusReadFifoQueueReplyParams;
struct ModbusReadFifoQueueReplyPdu;
struct ModbusReadFileRecordReply;
struct ModbusReadParams;
struct ModbusReadPdu;
struct ModbusReadReplyParams;
struct ModbusReadReplyPdu;
struct ModbusReadWriteMultipleRegistersParams;
struct ModbusReadWriteMultipleRegistersPdu;
struct ModbusReplyPduHdr;
struct ModbusRtuAduHdr;
struct ModbusRtuAduPduHdr;
struct ModbusRtuCrc;
struct ModbusTcpAduHdr;
struct ModbusTcpAduPduHdr;
struct ModbusWriteMultipleCoilsParams;
struct ModbusWriteMultipleParams;
struct ModbusWriteMultiplePdu;
struct ModbusWriteMultipleRegistersParams;
struct ModbusWriteMultipleReplyParams;
struct ModbusWriteMultipleReplyPdu;
struct ModbusWriteSingleParams;
struct ModbusWriteSinglePdu;
struct PcapFileHdr;
struct PcapPacketHdr;
struct RpdHdr;
struct RpdVersion;
struct TcpHdr;
struct UdpHdr;
struct UsbProduct;

// classes

class FileIdMgr;
class HwcProtoDecoder;
class I2cSignalDecoder;
class IpDecoder;
class IpDefragmenter;
class JLinkLib;
class SpiSignalDecoder;
class UartSignalDecoder;
class UsbDb;
class UsbVendor;

// global variables

io.HidDb g_hidDb;

// global functions

string_t detectSerialBuggyDriver(string_t portName);
void setConservativeSerialSettings(io.Serial* serial);
bool isEvenNonZeroBitCount(uint_t c);
io.UsbDb* getStdUsbDb();
string_t formatArpDigest(void const* p);
string_t getDf1ChecksumKindString(io.Df1ChecksumKind kind);
string_t formatDhcpDigest(void const* p);

io.DhcpOptionHdr const* findDhcpOption(
    io.DhcpOptionType type,
    void const* options,
    size_t size
);

string_t formatString(
    void const* p,
    size_t size
);

string_t formatEthernetAddress(void const* p);
string_t formatIpAddress(void const* p);

string_t formatDhcpParameterRequestList(
    void const* p,
    size_t size
);

string_t formatDhcpClientIdentifier(
    void const* p,
    size_t size
);

string_t formatDnsDigest(void const* p);

size_t scanDnsName(
    void const* p,
    size_t size
);

void const* scanDnsName(
    void const* p,
    void const* end
);

string_t formatDnsName(
    void const* p,
    size_t size,
    void const* base
);

string_t formatDnsName(
    void const* p,
    void const* end,
    void const* base
);

size_t formatDnsName(
    std.StringBuilder* string,
    void const* p,
    size_t size,
    void const* base
);

void const* formatDnsName(
    std.StringBuilder* string,
    void const* p,
    void const* end,
    void const* base
);

string_t formatEthernetDigest(void const* p);
string_t formatIcmpDigest(void const* p);
string_t formatIcmp6Digest(void const* p);
string_t formatIgmpDigest(void const* p);
string_t formatIpDigest(void const* p);
string_t formatIp6Digest(void const* p);
string_t formatLlcDigest(void const* p);

void layoutModbusRegisters(
    jnc.DynamicLayout* layout,
    size_t count,
    size_t size
);

void async layoutModbusPdu(
    jnc.DynamicLayout* layout,
    io.ModbusRole role
);

void appendModbusPduDigest(
    std.StringBuilder* digest,
    void const* p,
    size_t size,
    io.ModbusRole role
);

uint16_t crc16_modbus(
    void const* p,
    size_t size
);

string_t getModbusChecksumValidityString(bool isValid);
string_t formatModbusRtuCrc(void const* p);
string_t formatModbusAsciiLrc(void const* p);

void async layoutModbusAdu(
    jnc.DynamicLayout* layout,
    io.ModbusProtocol protocol,
    io.ModbusRole role
);

string_t getModbusAduDigest(
    void const* p,
    size_t size,
    jnc.ModuleItemDecl* decl
);

string_t getModbusRegisterDigest(
    void const* p0,
    size_t size
);

string_t getModbusBitDigest(
    void const* p,
    size_t size
);

string_t formatTcpFlagString(io.TcpFlags flags);
string_t formatTcpDigest(void const* p);
string_t formatUdpDigest(void const* p);

} // namespace io