⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irdatransportsocket.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// 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 + -