/*++

Copyright (c) Microsoft Corporation.  All rights reserved.

Module Name:

    NFCDTADev.h

Abstract:

    Header file for the NFC DTA device driver interface

--*/

#pragma once

#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)

//
// Interface GUIDs
//
#ifdef DEFINE_GUID

// {7fd3f30b-5e49-4be1-b3aa-af06260d236a}
DEFINE_GUID(GUID_DEVINTERFACE_NFCDTA, 0x7fd3f30b, 0x5e49, 0x4be1, 0xb3, 0xaa, 0xaf, 0x06, 0x26, 0x0d, 0x23, 0x6a);

#endif

//
// NFC DTA DDI
//

#define IOCTL_NFCDTA_CONFIG_RF_DISCOVERY            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_RF_DISCOVERY_CONFIG
#define IOCTL_NFCDTA_REMOTE_DEV_GET_NEXT            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0501, METHOD_BUFFERED, FILE_ANY_ACCESS) // Output: NFC_REMOTE_DEV_INFO
#define IOCTL_NFCDTA_REMOTE_DEV_CONNECT             CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0502, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_HANDLE
#define IOCTL_NFCDTA_REMOTE_DEV_DISCONNECT          CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0503, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEVICE_DISCONNET
#define IOCTL_NFCDTA_REMOTE_DEV_TRANSCEIVE          CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0504, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_SEND_INFO Output: NFC_REMOTE_DEV_RECV_INFO
#define IOCTL_NFCDTA_REMOTE_DEV_RECV                CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0505, METHOD_BUFFERED, FILE_ANY_ACCESS) // Output: NFC_REMOTE_DEV_RECV_INFO
#define IOCTL_NFCDTA_REMOTE_DEV_SEND                CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0506, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_SEND_INFO
#define IOCTL_NFCDTA_REMOTE_DEV_CHECK_PRESENCE      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0507, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_HANDLE
#define IOCTL_NFCDTA_CONFIG_P2P_PARAM               CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0508, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_P2P_PARAM_CONFIG
#define IOCTL_NFCDTA_SET_RF_CONFIG                  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0509, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: TLV-encoded BYTE array, 1st byte contains number of parameters

//
// NDEF
//
#define IOCTL_NFCDTA_REMOTE_DEV_NDEF_WRITE               CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0510, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_SEND_INFO
#define IOCTL_NFCDTA_REMOTE_DEV_NDEF_READ                CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0511, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_HANDLE Output: NFC_REMOTE_DEV_RECV_INFO
#define IOCTL_NFCDTA_REMOTE_DEV_NDEF_CONVERT_READ_ONLY   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0512, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_HANDLE
#define IOCTL_NFCDTA_REMOTE_DEV_NDEF_CHECK               CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0513, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_HANDLE Output: NFC_NDEF_INFO

//
// LLCP
//
#define IOCTL_NFCDTA_LLCP_CONFIG                    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0520, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_CONFIG
#define IOCTL_NFCDTA_LLCP_ACTIVATE                  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0521, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_HANDLE
#define IOCTL_NFCDTA_LLCP_DEACTIVATE                CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0522, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_HANDLE
#define IOCTL_NFCDTA_LLCP_DISCOVER_SERVICES         CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0523, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SERVICE_DISCOVER_REQUEST Output: NFC_LLCP_SERVICE_DISCOVER_SAP
#define IOCTL_NFCDTA_LLCP_LINK_STATUS_CHECK         CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0524, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_REMOTE_DEV_HANDLE
#define IOCTL_NFCDTA_LLCP_GET_NEXT_LINK_STATUS      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0525, METHOD_BUFFERED, FILE_ANY_ACCESS) // Output: NFC_LLCP_LINK_STATUS
#define IOCTL_NFCDTA_LLCP_SOCKET_CREATE             CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0526, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_INFO Output: NFC_LLCP_SOCKET_HANDLE
#define IOCTL_NFCDTA_LLCP_SOCKET_CLOSE              CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0527, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_HANDLE
#define IOCTL_NFCDTA_LLCP_SOCKET_BIND               CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0528, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_SERVICE_INFO
#define IOCTL_NFCDTA_LLCP_SOCKET_LISTEN             CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0529, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_HANDLE Output: NFC_LLCP_SOCKET_HANDLE
#define IOCTL_NFCDTA_LLCP_SOCKET_ACCEPT             CTL_CODE(FILE_DEVICE_UNKNOWN, 0x052a, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_ACCEPT_INFO
#define IOCTL_NFCDTA_LLCP_SOCKET_CONNECT            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x052b, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_CONNECT_INFO
#define IOCTL_NFCDTA_LLCP_SOCKET_DISCONNECT         CTL_CODE(FILE_DEVICE_UNKNOWN, 0x052c, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_HANDLE
#define IOCTL_NFCDTA_LLCP_SOCKET_RECV               CTL_CODE(FILE_DEVICE_UNKNOWN, 0x052d, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_HANDLE Output: NFC_LLCP_SOCKET_PAYLOAD
#define IOCTL_NFCDTA_LLCP_SOCKET_RECV_FROM          CTL_CODE(FILE_DEVICE_UNKNOWN, 0x052e, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_HANDLE Output: NFC_LLCP_SOCKET_PAYLOAD
#define IOCTL_NFCDTA_LLCP_SOCKET_SEND               CTL_CODE(FILE_DEVICE_UNKNOWN, 0x052f, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_PAYLOAD
#define IOCTL_NFCDTA_LLCP_SOCKET_SNED_TO            CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0530, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_CL_PAYLOAD
#define IOCTL_NFCDTA_LLCP_SOCKET_GET_NEXT_ERROR     CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0531, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_LLCP_SOCKET_HANDLE Output: NFC_LLCP_SOCKET_ERROR_INFO

//
// SNEP Server
//
#define IOCTL_NFCDTA_SNEP_INIT_SERVER                   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0540, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SNEP_SERVER_INFO Output: NFC_SNEP_SERVER_HANDLE
#define IOCTL_NFCDTA_SNEP_DEINIT_SERVER                 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0541, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SNEP_SERVER_HANDLE
#define IOCTL_NFCDTA_SNEP_SERVER_GET_NEXT_CONNECTION    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0542, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SNEP_SERVER_HANDLE Output: NFC_SNEP_SERVER_CONNECTION_HANDLE
#define IOCTL_NFCDTA_SNEP_SERVER_ACCEPT                 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0543, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SNEP_SERVER_ACCEPT_INFO
#define IOCTL_NFCDTA_SNEP_SERVER_GET_NEXT_REQUEST       CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0544, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SNEP_SERVER_HANDLE Output: NFC_SNEP_SERVER_REQUEST
#define IOCTL_NFCDTA_SNEP_SERVER_SEND_RESPONSE          CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0545, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SNEP_SERVER_RESPONSE_INFO Output: NFC_SNEP_SERVER_RESPONSE_INFO

//
// SNEP Client
//
#define IOCTL_NFCDTA_SNEP_INIT_CLIENT               CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0550, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SNEP_CLIENT_INFO Output: NFC_SNEP_CLIENT_HANDLE
#define IOCTL_NFCDTA_SNEP_DEINIT_CLIENT             CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0551, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SNEP_CLIENT_HANDLE
#define IOCTL_NFCDTA_SNEP_CLIENT_PUT                CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0552, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SNEP_CLIENT_PUT_INFO
#define IOCTL_NFCDTA_SNEP_CLIENT_GET                CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0553, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SNEP_CLIENT_GET_INFO Output: NFC_SNEP_CLIENT_DATA_BUFFER

//
// SE
//
#define IOCTL_NFCDTA_SE_ENUMERATE                   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0560, METHOD_BUFFERED, FILE_ANY_ACCESS) // Output: NFC_SE_LIST
#define IOCTL_NFCDTA_SE_SET_EMULATION_MODE          CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0561, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SE_EMULATION_MODE_INFO
#define IOCTL_NFCDTA_SE_SET_ROUTING_TABLE           CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0562, METHOD_BUFFERED, FILE_ANY_ACCESS) // Input: NFC_SE_ROUTING_TABLE
#define IOCTL_NFCDTA_SE_GET_NEXT_EVENT              CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0563, METHOD_BUFFERED, FILE_ANY_ACCESS) // Output: NFC_SE_EVENT_INFO

typedef enum _NFC_RF_DISCOVERY_MODE {
    RfDiscoveryConfig,
    RfDiscoveryStart,
    RFDiscoveryResume
} NFC_RF_DISCOVERY_MODE, *PNFC_RF_DISCOVERY_MODE;

typedef struct _NFC_RF_DISCOVERY_CONFIG {
    USHORT usTotalDuration;
    ULONG ulPollConfig;
    BOOLEAN fDisableCardEmulation;
    UCHAR ucNfcIPMode;
    BOOLEAN fNfcIPTgtModeDisable;
    UCHAR ucNfcIPTgtMode;
    UCHAR ucNfcCEMode;
    UCHAR ucBailoutConfig;
    UCHAR ucSystemCode[2];
    UCHAR ucRequestCode;
    UCHAR ucTimeSlotNumber;
    NFC_RF_DISCOVERY_MODE eRfDiscoveryMode;
} NFC_RF_DISCOVERY_CONFIG, *PNFC_RF_DISCOVERY_CONFIG;

typedef enum _NFC_P2P_MODE {
    NfcDepDefault,
    NfcDepPoll,
    NfcDepListen
} NFC_P2P_MODE, *PNFC_P2P_MODE;

#define MAX_ATR_LENGTH 48

typedef struct _NFC_P2P_PARAM_CONFIG {
    NFC_P2P_MODE eP2pMode;
    _Field_range_(<= , MAX_ATR_LENGTH) BYTE cbGeneralBytes;
    _Field_size_bytes_(cbGeneralBytes) BYTE pbGeneralBytes[MAX_ATR_LENGTH];
} NFC_P2P_PARAM_CONFIG, *PNFC_P2P_PARAM_CONFIG;

typedef enum _NFC_DEVICE_TYPE {
    NfcType1Tag,
    NfcType2Tag,
    NfcType3Tag,
    NfcType4Tag,
    NfcIP1Target,
    NfcIP1Initiator,
    NfcReader
} NFC_DEVICE_TYPE, *PNFC_DEVICE_TYPE;

typedef BYTE NFC_RF_TECHNOLOGY;
typedef BYTE NFC_RF_PROTOCOL;

#define MAX_UID_SIZE 16

typedef HANDLE NFC_REMOTE_DEV_HANDLE, *PNFC_REMOTE_DEV_HANDLE;

typedef struct _NFC_REMOTE_DEV_INFO {
    NFC_REMOTE_DEV_HANDLE hRemoteDev;
    NFC_DEVICE_TYPE eType;
    NFC_RF_TECHNOLOGY eRFTech;
    NFC_RF_PROTOCOL eProtocol;
    _Field_range_(<= , MAX_UID_SIZE) BYTE cbUid;
    _Field_size_bytes_(cbUid) BYTE pbUid[MAX_UID_SIZE];
} NFC_REMOTE_DEV_INFO, *PNFC_REMOTE_DEV_INFO;

typedef enum _NFC_RELEASE_TYPE {
    IdleMode,
    SleepMode,
    Discovery,
} NFC_RELEASE_TYPE, *PNFC_RELEASE_TYPE;

typedef struct _NFC_REMOTE_DEVICE_DISCONNET {
    NFC_REMOTE_DEV_HANDLE hRemoteDev;
    NFC_RELEASE_TYPE eReleaseType;
} NFC_REMOTE_DEVICE_DISCONNET, *PNFC_REMOTE_DEVICE_DISCONNET;

typedef struct _NFC_DATA_BUFFER {
    USHORT cbBuffer;
    _Field_size_bytes_(cbBuffer) BYTE pbBuffer[ANYSIZE_ARRAY];
} NFC_DATA_BUFFER, *PNFC_DATA_BUFFER;

typedef struct _NFC_REMOTE_DEV_SEND_INFO {
    NFC_REMOTE_DEV_HANDLE hRemoteDev;
    USHORT usTimeOut;
    NFC_DATA_BUFFER sSendBuffer;
} NFC_REMOTE_DEV_SEND_INFO, *PNFC_REMOTE_DEV_SEND_INFO;

typedef struct _NFC_REMOTE_DEV_RECV_INFO {
    NFC_REMOTE_DEV_HANDLE hRemoteDev;
    NFC_DATA_BUFFER sRecvBuffer;
} NFC_REMOTE_DEV_RECV_INFO, *PNFC_REMOTE_DEV_RECV_INFO;

typedef struct _NFC_NDEF_INFO {
    BOOLEAN fIsNdefFormatted;
    BOOLEAN fIsReadOnly;
    DWORD dwActualMessageLength;
    DWORD dwMaxMessageLength;
} NFC_NDEF_INFO, *PNFC_NDEF_INFO;

typedef struct _LLCP_SOCKET_OPTION {
    USHORT uMIUX;
    BYTE bRW;
} NFC_LLCP_SOCKET_OPTION, *PNFC_LLCP_SOCKET_OPTION;

#define MAX_LLCP_SERVICE_NAME_SIZE 256

typedef struct _NFC_LLCP_CONFIG {
    USHORT uMIU;
    USHORT uWKS;
    BYTE bLTO;
    BYTE bOptions;
    BOOLEAN fAutoActivate;
} NFC_LLCP_CONFIG, *PNFC_LLCP_CONFIG;

typedef struct _NFC_LLCP_SERVICE_NAME_ENTRY {
    _Field_range_(<= , MAX_LLCP_SERVICE_NAME_SIZE) DWORD cbServiceName;
    _Field_size_bytes_(cbServiceName) BYTE pbServiceName[ANYSIZE_ARRAY];
} NFC_LLCP_SERVICE_NAME_ENTRY, *PNFC_LLCP_SERVICE_NAME_ENTRY;

typedef struct _NFC_LLCP_SERVICE_DISCOVER_REQUEST {
    NFC_REMOTE_DEV_HANDLE hRemoteDev;
    DWORD NumberOfEntries;
    _Field_size_(NumberOfEntries) NFC_LLCP_SERVICE_NAME_ENTRY ServiceNameEntries[ANYSIZE_ARRAY];
} NFC_LLCP_SERVICE_DISCOVER_REQUEST, *PNFC_LLCP_SERVICE_DISCOVER_REQUEST;

typedef struct _NFC_LLCP_SERVICE_DISCOVER_SAP {
    DWORD NumberOfEntries;
    _Field_size_(NumberOfEntries) BYTE SAPEntries[ANYSIZE_ARRAY];
} NFC_LLCP_SERVICE_DISCOVER_SAP, *PNFC_LLCP_SERVICE_DISCOVER_SAP;

#define NFC_LLCP_SERVICE_DISCOVER_SAP_HEADER offsetof(NFC_LLCP_SERVICE_DISCOVER_SAP, SAPEntries)

typedef enum _NFC_LLCP_SOCKET_TYPE {
    ConnectionOriented,
    Connectionless,
} NFC_LLCP_SOCKET_TYPE, *PNFC_LLCP_SOCKET_TYPE;

typedef enum _NFC_LLCP_LINK_STATUS {
    LinkActivated,
    LinkDeactivated
} NFC_LLCP_LINK_STATUS, *PNFC_LLCP_LINK_STATUS;

typedef HANDLE NFC_LLCP_SOCKET_HANDLE, *PNFC_LLCP_SOCKET_HANDLE;

typedef struct _NFC_LLCP_SOCKET_INFO {
    NFC_LLCP_SOCKET_TYPE eSocketType;
    NFC_LLCP_SOCKET_OPTION sSocketOption;
} NFC_LLCP_SOCKET_INFO, *PNFC_LLCP_SOCKET_INFO;

typedef struct _NFC_LLCP_SOCKET_SERVICE_INFO {
    NFC_LLCP_SOCKET_HANDLE hSocket;
    BYTE bSAP;
    NFC_LLCP_SERVICE_NAME_ENTRY sServiceName;
} NFC_LLCP_SOCKET_SERVICE_INFO, *PNFC_LLCP_SOCKET_SERVICE_INFO;

typedef struct _NFC_LLCP_SOCKET_PAYLOAD {
    NFC_LLCP_SOCKET_HANDLE hSocket;
    BYTE bSAP;
    NFC_DATA_BUFFER sPayload;
} NFC_LLCP_SOCKET_PAYLOAD, *PNFC_LLCP_SOCKET_PAYLOAD;

typedef struct _NFC_LLCP_SOCKET_ACCEPT_INFO {
    NFC_LLCP_SOCKET_HANDLE hSocket;
    NFC_LLCP_SOCKET_OPTION sSocketOption;
} NFC_LLCP_SOCKET_ACCEPT_INFO, *PNFC_LLCP_SOCKET_ACCEPT_INFO;

typedef enum _NFC_LLCP_SOCKET_CONNECT_TYPE {
    NfcConnectBySap,
    NfcConnectByUri
} NFC_LLCP_SOCKET_CONNECT_TYPE, *PNFC_LLCP_SOCKET_CONNECT_TYPE;

typedef struct _NFC_LLCP_SOCKET_CONNECT_INFO {
    NFC_REMOTE_DEV_HANDLE hRemoteDev;
    NFC_LLCP_SOCKET_HANDLE hSocket;
    NFC_LLCP_SOCKET_CONNECT_TYPE eConnectType;
    union {
        BYTE bSAP;
        NFC_LLCP_SERVICE_NAME_ENTRY sServiceName;
    };
} NFC_LLCP_SOCKET_CONNECT_INFO, *PNFC_LLCP_SOCKET_CONNECT_INFO;

typedef struct _NFC_LLCP_SOCKET_CL_PAYLOAD {
    NFC_LLCP_SOCKET_HANDLE hSocket;
    BYTE bSAP;
    NFC_DATA_BUFFER sPayload;
} NFC_LLCP_SOCKET_CL_PAYLOAD, *PNFC_LLCP_SOCKET_CL_PAYLOAD;

typedef enum _NFC_LLCP_SOCKET_ERROR {
    NfcLlcpErrorDisconnected,
    NfcLlcpErrorFrameRejected,
    NfcLlcpErrorBusyCondition,
    NfcLlcpErrorNotBusyCondition,
} NFC_LLCP_SOCKET_ERROR, *PNFC_LLCP_SOCKET_ERROR;

typedef struct _NFC_LLCP_SOCKET_ERROR_INFO {
    NFC_LLCP_SOCKET_HANDLE hSocket;
    NFC_LLCP_SOCKET_ERROR eSocketError;
} NFC_LLCP_SOCKET_ERROR_INFO, *PNFC_LLCP_SOCKET_ERROR_INFO;

typedef enum _NFC_SNEP_SERVER_TYPE {
    DefaultSnepServer = 0,
    ExtendedSnepServer
} NFC_SNEP_SERVER_TYPE, *PNFC_SNEP_SERVER_TYPE;

typedef enum _NFC_SNEP_REQUEST_TYPE {
    SnepRequestGet = 0,
    SnepRequestPut,
} NFC_SNEP_REQUEST_TYPE, *PNFC_SNEP_REQUEST_TYPE;

#define MAX_SNEP_SERVER_NAME_SIZE 256

typedef HANDLE NFC_SNEP_SERVER_HANDLE, *PNFC_SNEP_SERVER_HANDLE;
typedef HANDLE NFC_SNEP_SERVER_CONNECTION_HANDLE, *PNFC_SNEP_SERVER_CONNECTION_HANDLE;
typedef NFC_LLCP_SOCKET_OPTION NFC_SNEP_SOCKET_OPTION, *PNFC_SNEP_SOCKET_OPTION;
typedef struct _NFC_LLCP_SERVICE_NAME_ENTRY NFC_SNEP_SERVICE_NAME, *PNFC_SNEP_SERVICE_NAME;

typedef struct _NFC_SNEP_SERVER_INFO {
    NFC_SNEP_SERVER_TYPE eServerType;
    NFC_SNEP_SOCKET_OPTION sSocketOption;
    USHORT usInboxSize;
    BYTE bSAP;
    NFC_SNEP_SERVICE_NAME sService;
} NFC_SNEP_SERVER_INFO, *PNFC_SNEP_SERVER_INFO;

typedef struct _NFC_SNEP_SERVER_ACCEPT_INFO {
    NFC_SNEP_SERVER_HANDLE hSnepServer;
    NFC_SNEP_SERVER_CONNECTION_HANDLE hConnection;
    NFC_SNEP_SOCKET_OPTION sSocketOption;   
} NFC_SNEP_SERVER_ACCEPT_INFO, *PNFC_SNEP_SERVER_ACCEPT_INFO;

typedef struct _NFC_SNEP_SERVER_REQUEST {
    NFC_SNEP_SERVER_HANDLE hSnepServer;
    NFC_SNEP_SERVER_CONNECTION_HANDLE hConnection;
    NFC_SNEP_REQUEST_TYPE eRequestType;
    NFC_DATA_BUFFER sRequestPayload;
} NFC_SNEP_SERVER_REQUEST, *PNFC_SNEP_SERVER_REQUEST;

typedef struct _NFC_SNEP_SERVER_RESPONSE_INFO {
    NFC_SNEP_SERVER_HANDLE hSnepServer;
    NFC_SNEP_SERVER_CONNECTION_HANDLE hConnection;
    DWORD dwResponseStatus;
    NFC_DATA_BUFFER sResponsePayload;
} NFC_SNEP_SERVER_RESPONSE_INFO, *PNFC_SNEP_SERVER_RESPONSE_INFO;

#define NFC_SNEP_SERVER_RESPONSE_HEADER offsetof(NFC_SNEP_SERVER_RESPONSE_INFO, sResponsePayload) + offsetof(NFC_DATA_BUFFER, pbBuffer)

typedef HANDLE NFC_SNEP_CLIENT_HANDLE, *PNFC_SNEP_CLIENT_HANDLE;
typedef NFC_DATA_BUFFER NFC_SNEP_CLIENT_DATA_BUFFER, *PNFC_SNEP_CLIENT_DATA_BUFFER;

typedef struct _NFC_SNEP_CLIENT_INFO {
    NFC_REMOTE_DEV_HANDLE hRemoteDev;
    NFC_SNEP_SERVER_TYPE eServerType;
    NFC_SNEP_SOCKET_OPTION sSocketOption;
    NFC_SNEP_SERVICE_NAME sService;
} NFC_SNEP_CLIENT_INFO, *PNFC_SNEP_CLIENT_INFO;

typedef struct _NFC_SNEP_CLIENT_PUT_INFO {
    NFC_SNEP_CLIENT_HANDLE hSnepClient;
    NFC_DATA_BUFFER sPutPayload;
} NFC_SNEP_CLIENT_PUT_INFO, *PNFC_SNEP_CLIENT_PUT_INFO;

#define  NFC_SNEP_CLIENT_PUT_HEADER offsetof(NFC_SNEP_CLIENT_PUT_INFO, sPutPayload) + offsetof(NFC_DATA_BUFFER, pbBuffer)

typedef struct _NFC_SNEP_CLIENT_GET_INFO {
    NFC_SNEP_CLIENT_HANDLE hSnepClient;
    NFC_DATA_BUFFER sGetPayload;
} NFC_SNEP_CLIENT_GET_INFO, *PNFC_SNEP_CLIENT_GET_INFO;

#define NFC_SNEP_CLIENT_GET_HEADER offsetof(NFC_SNEP_CLIENT_GET_INFO, sGetPayload) + offsetof(NFC_DATA_BUFFER, pbBuffer)

typedef SECURE_ELEMENT_TYPE NFC_SE_TYPE;
typedef HANDLE NFC_SE_HANDLE;
typedef SECURE_ELEMENT_EVENT_TYPE NFC_SE_EVENT_TYPE;

typedef enum _NFC_SE_EMULATION_MODE {
    EmulationDisabled = 0,
    EmulationEnabled = 1,
} NFC_SE_EMULATION_MODE, *PNFC_SE_EMULATION_MODE;

typedef struct _NFC_SE_INFO {
    NFC_SE_HANDLE hSecureElement;
    NFC_SE_TYPE eSecureElementType;
} NFC_SE_INFO, *PNFC_SE_INFO;

typedef struct _NFC_SE_LIST {
    DWORD NumberOfEndpoints;
    _Field_size_(NumberOfEndpoints)
    NFC_SE_INFO EndpointList[ANYSIZE_ARRAY];
} NFC_SE_LIST, *PNFC_SE_LIST;

typedef struct _NFC_SE_EMULATION_MODE_INFO {
    NFC_SE_HANDLE hSecureElement;
    NFC_SE_EMULATION_MODE eMode;
} NFC_SE_EMULATION_MODE_INFO, *PNFC_SE_EMULATION_MODE_INFO;

typedef SECURE_ELEMENT_ROUTING_TYPE NFC_SE_ROUTING_TABLE_TYPE;

typedef struct _NFC_SE_TECH_ROUTING_INFO {
    NFC_SE_HANDLE hSecureElement;
    BYTE bPowerState;
    BYTE eRfTechType;
} NFC_SE_TECH_ROUTING_INFO, *PNFC_SE_TECH_ROUTING_INFO;

typedef struct _NFC_SE_PROTO_ROUTING_INFO {
    NFC_SE_HANDLE hSecureElement;
    BYTE bPowerState;
    BYTE eRfProtocolType;
} NFC_SE_PROTO_ROUTING_INFO, *PNFC_SE_PROTO_ROUTING_INFO;

typedef struct _NFC_SE_AID_ROUTING_INFO {
    NFC_SE_HANDLE hSecureElement;
    BYTE bPowerState;
    _Field_range_(<= , ISO_7816_MAXIMUM_AID_LENGTH) DWORD cbAid;
    _Field_size_bytes_(cbAid) BYTE pbAid[ISO_7816_MAXIMUM_AID_LENGTH];
} NFC_SE_AID_ROUTING_INFO, *PNFC_SE_AID_ROUTING_INFO;

typedef struct _NFC_SE_ROUTING_TABLE_ENTRY {
    NFC_SE_ROUTING_TABLE_TYPE eRoutingType;
    union {
        NFC_SE_TECH_ROUTING_INFO TechRoutingInfo;
        NFC_SE_PROTO_ROUTING_INFO ProtoRoutingInfo;
        NFC_SE_AID_ROUTING_INFO AidRoutingInfo;
    };
} NFC_SE_ROUTING_TABLE_ENTRY, *PNFC_SE_ROUTING_TABLE_ENTRY;

typedef struct _NFC_SE_ROUTING_TABLE {
    DWORD NumberOfEntries;
    _Field_size_(NumberOfEntries)
    NFC_SE_ROUTING_TABLE_ENTRY TableEntries[ANYSIZE_ARRAY];
} NFC_SE_ROUTING_TABLE, *PNFC_SE_ROUTING_TABLE;

#define NFC_SE_ROUTING_TABLE_AND_ENTRIES(n) struct { \
    NFC_SE_ROUTING_TABLE Table; \
    NFC_SE_ROUTING_TABLE_ENTRY ExtraEntries[n-1]; \
}

typedef struct _NFC_SE_EVENT_INFO {
    NFC_SE_HANDLE hSecureElement;
    NFC_SE_EVENT_TYPE eEventType;
    DWORD cbEventData;
    _Field_size_bytes_(cbEventData)
    BYTE pbEventData[ANYSIZE_ARRAY];
} NFC_SE_EVENT_INFO, *PNFC_SE_EVENT_INFO;

#endif  // NTDDI_VERSION
