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

📄 irlap.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    IrdaTimerInitialize(&pIrlapCb->QueryTimer,
                        QueryTimerExp,
                        (IRLAP_MAX_SLOTS + 4) * SlotTimeout*2,
                        pIrlapCb,
                        pIrdaLinkCb);

    IrdaTimerInitialize(&pIrlapCb->WDogTimer,
                        WDogTimerExp,
                        3000,
                        pIrlapCb,
                        pIrdaLinkCb);

    IrdaTimerInitialize(&pIrlapCb->BackoffTimer,
                        BackoffTimerExp,
                        0,
                        pIrlapCb,
                        pIrdaLinkCb);

    // Initialize Link
    IMsg.Prim               = MAC_CONTROL_REQ;
    IMsg.IRDA_MSG_Op        = MAC_INITIALIZE_LINK;
    IMsg.IRDA_MSG_Baud      = IRLAP_CONTENTION_BAUD;
    IMsg.IRDA_MSG_NumBOFs   = IRLAP_CONTENTION_BOFS;
    IMsg.IRDA_MSG_DataSize  = IRLAP_CONTENTION_DATA_SIZE;
    IMsg.IRDA_MSG_MinTat    = 0;
    
    IrmacDown(pIrlapCb->pIrdaLinkCb, &IMsg);

    *Status = STATUS_SUCCESS;
}

/*****************************************************************************
*/
VOID
IrlapCloseLink(PIRDA_LINK_CB pIrdaLinkCb)
{
    IRDA_MSG    IMsg;
    PIRLAP_CB   pIrlapCb = (PIRLAP_CB) pIrdaLinkCb->IrlapContext;

    IRLAP_LOG_START((pIrlapCb, TEXT("IRLAP: CloseLink")));

    ReturnRxTxWinMsgs(pIrlapCb);    

    IrlapTimerStop(TEXT("IrlapCloseLink"), pIrlapCb, &pIrlapCb->SlotTimer);
    IrlapTimerStop(TEXT("IrlapCloseLink"), pIrlapCb, &pIrlapCb->QueryTimer);
    IrlapTimerStop(TEXT("IrlapCloseLink"), pIrlapCb, &pIrlapCb->PollTimer);
    IrlapTimerStop(TEXT("IrlapCloseLink"), pIrlapCb, &pIrlapCb->FinalTimer);
    IrlapTimerStop(TEXT("IrlapCloseLink"), pIrlapCb, &pIrlapCb->WDogTimer);
    IrlapTimerStop(TEXT("IrlapCloseLink"), pIrlapCb, &pIrlapCb->BackoffTimer);
    
    IRLAP_LOG_COMPLETE(pIrlapCb);
    
    IMsg.Prim = MAC_CONTROL_REQ;
    IMsg.IRDA_MSG_Op = MAC_CLOSE_LINK;
    IrmacDown(pIrlapCb->pIrdaLinkCb, &IMsg);    

    return;
}

/*****************************************************************************
*
* Delete memory associated with an Irlap instance
*
*/
VOID
IrlapDeleteInstance(PVOID Context)
{
    PIRLAP_CB   pIrlapCb = (PIRLAP_CB) Context;
        
#if DBG
    int     i;
    for (i = 0; i < IRLAP_MOD; i++)
    {
        ASSERT(pIrlapCb->TxWin.pMsg[i] == NULL);
        ASSERT(pIrlapCb->RxWin.pMsg[i] == NULL);
    }    
#endif

    FreeDevList(&pIrlapCb->DevList);
    
    IRDA_FREE_MEM(pIrlapCb);    
}

/*****************************************************************************
*
* InitializeState - resets link control block
*
*/
VOID
InitializeState(PIRLAP_CB pIrlapCb,
                IRLAP_STN_TYPE StationType)
{
//    IRDA_MSG    *pMsg;
//    int         i;

    pIrlapCb->StationType = StationType;

    if (StationType == PRIMARY)
        pIrlapCb->CRBit = IRLAP_CMD;
    else
        pIrlapCb->CRBit = IRLAP_RSP;

    pIrlapCb->RemoteBusy        = FALSE;
    pIrlapCb->LocalBusy         = FALSE;
    pIrlapCb->ClrLocalBusy      = FALSE;
    pIrlapCb->NoResponse        = FALSE;
    pIrlapCb->LocalDiscReq      = FALSE;
    pIrlapCb->ConnAfterClose    = FALSE;
    pIrlapCb->DscvAfterClose    = FALSE;
    pIrlapCb->GenNewAddr        = FALSE;
    pIrlapCb->StatusSent        = FALSE;    
    pIrlapCb->Vs                = 0;
    pIrlapCb->Vr                = 0;
    pIrlapCb->WDogExpCnt        = 0;    
    pIrlapCb->FastPollCount     = 0;

    FreeDevList(&pIrlapCb->DevList);

    memset(&pIrlapCb->RemoteQos, 0, sizeof(IRDA_QOS_PARMS));
    memset(&pIrlapCb->NegotiatedQos, 0, sizeof(IRDA_QOS_PARMS));

    // Return msgs on tx list and in tx/rx windows
    ReturnRxTxWinMsgs(pIrlapCb);
}

/*****************************************************************************
*
*  IrlapDown - Entry point into IRLAP for LMP
*
*/
UINT
IrlapDown(PVOID     Context,
          PIRDA_MSG pMsg)
{
    PIRLAP_CB   pIrlapCb    = (PIRLAP_CB) Context;
    UINT        rc          = SUCCESS;

    IRLAP_LOG_START((pIrlapCb, IRDA_PrimStr[pMsg->Prim]));

    switch (pMsg->Prim)
    {
      case IRLAP_DISCOVERY_REQ:
        rc = ProcessDiscoveryReq(pIrlapCb, pMsg);
        break;

      case IRLAP_CONNECT_REQ:
        rc = ProcessConnectReq(pIrlapCb, pMsg);
        break;

      case IRLAP_CONNECT_RESP:
        ProcessConnectResp(pIrlapCb, pMsg);
        break;

      case IRLAP_DISCONNECT_REQ:
        ProcessDisconnectReq(pIrlapCb);
        break;

      case IRLAP_DATA_REQ:
      case IRLAP_UDATA_REQ:
        rc = ProcessDataAndUDataReq(pIrlapCb, pMsg);
        break;

      case IRLAP_FLOWON_REQ:
        if (pIrlapCb->LocalBusy)
        {
            IRLAP_LOG_ACTION((pIrlapCb,TEXT("Local busy condition cleared")));
            pIrlapCb->LocalBusy = FALSE;
            pIrlapCb->ClrLocalBusy = TRUE;
        }
        break;

      case IRLAP_LINKCONTROL_REQ:
        rc = ProcessLinkControlReq(pIrlapCb, pMsg);
        break;

      default:
        ASSERT(0);
        rc = IRLAP_BAD_PRIM;

    }

    IRLAP_LOG_COMPLETE(pIrlapCb);

    return rc;
}
/*****************************************************************************
*
*  IrlapUp - Entry point into IRLAP for MAC
*
*/
VOID
IrlapUp(PVOID Context, PIRDA_MSG pMsg)
{
    BOOLEAN     FreeMsg     = TRUE;
    PIRLAP_CB   pIrlapCb    = (PIRLAP_CB) Context;


    switch (pMsg->Prim)
    {
      case MAC_DATA_IND:
//        IRLAP_LOG_START((pIrlapCb, TEXT("MAC_DATA_IND: %s"), FrameToStr(pMsg)));
        IRLAP_LOG_START((pIrlapCb, TEXT("MAC_DATA_IND")));

        ProcessMACDataInd(pIrlapCb, pMsg, &FreeMsg);

        if (FreeMsg)
        {
            pMsg->Prim = MAC_DATA_RESP;
            IrmacDown(pIrlapCb->pIrdaLinkCb, pMsg);
        }

        break;

      case MAC_DATA_CONF:
        
        IRLAP_LOG_START((pIrlapCb, TEXT("MAC_DATA_CONF")));
        // IrNDIS will only confirm if the ref count is 0. this will ensure
        // that we are not messing up message when retranmitting.
        // Proper way may be to incorporate send confirmations into the LAP state
        // machine and not retransmit until the message is confirmed.
        ASSERT(pMsg->IRDA_MSG_SendRefCnt == 0);
        pMsg->Prim = IRLAP_DATA_CONF;
        pMsg->IRDA_MSG_DataStatus = IRLAP_DATA_REQUEST_COMPLETED;

        IrlmpUp(pIrlapCb->pIrdaLinkCb, pMsg);
        break;

      case MAC_CONTROL_CONF:
        IRLAP_LOG_START((pIrlapCb, IRDA_PrimStr[pMsg->Prim]));
        ProcessMACControlConf(pIrlapCb, pMsg);
        break;

      default:
        IRLAP_LOG_START((pIrlapCb, IRDA_PrimStr[pMsg->Prim]));
        ASSERT(0); //rc = IRLAP_BAD_PRIM;

    }

    IRLAP_LOG_COMPLETE(pIrlapCb);
}

/*****************************************************************************
*
*/
VOID
ReturnRxTxWinMsgs(PIRLAP_CB pIrlapCb)
{
    int         i;
    IRDA_MSG   *pMsg;

    // Return messages on TxMsgList to LMP
    while (DequeMsgList(&pIrlapCb->TxMsgList, &pMsg) == SUCCESS)
    {
        pMsg->Prim += 2; // make it a confirm
        pMsg->IRDA_MSG_DataStatus = IRLAP_DATA_REQUEST_FAILED_LINK_RESET;
        IrlmpUp(pIrlapCb->pIrdaLinkCb, pMsg); 
    }

    pIrlapCb->TxWin.Start = 0;
    pIrlapCb->TxWin.End = 0;
    // Transmit window
    for (i = 0; i < IRLAP_MOD; i++)
    {
        if (pIrlapCb->TxWin.pMsg[i] != NULL)
        {
            pIrlapCb->TxWin.pMsg[i]->Prim = IRLAP_DATA_CONF;
            pIrlapCb->TxWin.pMsg[i]->IRDA_MSG_DataStatus =
            IRLAP_DATA_REQUEST_FAILED_LINK_RESET;
            IrlmpUp(pIrlapCb->pIrdaLinkCb, pIrlapCb->TxWin.pMsg[i]); // rc !!!

            pIrlapCb->TxWin.pMsg[i] = NULL;
        }
    }

    // Cleanup RxWin
    pIrlapCb->RxWin.Start = 0;
    pIrlapCb->RxWin.End = 0;
    for (i = 0; i < IRLAP_MOD; i++)
    {
        // Receive window
        if ((pMsg = pIrlapCb->RxWin.pMsg[i]) != NULL)
        {
            pMsg->Prim = MAC_DATA_RESP;
            IrmacDown(pIrlapCb->pIrdaLinkCb, pMsg);
            pIrlapCb->RxWin.pMsg[i] = NULL;
        }
    }

    return;
}

/*****************************************************************************
*
* MyDevAddr - Determines if DevAddr matches the local
*             device address or is the broadcast
*
* TRUE if address is mine or broadcast else FALS
*
*
*/
BOOLEAN
MyDevAddr(PIRLAP_CB pIrlapCb,
          UCHAR       DevAddr[])
{
    if (CTEMemCmp(DevAddr, IrlapBroadcastDevAddr,
                  IRDA_DEV_ADDR_LEN) &&
        CTEMemCmp(DevAddr, pIrlapCb->LocalDevice.DevAddr,
                  IRDA_DEV_ADDR_LEN))
    {
        return FALSE;
    }
    return TRUE;
}

/*****************************************************************************
*
*    ProcessConnectReq - Process connect request from LMP
*
*/
UINT
ProcessConnectReq(PIRLAP_CB pIrlapCb,
                  PIRDA_MSG pMsg)
{
    IRDA_MSG IMsg;
    
    switch (pIrlapCb->State)
    {
      case NDM:
        // Save Remote Address for later use
        CTEMemCopy(pIrlapCb->RemoteDevice.DevAddr,
                      pMsg->IRDA_MSG_RemoteDevAddr,
                      IRDA_DEV_ADDR_LEN);

        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)")));
        break;

      case P_CLOSE:
        CTEMemCopy(pIrlapCb->RemoteDevice.DevAddr,
                       pMsg->IRDA_MSG_RemoteDevAddr, IRDA_DEV_ADDR_LEN);
        pIrlapCb->ConnAfterClose = TRUE;
        break;
        
       case DSCV_REPLY:
       default:
          return IRLAP_REMOTE_DISCOVERY_IN_PROGRESS_ERR;
    }

    return SUCCESS;
}
/*****************************************************************************
*
*   ProcessConnectResp - Process connect response from LMP
*
*/
VOID
ProcessConnectResp(PIRLAP_CB pIrlapCb,
                   PIRDA_MSG pMsg)
{

    if (pIrlapCb->State != SNRM_RECEIVED)
    {
        ASSERT(0);
        return;
    }

    pIrlapCb->ConnAddr = pIrlapCb->SNRMConnAddr;
    SendUA(pIrlapCb, TRUE);
    ApplyQosParms(pIrlapCb);

    InitializeState(pIrlapCb, SECONDARY);
    // start watchdog timer with poll timeout
    IrlapTimerStart(TEXT("ProcessConnectResp"), pIrlapCb, &pIrlapCb->WDogTimer);
    pIrlapCb->State = S_NRM;
}
/*****************************************************************************
*
*   ProcessLinkControlReq - Process Link control request from LMP
*
*/
UINT
ProcessLinkControlReq(PIRLAP_CB pIrlapCb,
                      PIRDA_MSG pMsg)
{
    IRDA_MSG    IMsg;

    IMsg.Prim = MAC_CONTROL_REQ;

    while (pIrlapCb->State != NDM)
    {
        DEBUGMSG(1, (TEXT("Irlap link control waiting for LAP NDM.\r\n")));
        Sleep(200);
    }
    if (pMsg->IRDA_MSG_AcquireResources == TRUE)
    {
        UCHAR  DscvInfoBuf[64];
        int    DscvInfoLen;
        ULONG  Val, Mask;    
        int    i;

⌨️ 快捷键说明

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