[
    uuid(4b112204-0e19-11d3-b42b-0000f81feb9f),
    version(1.0),
    pointer_default(unique)
]

interface ssdpsrv
{

import   "wtypes.idl";

#define SSDP_SERVICE_PERSISTENT 0x00000001
cpp_quote("#define SSDP_SERVICE_PERSISTENT 0x00000001")

#define NUM_OF_HEADERS 19
cpp_quote("#define NUM_OF_HEADERS 19")

#define NUM_OF_METHODS 4
cpp_quote("#define NUM_OF_METHODS 4")

typedef enum _NOTIFY_TYPE {
    NOTIFY_ALIVE,
    NOTIFY_PROP_CHANGE
} NOTIFY_TYPE;

// make sure values matches array index to SsdpMethodStr in ssdp.idl
typedef enum _SSDP_METHOD {
    SSDP_NOTIFY = 0,
    SSDP_M_SEARCH = 1,
    GENA_SUBSCRIBE = 2,
    GENA_UNSUBSCRIBE =3,
    SSDP_INVALID = 4 // Must be qual to NUM_OF_METHODS
} SSDP_METHOD, *PSSDP_METHOD;

// make sure values matches array index to SsdpHeaderStr in ssdp.idl
typedef enum _SSDP_HEADER {
        SSDP_HOST = 0,
        SSDP_NT,
        SSDP_NTS,
        SSDP_ST,
        SSDP_MAN,
        SSDP_MX,
        SSDP_LOCATION,
        SSDP_AL,
        SSDP_USN,
        SSDP_CACHECONTROL,
        GENA_CALLBACK,
        GENA_TIMEOUT,
        GENA_SCOPE,
        GENA_SID,
        GENA_SEQ,
        CONTENT_LENGTH,
        CONTENT_TYPE,
        SSDP_SERVER,
        SSDP_EXT,
} SSDP_HEADER, *PSSDP_HEADER;

typedef [string] LPSTR MIDL_SZ;

typedef struct _SSDP_REQUEST {
    SSDP_METHOD Method;
    [string] LPSTR RequestUri;
    MIDL_SZ Headers[NUM_OF_HEADERS];
    [string] LPSTR ContentType;
    [string] LPSTR Content;
    GUID guidInterface;
} SSDP_REQUEST, *PSSDP_REQUEST;

typedef struct _SSDP_MESSAGE{
        // Message type
        [string] LPSTR szType;

        // location header
        [string] LPSTR szLocHeader;

        // alt location headers
        [string] LPSTR szAltHeaders;

        // unique service name
        [string] LPSTR szUSN;

        // Subscription identifier
        [string] LPSTR szSid;

        // sequence # for event notifications
        DWORD iSeq;

        // cache interval
        UINT iLifeTime;

        // optional content body
        [string] LPSTR szContent;

        // network interface on which received
        GUID guidInterface;

} SSDP_MESSAGE, *PSSDP_MESSAGE;

typedef struct _SSDP_REGISTER_INFO
{
    [string] LPSTR szSid;
             DWORD csecTimeout;
} SSDP_REGISTER_INFO;

typedef struct _MessageList {
        long size;
        [size_is(size)] SSDP_REQUEST *list;
} MessageList;

typedef enum _UPNP_PROPERTY_FLAG {
    UPF_NON_EVENTED = 0x00000001,
} UPNP_PROPERTY_FLAG;

typedef struct _UPNP_PROPERTY {
    // property name
    [string] LPSTR  szName;
             DWORD  dwFlags;
    // property value
    [string] LPSTR  szValue;

} UPNP_PROPERTY;

typedef struct _SUBSCRIBER_INFO {
    [string] LPSTR szDestUrl;
    FILETIME        ftTimeout;
    DWORD           csecTimeout;
    DWORD           iSeq;
    [string] LPSTR szSid;
} SUBSCRIBER_INFO;

typedef struct _EVTSRC_INFO {
    DWORD cSubs;
    [size_is(cSubs)] SUBSCRIBER_INFO *rgSubs;
} EVTSRC_INFO;

typedef [context_handle] void *PCONTEXT_HANDLE_TYPE;

typedef [context_handle] void *PSYNC_HANDLE_TYPE;

// Publication

int RegisterServiceRpc([out] PCONTEXT_HANDLE_TYPE *pphContext, [in] SSDP_MESSAGE svc, [in] DWORD flags);

int DeregisterServiceRpcByUSN([in, string] LPSTR szUSN, [in] BOOL fByebye);

int DeregisterServiceRpc([in, out] PCONTEXT_HANDLE_TYPE *pphContext, [in] BOOL fByebye);

// Cache

void UpdateCacheRpc([in, unique] PSSDP_REQUEST SsdpRequest);

int LookupCacheRpc([in, string] LPSTR szType, [out] MessageList **svcList);

void CleanupCacheRpc();

// Notification

// Initialize the synchronization handle
int InitializeSyncHandle([out] PSYNC_HANDLE_TYPE *pphContextSync);

void RemoveSyncHandle( [in, out] PSYNC_HANDLE_TYPE *pphContextSync);

int RegisterNotificationRpc(
    [out] PCONTEXT_HANDLE_TYPE *pphContext,
    [in] PSYNC_HANDLE_TYPE phContextSync,
    [in] NOTIFY_TYPE nt,
    [in, unique, string] LPSTR szType,
    [in, unique, string] LPSTR szEventUrl,
    [out] SSDP_REGISTER_INFO **ppinfo);

int GetNotificationRpc([in] PSYNC_HANDLE_TYPE pphContextSync, [out] MessageList **svcList);

int WakeupGetNotificationRpc([in] PSYNC_HANDLE_TYPE pphContextSync);

int DeregisterNotificationRpc([in, out] PCONTEXT_HANDLE_TYPE *pphContext, [in] BOOL fLast);

// Device Host ICS Support
void EnableDeviceHost();
void DisableDeviceHost();
void SetICSInterfaces([in] long nCount, [in, size_is(nCount)] GUID * arInterfaces);
void SetICSOff();

}