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 size_t ExportLogRecordToPcapFunc(
    log.Record const* record,
    io.MappedFile* pcapFile,
    uint64_t pcapOffset
    );

// enums

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

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

enum
{
    ModbusMaxPduSize = sizeof(ModbusWriteMultiplePdu) + 255,
};

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

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
{
    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
{
    RpdFileSignature = ':dpr',
};

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

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;
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 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 EthernetHdr;
struct EthernetHdr_ieee8023;
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 ModbusAsciiAduHdr;
struct ModbusExceptionPdu;
struct ModbusGetCommEventCounterReplyPdu;
struct ModbusGetCommEventLogReplyPdu;
struct ModbusMaskWritePdu;
struct ModbusPduHdr;
struct ModbusReadExceptionStatusReplyPdu;
struct ModbusReadFifoPdu;
struct ModbusReadFifoReplyPdu;
struct ModbusReadPdu;
struct ModbusReadReplyPdu;
struct ModbusReadWriteMultiplePdu;
struct ModbusRtuAduHdr;
struct ModbusTcpAduHdr;
struct ModbusWriteMultiplePdu;
struct ModbusWriteMultipleReplyPdu;
struct ModbusWritePdu;
struct PcapFileHdr;
struct PcapPacketHdr;
struct RpdHdr;
struct RpdVersion;
struct TcpHdr;
struct UdpHdr;
struct UsbProduct;

// classes

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

// global functions

bool errorcode exportLogToPcap(
    char const* logFileName,
    char const* pcapFileName,
    io.PcapLinkType linkType,
    size_t snapshotSize,
    io.ExportLogRecordToPcapFunc* exportRecordFunc
    );

size_t errorcode writePcapPacket(
    io.MappedFile* pcapFile,
    uint64_t pcapOffset,
    uint64_t timestamp,
    void const* p,
    size_t size
    );

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

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

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

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

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

char const* formatDnsDigest(void const* p);

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

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

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

char const* 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
    );

char const* formatEthernetDigest(void const* p);
char const* formatEthernetAddress(void const* p);
char const* formatIcmpDigest(void const* p);
char const* formatIcmp6Digest(void const* p);
char const* formatIgmpDigest(void const* p);
char const* formatIpDigest(void const* p);
char const* formatIpAddress(void const* p);
char const* formatIp6Digest(void const* p);
char const* formatIp6Address(void const* p);
char const* formatLlcDigest(void const* p);
char const* getModbusFuncString(io.ModbusFunc func);
char const* getModbusExceptionString(io.ModbusException exception);

size_t errorcode getModbusPduSize(
    io.ModbusRole role,
    io.ModbusPduHdr const* pduHdr,
    size_t size
    );

size_t errorcode getModbusRtuAduSize(
    io.ModbusRole role,
    io.ModbusRtuAduHdr const* aduHdr,
    size_t size
    );

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

} // namespace io