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

📄 irlmp.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        {
            RemoveEntryList(&pDevice->Linkage);
            IRDA_FREE_MEM(pDevice);
        }
    }    

    // remove IrdaLinkCb from List

    RemoveEntryList(&pIrlmpCb->pIrdaLinkCb->Linkage);

    ASSERT(IsListEmpty(&pIrlmpCb->LsapCbList));
    
    NdisReleaseSpinLock(&SpinLock);

    IasDelAttribute(pIrlmpCb->hAttribDeviceName);
    IasDelAttribute(pIrlmpCb->hAttribIrlmpSupport);

    CTEFreeMem(pIrlmpCb);
    
/*        
    // Cleanup registered LSAP
    while (!IsListEmpty(&RegisteredLsaps))
    {
        pPtr = RemoveHeadList(&RegisteredLsaps);
        IRDA_FREE_MEM(pPtr);
    }
    // And the device list
    while (!IsListEmpty(&DeviceList))
    {
        pPtr = RemoveHeadList(&DeviceList);
        IRDA_FREE_MEM(pPtr);
    }    

    // And IAS entries
    for (pObject = (IAS_OBJECT *) IasObjects.Flink;
         (LIST_ENTRY *) pObject != &IasObjects;
         pObject = pNextObject)    
    {
        DEBUGMSG(DBG_IRLMP, (TEXT("IRLMP: Deleting object %s\n"),
                              pObject->pClassName));
        
        // Get the next cuz this ones being deleted
        pNextObject = (IAS_OBJECT *) pObject->Linkage.Flink;

        IasDeleteObject(pObject->pClassName);
    }
 */   
}

/*****************************************************************************
*
*   @func   UINT | IrlmpCloseLink | Shuts down IRDA stack
*
*   @rdesc  SUCCESS or error
*
*/
VOID
IrlmpCloseLink(PIRDA_LINK_CB pIrdaLinkCb)
{
    DEBUGMSG(1, (TEXT("IRLMP: CloseLink request\n")));

    IrdaEventSchedule(&EvIrlmpCloseLink, pIrdaLinkCb);

    return;
}
/*****************************************************************************
*
*   @func   UINT | IrlmpRegisterLSAPProtocol | Bag to let IRLMP know if
*                                               a connect ind is using TTP
*   @rdesc  SUCCESS or error
*
*   @parm   int | LSAP | LSAP being registered
*   @parm   BOOLEAN | UseTtp | 
*/
VOID
RegisterLsapProtocol(int Lsap, BOOLEAN UseTtp)
{
    PIRLMP_REGISTERED_LSAP     pRegLsap;
    
    NdisAcquireSpinLock(&SpinLock);

    for (pRegLsap = (PIRLMP_REGISTERED_LSAP) RegisteredLsaps.Flink;
         (LIST_ENTRY *) pRegLsap != &RegisteredLsaps;
         pRegLsap = (PIRLMP_REGISTERED_LSAP) pRegLsap->Linkage.Flink)
    {
        if (pRegLsap->Lsap == Lsap)
        {
            pRegLsap->UseTtp = UseTtp;
            goto done;
        }
    }

    if (IRDA_ALLOC_MEM(pRegLsap, sizeof(IRLMP_REGISTERED_LSAP), 
                       MT_IRLMP_REGLSAP) == NULL)
    {
        ASSERT(0);
        goto done;
    }
    pRegLsap->Lsap = Lsap;
    pRegLsap->UseTtp = UseTtp;
    InsertTailList(&RegisteredLsaps, &pRegLsap->Linkage);    

done:

    NdisReleaseSpinLock(&SpinLock);

    DEBUGMSG(DBG_IRLMP, (TEXT("IRLMP: LSAP %x registered, %s\n"), Lsap,
                          UseTtp ? TEXT("use TTP") : TEXT("no TTP")));
}

VOID
DeregisterLsapProtocol(int Lsap)
{
    PIRLMP_REGISTERED_LSAP     pRegLsap;

    NdisAcquireSpinLock(&SpinLock);

    for (pRegLsap = (PIRLMP_REGISTERED_LSAP) RegisteredLsaps.Flink;
         (LIST_ENTRY *) pRegLsap != &RegisteredLsaps;
         pRegLsap = (PIRLMP_REGISTERED_LSAP) pRegLsap->Linkage.Flink)
    {
        if (pRegLsap->Lsap == Lsap)
        {
            DEBUGMSG(DBG_IRLMP, (TEXT("IRLMP: LSAP %x deregistered\n"),
                        Lsap));

            RemoveEntryList(&pRegLsap->Linkage);

            IRDA_FREE_MEM(pRegLsap);
            break;
        }
    }

    NdisReleaseSpinLock(&SpinLock);
}

/*****************************************************************************
*
*   @func   UINT | DeleteLsap | Delete an Lsap control context and
*
*   @rdesc  pointer to Lsap context or 0 on error
*
*   @parm   void | pLsapCb | pointer to an Lsap control block
*/
void
DeleteLsap(IRLMP_LSAP_CB *pLsapCb)
{
    VALIDLSAP(pLsapCb);

    ASSERT(pLsapCb->State == LSAP_DISCONNECTED);

    ASSERT(IsListEmpty(&pLsapCb->SegTxMsgList));

    ASSERT(IsListEmpty(&pLsapCb->TxMsgList));

    LOCK_LINK(pLsapCb->pIrlmpCb->pIrdaLinkCb);

#ifdef DBG 
    pLsapCb->Sig = 0xdaeddead;
#endif 

    RemoveEntryList(&pLsapCb->Linkage);

    UNLOCK_LINK(pLsapCb->pIrlmpCb->pIrdaLinkCb);
    REFDEL(&pLsapCb->pIrlmpCb->pIrdaLinkCb->RefCnt, 'PASL');
    
    IrdaTimerStop(&pLsapCb->ResponseTimer);
    
    DEBUGMSG(DBG_IRLMP, (TEXT("IRLMP: Deleting LsapCb:%X (%d,%d)\n"),
             pLsapCb, pLsapCb->LocalLsapSel, pLsapCb->RemoteLsapSel));

    memset(pLsapCb, 0, sizeof(IRLMP_LSAP_CB));

    IRDA_FREE_MEM(pLsapCb);
}

/*****************************************************************************
*
*   @func   UINT | CreateLsap | Create an LSAP control context and
*/
UINT
CreateLsap(PIRLMP_LINK_CB pIrlmpCb, IRLMP_LSAP_CB **ppLsapCb)
{
    IRLMP_LSAP_CB * pLsapCb;
    *ppLsapCb = NULL;

    IRDA_ALLOC_MEM(pLsapCb, sizeof(IRLMP_LSAP_CB), MT_IRLMP_LSAP_CB);

    if (pLsapCb == NULL)
    {
        return IRLMP_ALLOC_FAILED;
    }

    *ppLsapCb = pLsapCb;

    memset(pLsapCb, 0, sizeof(IRLMP_LSAP_CB));

    pLsapCb->pIrlmpCb = pIrlmpCb;
    pLsapCb->State = LSAP_CREATED;
    pLsapCb->UserDataLen = 0;

    InitializeListHead(&pLsapCb->TxMsgList);
    InitializeListHead(&pLsapCb->SegTxMsgList);

    ReferenceInit(&pLsapCb->RefCnt, *ppLsapCb, DeleteLsap);
    REFADD(&pLsapCb->RefCnt, ' TS1');

#if DBG
    pLsapCb->ResponseTimer.pName = "ResponseTimer";
    pLsapCb->Sig = LSAPSIG;
#endif
    IrdaTimerInitialize(&pLsapCb->ResponseTimer,
                        LsapResponseTimerExp,
                        LSAP_RESPONSE_TIMEOUT,
                        pLsapCb,
                        pIrlmpCb->pIrdaLinkCb);

    // Insert into list in the link control block
    NdisAcquireSpinLock(&SpinLock);

    InsertTailList(&pIrlmpCb->LsapCbList, &pLsapCb->Linkage);

    NdisReleaseSpinLock(&SpinLock);
    
    REFADD(&pIrlmpCb->pIrdaLinkCb->RefCnt, 'PASL');

    DEBUGMSG(DBG_IRLMP, (TEXT("IRLMP: New LsapCb:%X\n"),
             pLsapCb));

    return SUCCESS;
}

void
CleanupLsap(IRLMP_LSAP_CB *pLsapCb)
{
    IRDA_MSG *pMsg, *pNextMsg, *pSegParentMsg;
    
    VALIDLSAP(pLsapCb);

    DEBUGMSG(DBG_IRLMP, (TEXT("IRLMP: CleanupLsap:%X\n"), pLsapCb));

    if (pLsapCb->State == LSAP_DISCONNECTED)
    {
        ASSERT(0);
        return;
    }

    if (pLsapCb == pLsapCb->pIrlmpCb->pExclLsapCb)
    {
        pLsapCb->pIrlmpCb->pExclLsapCb = NULL;
    }
    
    pLsapCb->State = LSAP_DISCONNECTED;

    // Clean up the segmented tx msg list
    while (!IsListEmpty(&pLsapCb->SegTxMsgList))
    {
        pMsg = (IRDA_MSG *) RemoveHeadList(&pLsapCb->SegTxMsgList);
        
        // Decrement the segment counter contained in the parent data request
        pSegParentMsg = pMsg->DataContext;
        pSegParentMsg->IRDA_MSG_SegCount -= 1;
        // IRLMP owns these
        FreeIrdaBuf(IrdaMsgPool, pMsg);
    }

    // return any outstanding data requests (unless there are outstanding segments)
    for (pMsg = (IRDA_MSG *) pLsapCb->TxMsgList.Flink;
         (LIST_ENTRY *) pMsg != &(pLsapCb->TxMsgList);
         pMsg = pNextMsg)
    {
        pNextMsg = (IRDA_MSG *) pMsg->Linkage.Flink;

        if (pMsg->IRDA_MSG_SegCount == 0)
        {
            RemoveEntryList(&pMsg->Linkage);
            pMsg->Prim = IRLMP_DATA_CONF;
            pMsg->IRDA_MSG_DataStatus = IRLMP_DATA_REQUEST_FAILED;
            TdiUp(pLsapCb->pTdiContext, pMsg);
        }
    }
    REFDEL(&pLsapCb->RefCnt, ' TS1');
}

/*****************************************************************************
*
*   @func   void | TearDownConnections | Tears down and cleans up connections
*
*   @parm   IRLMP_DISC_REASONE| DiscReason | The reason connections are being
*                                            torn down. Passed to IRLMP clients
*                                            in IRLMP_DISCONNECT_IND
*/
void
TearDownConnections(PIRLMP_LINK_CB pIrlmpCb, IRLMP_DISC_REASON DiscReason)
{
    IRLMP_LSAP_CB       *pLsapCb, *pLsapCbNext;
    IRDA_MSG            IMsg;
    
    pIrlmpCb->pExclLsapCb = NULL; 
   
    DEBUGMSG(DBG_IRLMP, (TEXT("IRLMP: Tearing down connections\r\n")));
    
    // Clean up each LSAP
    for (pLsapCb = (IRLMP_LSAP_CB *) pIrlmpCb->LsapCbList.Flink;
         (LIST_ENTRY *) pLsapCb != &pIrlmpCb->LsapCbList;
         pLsapCb = pLsapCbNext)
    {
        pLsapCbNext = (IRLMP_LSAP_CB *) pLsapCb->Linkage.Flink;

        DEBUGMSG(DBG_IRLMP, (TEXT("IRLMP: Teardown LsapCb:%X\n"), pLsapCb));
        VALIDLSAP(pLsapCb);

        if (pLsapCb->LocalLsapSel == IAS_LSAP_SEL)
        {
            IasServerDisconnectReq(pLsapCb);
            continue;
        }
        
        if (pLsapCb->LocalLsapSel == IAS_LOCAL_LSAP_SEL && 
            pLsapCb->RemoteLsapSel == IAS_LSAP_SEL)
        {
            IasClientDisconnectReq(pLsapCb, DiscReason);
        }
        else
        {
            IrdaTimerStop(&pLsapCb->ResponseTimer);

            if (pLsapCb->State != LSAP_DISCONNECTED)
            {
                DEBUGMSG(DBG_IRLMP, 
                         (TEXT("IRLMP: Sending IRLMP Disconnect Ind\r\n")));

                // Now tell client this LSAP is history
        
                IMsg.Prim = IRLMP_DISCONNECT_IND;
                IMsg.IRDA_MSG_DiscReason = DiscReason;
                IMsg.IRDA_MSG_pDiscData = NULL;
                IMsg.IRDA_MSG_DiscDataLen = 0;

                TdiUp(pLsapCb->pTdiContext, &IMsg);
                CleanupLsap(pLsapCb);
            }
        }
    }
}

/*****************************************************************************
*
*   @func   UINT | IrlmpDown | Message from Upper layer to LMP
*
*   @rdesc  SUCCESS or an error code
*
*   @parm   void * | void_pLsapCb | void pointer to an LSAP_CB. Can be NULL
*   @parm   IRDA_MSG * | pMsg | Pointer to an IRDA Message
*/
UINT
IrlmpDown(void *void_pLsapCb, IRDA_MSG *pMsg)
{
    UINT rc = SUCCESS;

    IRLMP_LSAP_CB *pLsapCb =
            (IRLMP_LSAP_CB *) void_pLsapCb;

    if (pLsapCb != NULL && pLsapCb->State == LSAP_DISCONNECTED)
    {
        return IRLMP_INVALID_LSAP_CB;
    }

    if (pLsapCb)
    {
#ifdef DEBUG
        if (pLsapCb->Sig != LSAPSIG) {
            DEBUGMSG(DBG_ERROR, (L"IRLMP:IrlmpDown IRLMP_LSAP_SIG==0x%x vs. 0x%x\n", pLsapCb->Sig, LSAPSIG));
            ASSERT(0);
            return IRLMP_INVALID_LSAP_CB;
        }
#endif
        VALIDLSAP(pLsapCb);

        REFADD(&pLsapCb->RefCnt, 'NWOD');
        if (pLsapCb->pIrlmpCb == NULL) {
            REFDEL(&pLsapCb->RefCnt, 'NWOD');
            DEBUGMSG(DBG_ERROR, (L"IRLMP:IrlmpDown pIrlmpCb==NULL\n"));
            return IRLMP_INVALID_LSAP_CB;
        }

        LOCK_LINK(pLsapCb->pIrlmpCb->pIrdaLinkCb);
    } else {
        //
        // These requests cannot have a NULL LsapCb
        //
        switch (pMsg->Prim) {
        case IRLMP_CONNECT_RESP:
        case IRLMP_DATA_REQ:
        case IRLMP_ACCESSMODE_REQ:
        case IRLMP_MORECREDIT_REQ:
            return IRLMP_INVALID_LSAP_CB;
        }
    }
    
    switch (pMsg->Prim)
    {
      case IRLMP_DISCOVERY_REQ:
        IrlmpDiscoveryReq(pMsg);
        break;

      case IRLMP_CONNECT_REQ:
        rc = IrlmpConnectReq(pMsg);
        break;

⌨️ 快捷键说明

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