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

📄 bthid.cxx

📁 WinCE5.0部分核心源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:
        gpState->pCalls = pCall;
    else {
        SCall *pLast = gpState->pCalls;
        while (pLast->pNext)
            pLast = pLast->pNext;

        pLast->pNext = pCall;
    }

    IFDBG(DebugOut (DEBUG_LAYER_TRACE, L"BTH HID: Allocated call 0x%08x what = 0x%02x\n", pCall, fWhat));

    return pCall;
}

static void DeleteCall (SCall *pCall) {
    if (pCall == gpState->pCalls)
        gpState->pCalls = pCall->pNext;
    else {
        SCall *pParent = gpState->pCalls;
        while (pParent && (pParent->pNext != pCall))
            pParent = pParent->pNext;

        if (! pParent) {
            IFDBG(DebugOut (DEBUG_ERROR, L"BTH HID: call not in list in DeleteCall!\n"));

            return;
        }

        pParent->pNext = pCall->pNext;
    }

    CloseHandle (pCall->hEvent);

    svsutil_FreeFixed (pCall, gpState->pfmdCalls);
}

static SCall *VerifyCall (SCall *pCall) {
    SCall *p = gpState->pCalls;
    while (p && (p != pCall))
        p = p->pNext;

    return p;
}

static SCall *FindCall (unsigned int fOp) {
    SCall *p = gpState->pCalls;
    while (p && (p->fWhat != fOp))
        p = p->pNext;

    return p;
}

static SCall *FindCall (Link *pLink, unsigned int fOp) {
    SCall *p = gpState->pCalls;
    while (p && ((p->pLink != pLink) || (p->fWhat != fOp)))
        p = p->pNext;

    return p;
}

static HidDevice *VerifyDevice (HidDevice *pDev) {
    HidDevice *pD = gpState->pHIDs;
    while (pD && (pD != pDev))
        pD = pD->pNext;

    return pD;
}

static HidDevice *FindDevice (BD_ADDR *pba) {
    HidDevice *pD = gpState->pHIDs;
    while (pD && (pD->b != *pba))
        pD = pD->pNext;

    return pD;
}

static void DeleteDevice (HidDevice *pDev) {
    if (pDev == gpState->pHIDs)
        gpState->pHIDs = pDev->pNext;
    else {
        HidDevice *p = gpState->pHIDs;
        while (p->pNext != pDev)
            p = p->pNext;

        p->pNext = pDev->pNext;
    }

    delete pDev;

    // Signal Reconnect thread that a device has been deleted
    SetEvent(gpState->hReconnectEvent);
}
    
static Link *VerifyLink (Link *pLink) {
    Link *p = gpState->pLinks;
    while (p && (p != pLink))
        p = p->pNext;

    return p;
}

static Link *FindLink (BD_ADDR *pba) {
    Link *pL = gpState->pLinks;
    while (pL && (pL->b != *pba))
        pL = pL->pNext;

    return pL;
}
    
static Link *FindLink (BD_ADDR *pba, unsigned short psm) {
    Link *pL = gpState->pLinks;
    while (pL && ((pL->b != *pba) || (pL->psm != psm)))
        pL = pL->pNext;

    return pL;
}
    
static Link *FindLink (unsigned short cid) {
    Link *p = gpState->pLinks;
    while (p && (p->cid != cid))
        p = p->pNext;

    return p;
}

static void DisconnectDevice (HidDevice *pDev, BOOL fSendVCD) {    
    for ( ; ; ) {
        Link *pLink = FindLink (&pDev->b);
        if (! pLink)
            return;

        if (fSendVCD && pDev->fVirtualCable) {
            // Send VIRTUAL_CABLE_DISCONNECT
            BTHHIDPacket packet;
            packet.SetHeader(gbUnplugHeader);        
            (void) WritePacket (pDev, &packet, 0, NULL, BTH_PSM_CONTROL);
        }

        HIDCloseCID_Int (pLink->cid);
    }
}

static DWORD WINAPI HidReconnectThread (LPVOID lpArg) {
    IFDBG(DebugOut (DEBUG_LAYER_TRACE, L"BTH HID: Started reconnect thread\n"));

    if (! gpState)
        return ERROR_SERVICE_NOT_ACTIVE;

    gpState->Lock ();

    while (1) {
        DWORD dwTimeout;

        if (! gpState->fIsRunning) {
            break;
        }

        HANDLE h = gpState->hReconnectEvent;

        if (gpState->pHIDs)
            dwTimeout = HID_RECONNECT_INTERVAL;
        else 
            dwTimeout = INFINITE;

        gpState->AddRef ();
        gpState->Unlock ();

        DWORD dwWait = WaitForSingleObject(h, dwTimeout);

        gpState->Lock ();
        gpState->DelRef ();

        if (WAIT_TIMEOUT == dwWait) {
            HidDevice *pD = gpState->pHIDs;
            while (pD) {            
                if ((!pD->fHaveControl || !pD->fHaveInterrupt) && !pD->fReconnectInitiate && pD->fNormallyConnectable) {
                    int iRes = ERROR_SUCCESS;
                    
                    unsigned short cidControl = 0;
                    if (!pD->fHaveControl) {
                        gpState->AddRef ();
                        gpState->Unlock ();
                        iRes = HIDConnect_Int (&pD->b, BTH_PSM_CONTROL, &cidControl);
                        gpState->Lock ();
                        gpState->DelRef ();
                    }

                    if (iRes == ERROR_SUCCESS) {
                        unsigned short cidInterrupt = 0;
                        if (!pD->fHaveInterrupt) {
                            gpState->AddRef ();
                            gpState->Unlock ();
                            
                            iRes = HIDConnect_Int (&pD->b, BTH_PSM_INTERRUPT, &cidInterrupt);
                            
                            if (iRes != ERROR_SUCCESS) {
                                if (cidControl)
                                    HIDCloseCID_Int (cidControl);                            
                            }

                            gpState->Lock ();
                            gpState->DelRef ();
                        }
                    }
                }
                
                pD = pD->pNext;
            }
        }
        
        
    }    

    gpState->Unlock ();

    return ERROR_SUCCESS;
}

static DWORD WINAPI DeviceTimeout (LPVOID lpArg) {
    IFDBG(DebugOut (DEBUG_LAYER_TRACE, L"BTH HID: Timeout on hid device\n"));

    if (! gpState)
        return ERROR_SERVICE_NOT_ACTIVE;

    gpState->Lock ();

    if (! gpState->fIsRunning) {
        gpState->Unlock ();
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    HidDevice *pDev = VerifyDevice ((HidDevice *)lpArg);
    if (pDev && pDev->ckDeviceTimeout && (! FindLink (&pDev->b))) {
        DeleteDevice(pDev);
    }

    gpState->Unlock ();

    return ERROR_SUCCESS;
}

static DWORD WINAPI ConnectionTimeout (LPVOID lpArg) {
    IFDBG(DebugOut (DEBUG_LAYER_TRACE, L"BTH HID: Connection Timeout on hid device\n"));

    if (! gpState)
        return ERROR_SERVICE_NOT_ACTIVE;

    gpState->Lock ();

    if (! gpState->fIsRunning) {
        gpState->Unlock ();
        return ERROR_SERVICE_NOT_ACTIVE;
    }

    HidDevice *pDev = VerifyDevice ((HidDevice *)lpArg);
    if (pDev && pDev->ckConnectionTimeout && (! (pDev->fHaveControl && pDev->fHaveInterrupt))) {
        pDev->ckConnectionTimeout = 0;
        DisconnectDevice (pDev, TRUE);
    }

    gpState->Unlock ();

    return ERROR_SUCCESS;
}

static void DeleteLink (Link *pLink) {
    IFDBG(DebugOut (DEBUG_LAYER_TRACE, L"BTH HID: delete link for bd_addr %04x%08x cid 0x%04x\n", pLink->b.NAP, pLink->b.SAP, pLink->cid));

    if (pLink == gpState->pLinks)
        gpState->pLinks = pLink->pNext;
    else {
        Link *pParent = gpState->pLinks;
        while (pParent && (pParent->pNext != pLink))
            pParent = pParent->pNext;

        if (! pParent) {
            IFDBG(DebugOut (DEBUG_ERROR, L"BTH HID: link to be deleted not in list\n"));
            return;
        }

        pParent->pNext = pLink->pNext;
    }

    SCall *pC = gpState->pCalls;
    while (pC) {
        if (pC->pLink == pLink) {
            if (pC->fAutoClean) {
                DeleteCall (pC);
                pC = gpState->pCalls;
                continue;
            } else if (! pC->fComplete) {
                pC->pLink = NULL;
                pC->fComplete = TRUE;
                pC->iResult = ERROR_CONNECTION_UNAVAIL;
                SetEvent (pC->hEvent);
            } else {
                pC->pLink = NULL;
                if (pC->iResult == ERROR_SUCCESS)
                    pC->iResult = ERROR_CONNECTION_UNAVAIL;

            }
        }

        pC = pC->pNext;
    }

    HidDevice *pDev = FindDevice (&pLink->b);

    if (pDev) {
        if (pLink->psm == BTH_PSM_CONTROL)
            pDev->fHaveControl = FALSE;
        else
            pDev->fHaveInterrupt = FALSE;

        if (! pDev->ckDeviceTimeout)
            pDev->ckDeviceTimeout = gpState->pSchedule->ScheduleEvent (DeviceTimeout, pDev, BTH_PARSER_TIMEOUT);
    }

    svsutil_FreeFixed (pLink, gpState->pfmdLinks);
}

static void HID_BufferFree (BD_BUFFER *pBuf) {
    if (! pBuf->fMustCopy)
        g_funcFree (pBuf, g_pvFreeData);
}

static void HID_BufferFreeArray (BD_BUFFER **ppArray, int carray) {
    for (int i = 0 ; i < carray ; ++i)
        HID_BufferFree (ppArray[i]);
}

static BD_BUFFER *HID_BufferAlloc (int cSize) {
    SVSUTIL_ASSERT (cSize > 0);

    BD_BUFFER *pRes = (BD_BUFFER *)g_funcAlloc (cSize + sizeof (BD_BUFFER), g_pvAllocData);
    pRes->cSize = cSize;

    pRes->cEnd = pRes->cSize;
    pRes->cStart = 0;

    pRes->fMustCopy = FALSE;
    pRes->pFree = HID_BufferFree;
    pRes->pBuffer = (unsigned char *)(pRes + 1);

    return pRes;
}

static BD_BUFFER *HID_BufferCopy (BD_BUFFER *pBuffer) {
    BD_BUFFER *pRes = HID_BufferAlloc (pBuffer->cSize);
    pRes->cSize = pBuffer->cSize;
    pRes->cStart = pBuffer->cStart;
    pRes->cEnd = pBuffer->cEnd;
    pRes->fMustCopy = FALSE;
    pRes->pFree = HID_BufferFree;
    pRes->pBuffer = (unsigned char *)(pRes + 1);

    memcpy (pRes->pBuffer, pBuffer->pBuffer, pRes->cSize);

    return pRes;
}

static DWORD WINAPI StackDown (LPVOID lpVoid) {        // Attention - must increment ref count before calling this!
    IFDBG(DebugOut (DEBUG_LAYER_TRACE, L"BTH HID: Stack Down\n"));

    if (! gpState)
        return ERROR_SERVICE_NOT_ACTIVE;

    gpState->Lock ();
    gpState->DelRef ();

    if ((! gpState->fIsRunning) || (! gpState->fConnected)) {
        gpState->Unlock ();

        return ERROR_SERVICE_NOT_ACTIVE;
    }

    gpState->fConnected = FALSE;

    Link *pLink = gpState->pLinks;

    while (gpState->pLinks)
        DeleteLink (gpState->pLinks);

    SCall *pC = gpState->pCalls;
    while (pC) {
        if (pC->fAutoClean) {
            DeleteCall (pC);
            pC = gpState->pCalls;
            continue;
        } else if (! pC->fComplete) {
            pC->pLink = NULL;
            pC->fComplete = TRUE;
            pC->iResult = ERROR_CONNECTION_UNAVAIL;
            SetEvent (pC->hEvent);
        } else {
            pC->pLink = NULL;
            if (pC->iResult == ERROR_SUCCESS)
                pC->iResult = ERROR_CONNECTION_UNAVAIL;
        }
        pC = pC->pNext;
    }

    gpState->Unlock ();
    return ERROR_SUCCESS;
}

static DWORD WINAPI StackUp (LPVOID lpVoid) {    // Attention - must increment ref count before calling this!
    IFDBG(DebugOut (DEBUG_LAYER_TRACE, L"BTH HID: Stack Up\n"));

    if (! gpState)
        return ERROR_SERVICE_NOT_ACTIVE;

    gpState->Lock ();
    gpState->DelRef ();

    if ((! gpState->fIsRunning) || gpState->fConnected) {
        gpState->Unlock ();

        return ERROR_SERVICE_NOT_ACTIVE;
    }

    gpState->fConnected = TRUE;
    gpState->Unlock ();

    return ERROR_SUCCESS;
}

static HidDevice *MakeNewDevice (BD_ADDR *pba, int fIncoming) {
    IFDBG(DebugOut (DEBUG_LAYER_TRACE, L"BTH HID: MakeNewDevice %04x%08x\n", pba->NAP, pba->SAP));

    HidDevice *pDev = new HidDevice (pba);

    if (! pDev)
        return NULL;

    if (! pDev->FillPersistentParameters (fIncoming)) {
        IFDBG(DebugOut (DEBUG_WARN, L"BTH HID: MakeNewDevice %04x%08x fails to retrieve pairing information\n", pba->NAP, pba->SAP));
        delete pDev;
        return NULL;
    }

    pDev->pNext     = gpState->pHIDs;
    gpState->pHIDs  = pDev;
    pDev->fIncoming = fIncoming;

    // Signal Reconnect thread that we added a device.

⌨️ 快捷键说明

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