|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 2000.
//
// File: S E A R C H . C P P
//
// Contents: SSDP Search Response
//
// Notes:
//
// Author: mbend 10 Nov 2000
//
//----------------------------------------------------------------------------
#include <pch.h>
#pragma hdrstop
#include "search.h"
#include "ssdpfunc.h"
#include "ncbase.h"
#include "announce.h"
// response ahead 1 second
#define RESPONSE_AHEAD 0.5
CSsdpSearchResponse::CSsdpSearchResponse() : m_timer(*this), m_szResponse(NULL) { }
CSsdpSearchResponse::~CSsdpSearchResponse() { delete [] m_szResponse; m_szResponse = NULL; }
HRESULT CSsdpSearchResponse::HrCreate(SOCKET * pSockLocal, SOCKADDR_IN * pSockRemote, char * szResponse, long nMX) { HRESULT hr = S_OK;
CSsdpSearchResponse * pResponse = new CSsdpSearchResponse(); if(!pResponse) { delete [] szResponse; hr = E_OUTOFMEMORY; } if(SUCCEEDED(hr)) { hr = pResponse->HrInitialize(pSockLocal, pSockRemote, szResponse, nMX); if(SUCCEEDED(hr)) { long nDelay = pResponse->CalculateDelay();
TraceTag(ttidSsdpSearchResp, "CSsdpSearchResponse::HrCreate - " "timer started for %d", nDelay);
hr = pResponse->m_timer.HrSetTimer(nDelay); } else { delete [] szResponse; }
if(FAILED(hr)) { delete pResponse; } }
TraceHr(ttidSsdpSearchResp, FAL, hr, FALSE, "CSsdpSearchResponse::HrCreate"); return hr; }
HRESULT CSsdpSearchResponse::HrInitialize( SOCKET * pSockLocal, SOCKADDR_IN * pSockRemote, char * szResponse, long nMX) { HRESULT hr = S_OK;
m_sockLocal = *pSockLocal; m_sockRemote = *pSockRemote; m_nMX = nMX; m_szResponse = szResponse;
TraceHr(ttidSsdpSearchResp, FAL, hr, FALSE, "CSsdpSearchResponse::HrInitialize"); return hr; }
long CSsdpSearchResponse::CalculateDelay() { // Range = (ResponseEntry->MX - 0);
float nRange = (float)m_nMX; long nDelay;
if (nRange > RESPONSE_AHEAD) { nRange -= RESPONSE_AHEAD; nDelay = (long)((rand() * nRange / RAND_MAX) * 1000.0); } else { nDelay = 0; } return nDelay; }
void CSsdpSearchResponse::TimerFired() { HRESULT hr = S_OK;
if (FReferenceSocket(m_sockLocal)) { SocketSendWithReplacement(m_szResponse, &m_sockLocal, &m_sockRemote); UnreferenceSocket(m_sockLocal); }
TraceTag(ttidSsdpSearchResp, "Sending search response: %s", m_szResponse);
// This will queue ourselves to autodelete
hr = HrStart(TRUE, FALSE);
TraceHr(ttidSsdpSearchResp, FAL, hr, FALSE, "CSsdpSearchResponse::TimerFired"); }
DWORD CSsdpSearchResponse::DwRun() { // Must lock and queue work item to free ourselves or timer stuff will AV
CLock lock(m_critSec); m_timer.HrDelete(INVALID_HANDLE_VALUE); return 0; }
|