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

📄 irlap.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        
        // Update the device discovery info. IrLMP has already updated
        // NickName & NickNameLen.
        // Build the discovery info    
        Val = Hints;
        DscvInfoLen = 0;
        for (i = 0, Mask = 0xFF000000; i < 4; i++, Mask >>= 8)
        {
            if (Mask & Val || DscvInfoLen > 0)
            {
                DscvInfoBuf[DscvInfoLen++] = (UCHAR)
                    ((Mask & Val) >> (8 * (3-i)));
            }
        }
        DscvInfoBuf[DscvInfoLen++] = CharSet;
        RtlCopyMemory(DscvInfoBuf+DscvInfoLen, NickName, NickNameLen);
        DscvInfoLen += NickNameLen;    

        DscvInfoLen = DscvInfoLen > IRLAP_DSCV_INFO_LEN ?
            IRLAP_DSCV_INFO_LEN : DscvInfoLen;
        
        CTEMemCopy(pIrlapCb->LocalDevice.DscvInfo, DscvInfoBuf, DscvInfoLen);
    
        pIrlapCb->LocalDevice.DscvInfoLen = DscvInfoLen;
    
        IMsg.IRDA_MSG_Op = MAC_ACQUIRE_RESOURCES;
    }
    else
    {
        IMsg.IRDA_MSG_Op = MAC_RELEASE_RESOURCES;
    }
    IMsg.IRDA_MSG_pMacConfig = pMsg->IRDA_MSG_pLinkConfig;

    IrmacDown(pMsg->IRDA_MSG_pLinkContext, &IMsg);

    return (IMsg.IRDA_MSG_MacConfigStatus);
}
/*****************************************************************************
*
*   ProcessDiscoveryReq - Process Discovery request from LMP
*
*/
UINT
ProcessDiscoveryReq(PIRLAP_CB pIrlapCb,
                    PIRDA_MSG pMsg)
{
    IRDA_MSG    IMsg;
    
    switch (pIrlapCb->State)
    {
      case NDM:
        if (pMsg->IRDA_MSG_SenseMedia == TRUE)
        {
            IMsg.Prim = MAC_CONTROL_REQ;
            IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
            IMsg.IRDA_MSG_SenseTime = IRLAP_MEDIA_SENSE_TIME;            
            IrmacDown(pIrlapCb->pIrdaLinkCb, &IMsg);
            pIrlapCb->State = DSCV_MEDIA_SENSE;
            IRLAP_LOG_ACTION((pIrlapCb,TEXT("MAC_CONTROL_REQ (mediasense)")));
        }
        else
        {
            pIrlapCb->SlotCnt = 0;
            pIrlapCb->GenNewAddr = FALSE;

            FreeDevList(&pIrlapCb->DevList);

            SendDscvXIDCmd(pIrlapCb);

            IMsg.Prim = MAC_CONTROL_REQ;
            IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
            IMsg.IRDA_MSG_SenseTime = DiscoverTimeout;
            IRLAP_LOG_ACTION((pIrlapCb,TEXT("MAC_CONTROL_REQ (dscvsense)")));
            IrmacDown(pIrlapCb->pIrdaLinkCb, &IMsg);

            pIrlapCb->State = DSCV_QUERY;
        }
        break;

      case DSCV_REPLY:
        return IRLAP_REMOTE_DISCOVERY_IN_PROGRESS_ERR;

      case SNRM_RECEIVED:
        return IRLAP_REMOTE_CONNECTION_IN_PROGRESS_ERR;

      case P_CLOSE:
        pIrlapCb->DscvAfterClose = TRUE;
        break;
        
      default:
        ASSERT(0);
        return IRLAP_BAD_STATE;
    }
    return SUCCESS;
}
/*****************************************************************************
*
*   ProcessDisconnectReq - Process disconnect request from LMP
*
*/
VOID
ProcessDisconnectReq(PIRLAP_CB pIrlapCb)
{
    ReturnRxTxWinMsgs(pIrlapCb);

    switch (pIrlapCb->State)
    {
      case NDM:
        IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
        break;

      case SNRM_SENT:
        IrlapTimerStop(TEXT("ProcessDisconnectResp: SNRM_SENT"), pIrlapCb, &pIrlapCb->FinalTimer);
      case DSCV_MEDIA_SENSE:
      case DSCV_QUERY:
      case DSCV_REPLY:
      case CONN_MEDIA_SENSE:
        pIrlapCb->State = NDM;
        break;

      case BACKOFF_WAIT:
        IrlapTimerStop(TEXT("ProcessDisconnectResp: BACKOFF_WAIT"), pIrlapCb, &pIrlapCb->BackoffTimer);
        pIrlapCb->State = NDM;
        break;

      case SNRM_RECEIVED:
        pIrlapCb->ConnAddr = pIrlapCb->SNRMConnAddr;
        SendDM(pIrlapCb);
        pIrlapCb->ConnAddr = IRLAP_BROADCAST_CONN_ADDR;
        pIrlapCb->State = NDM;
        break;

      case P_XMIT:
        pIrlapCb->LocalDiscReq = TRUE;
        IrlapTimerStop(TEXT("ProcessDisconnectResp: P_XMIT"), pIrlapCb, &pIrlapCb->PollTimer);
        SendDISC(pIrlapCb);
        IrlapTimerStart(TEXT("ProcessDisconnectResp: P_XMIT"), pIrlapCb, &pIrlapCb->FinalTimer);
        pIrlapCb->RetryCnt = 0;
        pIrlapCb->State = P_CLOSE;
        break;

      case P_RECV:
        pIrlapCb->LocalDiscReq = TRUE;
        pIrlapCb->State = P_DISCONNECT_PEND;
        break;

      case S_NRM:
        pIrlapCb->LocalDiscReq = TRUE;
        pIrlapCb->State = S_DISCONNECT_PEND;
        break;

      default:
        ASSERT(0);
        // return IRLAP_BAD_STATE;
    }
}
/*****************************************************************************
*
*   ProcessDataReq - Process data request from LMP
*
*/
UINT
ProcessDataAndUDataReq(PIRLAP_CB pIrlapCb,
                       PIRDA_MSG pMsg)
{
    BOOLEAN LinkTurned;
    int  DataSize = (pMsg->IRDA_MSG_pHdrWrite - pMsg->IRDA_MSG_pHdrRead) +
                    (pMsg->IRDA_MSG_pWrite - pMsg->IRDA_MSG_pRead);
    UINT rc;

    if (DataSize > pIrlapCb->RemoteDataSize)
    {
        rc = IRLAP_BAD_DATA_REQUEST;
        goto pdaudr_fail;
    }

    switch (pIrlapCb->State)
    {
      case P_XMIT:
        // Enque message, then drain the message list. If the link
        // was turned in the process of draining messages stop Poll Timer,
        // start Final Timer and enter P_RECV. Otherwise we'll stay in P_XMIT
        // waiting for more data requests from LMP or Poll Timer expiration
        EnqueMsgList(&pIrlapCb->TxMsgList, pMsg, -1);

        XmitTxMsgList(pIrlapCb, FALSE, &LinkTurned);

        if (LinkTurned)
        {
           IrlapTimerStop(TEXT("ProcessDataAndUDataReq: P_XMIT"), pIrlapCb, &pIrlapCb->PollTimer);
           IrlapTimerStart(TEXT("ProcessDataAndUDataReq: P_XMIT"), pIrlapCb, &pIrlapCb->FinalTimer);
           pIrlapCb->State = P_RECV;
        }
        return SUCCESS;

      case P_DISCONNECT_PEND: //For pending disc states, take the message.
      case S_DISCONNECT_PEND: // They will be returned when the link discs
      case P_RECV:
      case S_NRM:
        // Que the message for later transmission

        IRLAP_LOG_ACTION((pIrlapCb, TEXT("Queueing request")));

        EnqueMsgList(&pIrlapCb->TxMsgList, pMsg, -1);
        
        return SUCCESS;

      default:
        if (pMsg->Prim == IRLAP_DATA_REQ)
        {
            ASSERT(0);
            rc = IRLAP_BAD_STATE;
            goto pdaudr_fail;
        }
        else
        {
            if (pIrlapCb->State == NDM)
            {
                SendUIFrame(pIrlapCb, pMsg);
            }
            else
            {
                IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
                rc = SUCCESS;
                goto pdaudr_fail;
            }
        }
    }
    return SUCCESS;

pdaudr_fail:
    //
    // Check if the msg should be freed
    //
    if ((NULL == pMsg->IRDA_MSG_pOwner) && (pMsg->IRDA_MSG_SegFlags & SEG_LOCAL)) {
        FreeIrdaBuf(IrdaMsgPool, pMsg);
    }
    return rc;

}
/*****************************************************************************
*
*/
VOID
XmitTxMsgList(PIRLAP_CB pIrlapCb, BOOLEAN AlwaysTurnLink,
              BOOLEAN *pLinkTurned)
{
    IRDA_MSG    *pMsg;
    UINT        LinkTurned;

    LinkTurned = FALSE;

    // If the remote is not busy send data
    // If we need to clear the local busy condition, don't send data send RR
    if (!pIrlapCb->RemoteBusy && !pIrlapCb->ClrLocalBusy)
    {
        while (!LinkTurned &&
               (DequeMsgList(&pIrlapCb->TxMsgList, &pMsg) == SUCCESS))
        {
            pIrlapCb->FastPollCount = IRLAP_FAST_POLL_COUNT;
            pIrlapCb->PollTimer.Timeout = IRLAP_FAST_POLL_TIME > 
                pIrlapCb->RemoteMaxTAT ? pIrlapCb->RemoteMaxTAT : IRLAP_FAST_POLL_TIME;

            if (pMsg->Prim == IRLAP_DATA_REQ)
            {
                // Insert message into transmit window
                pIrlapCb->TxWin.pMsg[pIrlapCb->Vs] = pMsg;

                pMsg->IRDA_MSG_SendRefCnt = 1;

                // Send message. If full window or there are no
                // more data requests, send with PF Set (turns link).
                if ((pIrlapCb->Vs == (pIrlapCb->TxWin.Start +
                      pIrlapCb->RemoteWinSize-1) % IRLAP_MOD) ||
                      (0 == pIrlapCb->TxMsgList.Len /*AlwaysTurnLink*/))
                {
                    SendIFrame(pIrlapCb,
                               pMsg,
                               pIrlapCb->Vs,
                               IRLAP_PFBIT_SET);
                    LinkTurned = TRUE;
                }
                else
                {
                    SendIFrame(pIrlapCb,
                               pMsg,
                               pIrlapCb->Vs,
                               IRLAP_PFBIT_CLEAR);
                }
                pIrlapCb->Vs = (pIrlapCb->Vs + 1) % IRLAP_MOD;
            }
            else // IRLAP_UDATA_REQUEST
            {
                // For now, always turn link
                SendUIFrame(pIrlapCb, pMsg);
                pMsg->Prim = IRLAP_UDATA_CONF;
                pMsg->IRDA_MSG_DataStatus = IRLAP_DATA_REQUEST_COMPLETED;
                IrlmpUp(pIrlapCb->pIrdaLinkCb, pMsg);
                LinkTurned = TRUE;
            }
        }
        pIrlapCb->TxWin.End = pIrlapCb->Vs;
    }

    if ((AlwaysTurnLink && !LinkTurned) || pIrlapCb->ClrLocalBusy)
    {
        SendRR_RNR(pIrlapCb);
        LinkTurned = TRUE;
        if (pIrlapCb->ClrLocalBusy)
        {
            pIrlapCb->ClrLocalBusy = FALSE;
        }
    }

    if (pLinkTurned != NULL)
    {
        *pLinkTurned = LinkTurned;
    }
}

VOID
GotoPCloseState(PIRLAP_CB pIrlapCb)
{
    IRDA_MSG IMsg;
    
    if (!pIrlapCb->LocalDiscReq)
    {
        IMsg.Prim = IRLAP_DISCONNECT_IND;
        IMsg.IRDA_MSG_DiscStatus = IRLAP_REMOTE_INITIATED;
        IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
    }

    ReturnRxTxWinMsgs(pIrlapCb);
    pIrlapCb->State = P_CLOSE;
}

VOID
GotoNDMThenDscvOrConn(PIRLAP_CB pIrlapCb)
{
    IRDA_MSG IMsg;
    
    if (pIrlapCb->ConnAfterClose)
    {
        pIrlapCb->ConnAfterClose = FALSE;
        IMsg.Prim = MAC_CONTROL_REQ;
        IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
        IMsg.IRDA_MSG_SenseTime = IRLAP_MEDIA_SENSE_TIME;
        
        IrmacDown(pIrlapCb->pIrdaLinkCb, &IMsg);
        pIrlapCb->State = CONN_MEDIA_SENSE;
        IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ (media sense)")));
        return;
    }

    if (pIrlapCb->DscvAfterClose)
    {
        pIrlapCb->DscvAfterClose = FALSE;
        IMsg.Prim = MAC_CONTROL_REQ;
        IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
        IMsg.IRDA_MSG_SenseTime = IRLAP_MEDIA_SENSE_TIME;        
        IrmacDown(pIrlapCb->pIrdaLinkCb, &IMsg);
        pIrlapCb->State = DSCV_MEDIA_SENSE;
        IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ (media sense)")));
        return;
    }
    pIrlapCb->State = NDM;
    return;
}

/*****************************************************************************
*
*   ProcessMACControlConf - Process a control confirm from MAC
*
*/
VOID
ProcessMACControlConf(PIRLAP_CB pIrlapCb, PIRDA_MSG pMsg)
{
    IRDA_MSG    IMsg;
    
    if (pMsg->IRDA_MSG_Op != MAC_MEDIA_SENSE)
    {
        ASSERT(0);
        return; //IRLAP_BAD_OP;
    }

    switch (pIrlapCb->State)
    {
      case DSCV_MEDIA_SENSE:
        switch (pMsg->IRDA_MSG_OpStatus)
        {
          case MAC_MEDIA_CLEAR:
               
            //IndicateLinkStatus(pIrlapCb, LINK_STATUS_DISCOVERING);

            pIrlapCb->SlotCnt = 0;
            pIrlapCb->GenNewAddr = FALSE;

            FreeDevList(&pIrlapCb->DevList);

            SendDscvXIDCmd(pIrlapCb);

            IMsg.Prim = MAC_CONTROL_REQ;
            IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
            IMsg.IRDA_MSG_SenseTime = DiscoverTimeout;

⌨️ 快捷键说明

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