📄 irdatransportsocket.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "common.h"
#include "IRDATransportSocket.h"
#include "ObexTransportConnection.h"
#include "ObexIRDATransport.h"
#include "ObexStrings.h"
/******globals******/
extern CRITICAL_SECTION g_TransportSocketCS;
static IRDA_CONNECTION_HOLDER *g_pConnectionList = 0;
UINT g_uiIRDAMaxRetries;
CIRDATransportSocket::CIRDATransportSocket():
_refCount(1)
{
DEBUGMSG(OBEX_TRANSPORTSOCKET_ZONE,(L"CIRDATransportSocket::CIRDATransportSocket()\n"));
//initilize the socket libs
WSADATA wsd;
WSAStartup (MAKEWORD(2,2), &wsd);
}
CIRDATransportSocket::~CIRDATransportSocket()
{
DEBUGMSG(OBEX_TRANSPORTSOCKET_ZONE,(L"CIRDATransportSocket::~CIRDATransportSocket()\n"));
Close();
//clean up winsock
WSACleanup();
}
HRESULT STDMETHODCALLTYPE
CIRDATransportSocket::Close()
{
DEBUGMSG(OBEX_TRANSPORTSOCKET_ZONE,(L"CIRDATransportSocket::Close()\n"));
CCritSection TransportCS(&g_TransportSocketCS);
TransportCS.Lock();
HRESULT hRes = E_FAIL;
IRDA_CONNECTION_HOLDER *pTemp = 0;
IRDA_CONNECTION_HOLDER *pPrev = 0;
if(g_pConnectionList)
{
pTemp = g_pConnectionList->pNext;
pPrev = g_pConnectionList;
}
else
{
return S_OK;
}
if(pPrev)
{
//its okay that we dont free up the memory pointed to here!
// actually we CANT because we dont own a reference to it
// to prevent a loop of refcounts
if(memcmp(pPrev->DeviceID, connectionID, 4) == 0)
{
IRDA_CONNECTION_HOLDER *pDel = pPrev;
g_pConnectionList = pPrev->pNext;
delete pDel;
pTemp = 0;
hRes = S_OK;
}
}
while(pTemp && pTemp->pNext)
{
//its okay that we dont free up the memory pointed to here!
// actually we CANT because we dont own a reference to it
// to prevent a loop of refcounts
if(memcmp(pTemp->pNext->DeviceID, connectionID, 4) == 0)
{
IRDA_CONNECTION_HOLDER *pDel = pTemp;
pPrev->pNext = pTemp->pNext;
delete pDel;
hRes = S_OK;
break;
}
pPrev = pTemp;
pTemp = pTemp->pNext;
}
return hRes;
}
HRESULT STDMETHODCALLTYPE
CIRDATransportSocket::Listen(LPTRANSPORTCONNECTION *ppConnection)
{
DEBUGMSG(OBEX_TRANSPORTSOCKET_ZONE,(L"CIRDATransportSocket::Listen()\n"));
return E_NOTIMPL;
}
int
CIRDATransportSocket::reenum_connect(IObexAbortTransportEnumeration *pAbortEnum, SOCKET s,const SOCKADDR_IRDA *name, int namelen, char *pDeviceName)
{
SVSUTIL_ASSERT(name);
int returnValue = SOCKET_ERROR;
//retry connecting (seems that the the server will quit listening if the
// user delays for about 6 seconds)... do this by enuming
// the IRDA devices looking for ours
for ( UINT uiReTries=0; uiReTries < g_uiIRDAMaxRetries; uiReTries ++)
{
// This is to ensure that the server is ready to receive.
SOCKET pollSock = socket(AF_IRDA, SOCK_STREAM, 0);
if(INVALID_SOCKET != pollSock)
{
//memory to hold possible servers
unsigned char DevListBuff[sizeof(DEVICELIST) -
sizeof(IRDA_DEVICE_INFO) +
(sizeof(IRDA_DEVICE_INFO) * DEVICE_LIST_LEN)];
int DevListLen = sizeof(DevListBuff);
PDEVICELIST pDevList = (PDEVICELIST) DevListBuff;
pDevList->numDevice = 0;
for(UINT uiTries=0; uiTries < g_uiIRDAMaxRetries; uiTries ++)
{
int optReturn = getsockopt(pollSock, SOL_IRLMP, IRLMP_ENUMDEVICES,(char *) pDevList, &DevListLen);
// if we are told to abort, do so
if(NULL != pAbortEnum) {
BOOL fAbort;
pAbortEnum->IsAborting(&fAbort);
if(TRUE == fAbort) {
closesocket(pollSock);
return SOCKET_ERROR;
}
}
//if there is an error see if it is an INPROGRESS one
// if so, try again (up to MAX_IRDA_TRIES) if not
// something happened that is more serious so bail out
// of the function with SOCKET_ERROR
if(SOCKET_ERROR == optReturn)
{
int errorCode = WSAGetLastError();
if(WSAEINPROGRESS == errorCode)
{
Sleep(500);
continue;
}
else
{
closesocket(pollSock);
return SOCKET_ERROR;
}
}
if(pDevList->numDevice != 0)
break;
}
closesocket(pollSock);
//if we have devices, check to see if we have OUR device
// if not, bail out cause our device walked off
if ( DevListLen != 0 )
{
for(UINT i=0; i<pDevList->numDevice; i++)
{
SVSUTIL_ASSERT(sizeof(pDevList->Device[i].irdaDeviceName) >= strlen(pDeviceName));
if(0 == strcmp(pDevList->Device[i].irdaDeviceName, pDeviceName))
{
DEBUGMSG(OBEX_TRANSPORTSOCKET_ZONE, (L"[OBEX-IRDA] Attempting reconnect\n"));
//patch up the device ID
SVSUTIL_ASSERT(4 == sizeof(pDevList->Device[i].irdaDeviceID));
memcpy((char *)name->irdaDeviceID, (char *)pDevList->Device[i].irdaDeviceID, 4);
//reconnect
returnValue = connect(s, (const struct sockaddr *) name, namelen);
if(SOCKET_ERROR != returnValue)
{
DEBUGMSG(OBEX_TRANSPORTSOCKET_ZONE, (L"[OBEX] Got a connection!\n"));
return returnValue;
}
else
{
int err = WSAGetLastError();
DEBUGMSG(OBEX_TRANSPORTSOCKET_ZONE, (L"[OBEX] Error(%x) connecting... maybe the device isnt in range? trying again.\n",err));
}
}
}
}
}
//an error getting an IRDA socket occured... print an error, but dont
// do anything (we will retry)
else
{
DEBUGMSG(OBEX_TRANSPORTSOCKET_ZONE, (L"[OBEX] Error getting an IRDA socket, trying again\n"));
}
}
return returnValue;
}
HRESULT STDMETHODCALLTYPE
CIRDATransportSocket::Connect(LPPROPERTYBAG2 pDeviceProps,DWORD dwCapability, LPTRANSPORTCONNECTION * ppConnection)
{
DEBUGMSG(OBEX_TRANSPORTSOCKET_ZONE,(L"CIRDATransportSocket::Connect()\n"));
CCritSection TransportCS(&g_TransportSocketCS);
TransportCS.Lock();
PREFAST_ASSERT(pDeviceProps);
*ppConnection = NULL;
//set the default error to return
HRESULT hRet = E_FAIL;
//variables
SOCKET sMySock = INVALID_SOCKET;
IRDA_CONNECTION_HOLDER *pTemp = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -