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

📄 obmain.cxx

📁 Windows CE 6.0 Server 源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:

        memset (pServ, 0, sizeof(*pServ));

        //if the serviceID = 0
        //load up the client dll by the serviceid
        if (! pServ->Load (iLen, (unsigned char *)serviceid)) {
            pServ->Unload ();
            svsutil_FreeFixed (pServ, pfmdServers);
            IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x fails with SERVICEUNAVAIL (no server)\n", pConn->uiCurrentTransaction));
            SendTrivialResponse (pConn, OBEX_STAT_SERVICEUNAVAIL | OBEX_OP_ISFINAL);
            SVSUTIL_ASSERT (! IsLocked ());
            return;
        }

        pServ->pNext = pservList;
        pservList = pServ;
    }

    SVSUTIL_ASSERT (pServ);
    if (pServ->CanUseConnection (pConn))
    {       
        //NOTE:  the transaction ID *MUST* be set by DispatchCall
        //  in this one special case (where CID is INVALID!)
        pServ->DispatchCall (OBEX_INVALID_CID, pConn, &p);
    }    
    else {
        IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::ServiceRequest: packet 0x%08x fails with SERVICEUNAVAIL (server won't serve)\n", pConn->uiCurrentTransaction));
        SendTrivialResponse (pConn, OBEX_STAT_SERVICEUNAVAIL | OBEX_OP_ISFINAL);
    }

    IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] -GlobalData::ServiceRequest\n"));
    SVSUTIL_ASSERT (! IsLocked ());
}

DWORD WINAPI GlobalData::Compact (LPVOID pVoid) {
    IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"GlobalData::Compact - entered\n"));

    if (! gpState)
        return 0;

    gpState->Lock ();
    if (gpState->fState != RUNNING) {
        gpState->Unlock ();
        return 0;
    }

    //
    //    Compaction pass on all structures.
    //
    //    Close long inactive connections.
    int tickNow = GetTickCount ();

    if (gpState->uiOBEX_CONNECTION_TIMEOUT) {
        for ( ; ; ) {
            int fResume = FALSE;
            Connection *pConn = gpState->pconnList;
            while (pConn) {
                if ((! pConn->uiCurrentTransaction) &&
                        (tickNow - pConn->tickLastActive > (int)gpState->uiOBEX_CONNECTION_TIMEOUT)) {
                    IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Compact: retiring connection %d\n", pConn->s));

                    gpState->CloseConnection (pConn);
                    if (gpState->fState != RUNNING) {
                        gpState->Unlock ();
                        return 0;
                    }

                    fResume = TRUE;
                    break;
                }
                pConn = pConn->pNext;
            }

            if (! fResume)
                break;
        }
    }

    for ( ; ; ) {
        int fResume = FALSE;
        Server *pParent = NULL;
        Server *pServ = gpState->pservList;
        while (pServ) {
            if ((! pServ->iCallRef) &&
                    (tickNow - pServ->tickLastActive > (int)gpState->uiOBEX_SERVER_TIMEOUT)) {
                Association *pA = gpState->passocList;
                while (pA) {
                    if (pA->pServer == pServ)
                        break;
                    pA = pA->pNext;
                }
                if (! pA) {
                    IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Compact: retiring server %s\n", pServ->szName));

                    if (pParent)
                        pParent->pNext = pServ->pNext;
                    else
                        gpState->pservList = gpState->pservList->pNext;

                    pServ->pNext = NULL;
                    pServ->Unload ();

                    if (gpState->fState != RUNNING) {
                        gpState->Unlock ();
                        return 0;
                    }

                    svsutil_FreeFixed (pServ, gpState->pfmdServers);

                    fResume = TRUE;
                    break;
                }
            }
            pParent = pServ;
            pServ = pServ->pNext;
        }

        if (! fResume)
            break;
    }

    if ((! gpState->pconnList) && (! gpState->pservList)) {
        gpState->fMaintain = FALSE;    // just exit... or
        IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Compact - exited\n"));
    } else {                            // schedule forward...
        gpState->pThreads->ScheduleEvent (Compact, NULL, gpState->uiOBEX_MAINT_PERIOD);
        IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Compact - rescheduled\n"));
    }
    gpState->Unlock();

    return 0;
}

int GlobalData::SendTrivialResponse (Connection *pConn, int iResponse) {
    IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PACKETS, L"[OBEX] GlobalData::SendTrivialResponse - response 0x%02x\n", iResponse));

    SVSUTIL_ASSERT (pConn->uiCurrentTransaction);
    SVSUTIL_ASSERT (pConn->pBuffer);
    SVSUTIL_ASSERT (pConn->cBufSize >= 3);
    SVSUTIL_ASSERT (pConn->cFilled == pConn->cBufSize);

    SOCKET s = pConn->s;

    pConn->uiCurrentTransaction = 0;    // We are responding...
    pConn->cBufSize = pConn->cFilled = 0;
    obex_Free (pConn->pBuffer);
    pConn->pBuffer = NULL;

    gpState->Unlock ();

    char x[3];
    x[0] = (char)iResponse;        // Response
    x[1] = 0;                    // Length
    x[2] = 3;

    IFDBG(svslog_DumpBuff (VERBOSE_OUTPUT_PACKETS, (unsigned char *)x, 3));

    return send(s, x, 3, 0);
}

HRESULT GlobalData::CloseConnection (Connection *pConn) {
    IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] GlobalData::CloseConnection\n"));
    SVSUTIL_ASSERT (gpState->IsLocked ());

    //    Free resources
    closesocket (pConn->s);
    pConn->s = INVALID_SOCKET;

    if (pConn->pBuffer)
        obex_Free (pConn->pBuffer);

    pConn->pBuffer = NULL;
    pConn->cFilled = 0;
    pConn->cBufSize = 0;

    pConn->cPeekFilled = 0;

    //
    //        Take it out of the list
    //
    Connection *pParent = NULL;
    Connection *pRun = pconnList;
    while (pRun) {
        if (pConn == pRun)
            break;

        pParent = pRun;
        pRun = pRun->pNext;
    }

    if (! pRun) {
        SVSUTIL_ASSERT (0);
        return E_FAIL;
    }

    if (! pParent)
        pconnList = pconnList->pNext;
    else
        pParent->pNext = pRun->pNext;

    //    Clean up associations, notify servers
    for ( ; ; ) {
        Association *pAssocParent = NULL;
        Association *pA = passocList;
        while (pA) {
            if (pA->pConn == pConn) {
                IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] GlobalData::CloseConnection : closing association to %s\n", pA->pServer->szName));

                if (! pAssocParent)
                    passocList = passocList->pNext;
                else
                    pAssocParent->pNext = pA->pNext;

                Server *pServ = pA->pServer;
                unsigned int uiCId = pA->uiConnectionId;
                svsutil_FreeFixed (pA, pfmdAssociations);
                pA->uiTransactionId = pConn->uiCurrentTransaction;             
                pServ->DispatchCall (uiCId, NULL, NULL);
            
                SVSUTIL_ASSERT (! gpState->IsLocked());
                gpState->Lock ();               
                break;
            }

            pAssocParent = pA;
            pA = pA->pNext;
        }

        if (! pA)
            break;
    }

    svsutil_FreeFixed (pConn, gpState->pfmdConnections);
    IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_PROTOCOL, L"[OBEX] -GlobalData::CloseConnection\n"));
    return S_OK;
}

void GlobalData::SetMaintain(void) {
    if (! fMaintain) {
        IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::SetMaintain :: scheduling maintenance\n"));

        fMaintain = TRUE;
        pThreads->ScheduleEvent (Compact, NULL, uiOBEX_MAINT_PERIOD);
    }
}


#define SOCKET_CREATION_ATTEMPTS 20


#ifndef SDK_BUILD

//
//    AddressFamily
//
int AddressFamily::Start (int af, int iPort) {
    IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Start :: TCP/IP\n"));

    SVSUTIL_ASSERT (gpState->IsLocked ());

    SOCKET sl;
    ADDRINFO aiHints, *aiAddrInfo, *AI;
    char portBuffer[21];
    int i;
    
    _itoa(iPort, portBuffer, 10);
    
    memset(&aiHints, 0, sizeof(aiHints));
    aiHints.ai_family = af;
    aiHints.ai_socktype = SOCK_STREAM;
    aiHints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;

    BOOL fGotValidBinding = FALSE;
    
    //use getaddrinfo for fetching addrinfo
    if(0 != getaddrinfo(NULL,portBuffer,&aiHints, &aiAddrInfo))
    {
        IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] AddressFamily::error with getaddrinfo! (%d)\n", WSAGetLastError()));
        return FALSE;  
    }
   
    for (i = 0, AI = aiAddrInfo; AI != NULL; AI = AI->ai_next, i++) 
    {
        // Highly unlikely, but check anyway.
        if (i == FD_SETSIZE) {
            IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] Too many addresses given\n"));
            break;
        }

        // Make sure we're not beyond the OBEX_MAXPORTS
        if(cSockets >= OBEX_MAXPORTS) {
            ASSERT(FALSE);
            IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] Too many address Families\n"));
            break;
        }
            
        // we only support PF_INET and PF_INET6 here
        if ((AI->ai_family != PF_INET) && (AI->ai_family != PF_INET6))
            continue;
            
        // Open a socket with the correct address family for this address.        
        sl = aSocket[cSockets] = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
        if (sl == INVALID_SOCKET){
            IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] Too many addresses given\n"));   
            continue;
        }     
        
        //bind the socket
        if (bind (sl, AI->ai_addr, AI->ai_addrlen)) 
        {
            IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] AddressFamily::Start: bind failed (ecode=%d)!\n", WSAGetLastError()));
            closesocket (sl);
            continue;
        }

        if (listen (sl, 5)) {
            IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] AddressFamily::Start::Listen failed (ecode=%d)!\n", WSAGetLastError()));
            closesocket (sl);
            continue;
        }
        
        if (! hThread)
           hThread = CreateThread (NULL, 0, ThreadListen, (void *)this, 0, NULL);

        if (! hThread) 
        {
            IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_ERRORS, L"[OBEX] AddressFamily::Start failed to create thread (error=0x%08x (%d))\n", GetLastError(), GetLastError ()));
            closesocket (sl);
            continue;
        }
        
        SVSUTIL_ASSERT (cSockets < OBEX_MAXPORTS);     
        addFam[cSockets] = AI->ai_family;
        PREFAST_SUPPRESS(394,  "this is checked at the beginning of the for loop to make sure < OBEX_MAXPORT")        
        ++cSockets;
         
        fGotValidBinding = TRUE;
        IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_INIT, L"[OBEX] AddressFamily::Start - successfully started af %d port %d\n", af, iPort));   
    }
    
    freeaddrinfo(aiAddrInfo);
    return fGotValidBinding;
}

#endif


int AddressFamily::Start (int af) {
    IFDBG(svslog_DebugOut (VERBOSE_OUTPUT_MAINTAIN, L"[OBEX] GlobalData::Start :: Bluetooth\n"));

    SVSUTIL_ASSERT (gpState->IsLocked ());

    SVSUTIL_ASSERT (cSockets < OBEX_MAXPORTS);
    
    addFam[cSockets] = af;


    SOCKET sl;
    for(int i=0; i < SOCKET_CREATION_ATTEMPTS; i++) {
        sl = aSocket[cSockets] = socket (af, SOCK_STREAM, BTHPROTO_RFCOMM);

        if(sl != INVALID_SOCKET)
            break;
        else {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -