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

📄 irlap.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
            IMsg.IRDA_MSG_DscvStatus =
                IRLAP_REMOTE_DISCOVERY_IN_PROGRESS;
            IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
            // fall through

          case NDM:
            InitDscvCmdProcessing(pIrlapCb, pXidFormat);
            pIrlapCb->State = DSCV_REPLY;
            break;

          case DSCV_QUERY:
            pIrlapCb->State = NDM;
            IMsg.Prim = IRLAP_DISCOVERY_CONF;
            IMsg.IRDA_MSG_pDevList = NULL;
            IMsg.IRDA_MSG_DscvStatus = IRLAP_DISCOVERY_COLLISION;
            IrlapTimerStop(TEXT("ProcessDscvXIDCmd: DSCV_QUERY2"), 
                           pIrlapCb, &pIrlapCb->SlotTimer);
            IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
            break;

          case DSCV_REPLY:
            if (pXidFormat->GenNewAddr)
            {
                pIrlapCb->GenNewAddr = TRUE;
                IrlapTimerStop(TEXT("ProcessDscvXIDCmd: DSCV_REPLY2"),
                               pIrlapCb, &pIrlapCb->QueryTimer);
                InitDscvCmdProcessing(pIrlapCb, pXidFormat);
            }
            else
            {
                if (pIrlapCb->RespSlot <= pXidFormat->SlotNo &&
                    !pIrlapCb->DscvRespSent)
                {
                    SendDscvXIDRsp(pIrlapCb);
                    pIrlapCb->DscvRespSent = TRUE;
                }
            }
            break;

          default:
            IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
        }
    }
    return;
}
/*****************************************************************************
*
*
*/
void
ExtractDeviceInfo(IRDA_DEVICE *pDevice, IRLAP_XID_DSCV_FORMAT *pXidFormat,
                  UCHAR *pEndDscvInfoUCHAR)
{
    CTEMemCopy(pDevice->DevAddr, pXidFormat->SrcAddr, IRDA_DEV_ADDR_LEN);
    pDevice->IRLAP_Version = pXidFormat->Version;

    // ??? what about DscvMethod

    pDevice->DscvInfoLen =
        pEndDscvInfoUCHAR > &pXidFormat->FirstDscvInfoByte ?
        pEndDscvInfoUCHAR-&pXidFormat->FirstDscvInfoByte : 0;
    
    memset(pDevice->DscvInfo, 0, sizeof(pDevice->DscvInfo));
    CTEMemCopy(pDevice->DscvInfo, &pXidFormat->FirstDscvInfoByte,
           pDevice->DscvInfoLen);
}
/*****************************************************************************
*
*
*/
VOID
InitDscvCmdProcessing(PIRLAP_CB pIrlapCb,
                      IRLAP_XID_DSCV_FORMAT *pXidFormat)
{
    pIrlapCb->RemoteMaxSlot = IrlapSlotTable[pXidFormat->NoOfSlots];

    pIrlapCb->RespSlot = IRLAP_RAND(pXidFormat->SlotNo,
                                   pIrlapCb->RemoteMaxSlot - 1);

    CTEMemCopy(pIrlapCb->RemoteDevice.DevAddr, pXidFormat->SrcAddr,
                  IRDA_DEV_ADDR_LEN);

    IRLAP_LOG_ACTION((pIrlapCb,
                      TEXT("Responding in slot %d to dev %02X%02X%02X%02X"),
                      pIrlapCb->RespSlot,
                      pIrlapCb->RemoteDevice.DevAddr[0],
                      pIrlapCb->RemoteDevice.DevAddr[1],
                      pIrlapCb->RemoteDevice.DevAddr[2],
                      pIrlapCb->RemoteDevice.DevAddr[3]));

    if (pIrlapCb->RespSlot == pXidFormat->SlotNo)
    {
        SendDscvXIDRsp(pIrlapCb);
        pIrlapCb->DscvRespSent = TRUE;
    }
    else
    {
        pIrlapCb->DscvRespSent = FALSE;
    }

    IrlapTimerStart(TEXT("InitDscvCmdProcessing"),
                    pIrlapCb, &pIrlapCb->QueryTimer);
}
/*****************************************************************************
*
*/
VOID
ProcessDscvXIDRsp(PIRLAP_CB pIrlapCb,
                  IRLAP_XID_DSCV_FORMAT *pXidFormat,
                  UCHAR *pEndDscvInfoUCHAR)
{
    IRDA_MSG    IMsg;
    
    if (pIrlapCb->State == DSCV_QUERY)
    {

        if (DevInDevList(pXidFormat->SrcAddr, &pIrlapCb->DevList))
        {
            IrlapTimerStop(TEXT("ProcessDscvXIDRsp"),
                           pIrlapCb, &pIrlapCb->SlotTimer);
            pIrlapCb->SlotCnt = 0;
            pIrlapCb->GenNewAddr = TRUE;
            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 (dscv sense)")));
            IrmacDown(pIrlapCb->pIrdaLinkCb, &IMsg);            
        }
        else
        {
            AddDevToList(pIrlapCb, pXidFormat, pEndDscvInfoUCHAR);
        }
    }
    else
    {
        IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
    }
}
/*****************************************************************************
*
*   DevInDevList - Determines if given device is already in list
*
*/
BOOLEAN
DevInDevList(UCHAR DevAddr[], LIST_ENTRY *pDevList)
{
    IRDA_DEVICE *pDevice;

    pDevice = (IRDA_DEVICE *) pDevList->Flink;

    while (pDevList != (LIST_ENTRY *) pDevice)
    {
        if (CTEMemCmp(pDevice->DevAddr, DevAddr,
                      IRDA_DEV_ADDR_LEN) == 0)
            return (TRUE);

        pDevice = (IRDA_DEVICE *) pDevice->Linkage.Flink;
    }
    return (FALSE);
}
/*****************************************************************************
*
*   AddDevToList - Adds elements in a device list
*
*/
VOID
AddDevToList(PIRLAP_CB pIrlapCb,
             IRLAP_XID_DSCV_FORMAT *pXidFormat,
             UCHAR *pEndDscvInfoUCHAR)
{
    IRDA_DEVICE *pDevice;

    if (IRDA_ALLOC_MEM(pDevice, sizeof(IRDA_DEVICE), MT_IRLAP_DEVICE) == NULL)
    {
        ASSERT(0);
        
        return;// (IRLAP_MALLOC_FAILED);
    }
    else
    {
        ExtractDeviceInfo(pDevice, pXidFormat, pEndDscvInfoUCHAR);

        InsertTailList(&pIrlapCb->DevList, &(pDevice->Linkage));

        IRLAP_LOG_ACTION((pIrlapCb,
                          TEXT("%02X%02X%02X%02X added to Device List"),
                          EXPAND_ADDR(pDevice->DevAddr)));
    }
}
/*****************************************************************************
*
*/
void
FreeDevList(LIST_ENTRY *pDevList)
{
    IRDA_DEVICE *pDevice;

    while (IsListEmpty(pDevList) == FALSE)
    {
        pDevice = (IRDA_DEVICE *) RemoveHeadList(pDevList);
        IRDA_FREE_MEM(pDevice);
    }

    //IRLAP_LOG_ACTION((pIrlapCb, TEXT("Device list cleared")));
}

/*****************************************************************************
*
*/
int
AddressGreaterThan(UCHAR A1[], UCHAR A2[])
{
    int i;
    
    for (i = 0; i < IRDA_DEV_ADDR_LEN; i++)
    {
        if (A1[i] > A2[i])
            return TRUE;
        if (A1[i] != A2[1])
            return FALSE;
    }
    return FALSE;
}
/*****************************************************************************
*
*/
VOID
ProcessSNRM(PIRLAP_CB pIrlapCb,
            IRLAP_SNRM_FORMAT *pSnrmFormat,
            UCHAR *pEndQosUCHAR)
{
    IRDA_MSG    IMsg;
    BOOLEAN     QosInSNRM = &pSnrmFormat->FirstQosByte < pEndQosUCHAR;
    BOOLEAN     AddrsInSNRM = (UCHAR *)pSnrmFormat < pEndQosUCHAR;
    UINT        rc;

    if (AddrsInSNRM)
    {
        if (!MyDevAddr(pIrlapCb, pSnrmFormat->DestAddr))
        {
            IRLAP_LOG_ACTION((pIrlapCb, 
                       TEXT("Ignoring SNRM addressed to:%02X%02X%02X%02X"),
                              EXPAND_ADDR(pSnrmFormat->DestAddr)));
            return;
        }
        CTEMemCopy(pIrlapCb->RemoteDevice.DevAddr,
                  pSnrmFormat->SrcAddr, IRDA_DEV_ADDR_LEN);
    }

    switch (pIrlapCb->State)
    {
      case DSCV_MEDIA_SENSE:
      case DSCV_QUERY:
        // In the middle of discovery... End discovery and reply to SNRM
        IMsg.Prim = IRLAP_DISCOVERY_CONF;
        IMsg.IRDA_MSG_pDevList = NULL;
        IMsg.IRDA_MSG_DscvStatus = IRLAP_REMOTE_CONNECTION_IN_PROGRESS;
        IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
        // fall through and send connect indication
      case DSCV_REPLY:
      case NDM:
        if (AddrsInSNRM)
        {
            pIrlapCb->SNRMConnAddr =
                (int)IRLAP_GET_ADDR(pSnrmFormat->ConnAddr);
        }
        if (QosInSNRM)
        {
            ExtractQosParms(&pIrlapCb->RemoteQos, &pSnrmFormat->FirstQosByte,
                        pEndQosUCHAR);

            if ((rc = NegotiateQosParms(pIrlapCb, &pIrlapCb->RemoteQos)))
            {
                DEBUGMSG(1, (TEXT("IRLAP: SNRM/UA negotiation failed, rc=%\n"), rc));
                ASSERT(0);
                return;
            }
        }

        CTEMemCopy(IMsg.IRDA_MSG_RemoteDevAddr,
               pIrlapCb->RemoteDevice.DevAddr, IRDA_DEV_ADDR_LEN);
        IMsg.IRDA_MSG_pQos = &pIrlapCb->NegotiatedQos;
        IMsg.Prim = IRLAP_CONNECT_IND;
        IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
        pIrlapCb->State = SNRM_RECEIVED;
        break;

      case BACKOFF_WAIT:   // CROSSED SNRM
        // if Remote address greater than mine we'll respond to SNRM
        if (AddrsInSNRM)
        {
            if (AddressGreaterThan(pSnrmFormat->SrcAddr,
                                   pIrlapCb->LocalDevice.DevAddr))
            {
                IrlapTimerStop(TEXT("ProcessSNRM: BACKOFF_WAIT"), 
                               pIrlapCb, &pIrlapCb->BackoffTimer);
            }
        }
        // fall through
      case CONN_MEDIA_SENSE:   // CROSSED SNRM
      case SNRM_SENT:
        // if Remote address greater than mine we'll respond to SNRM
        if (AddrsInSNRM && AddressGreaterThan(pSnrmFormat->SrcAddr,
                                              pIrlapCb->LocalDevice.DevAddr))
        {
            if (pIrlapCb->State != BACKOFF_WAIT)
            {
                IrlapTimerStop(TEXT("ProcessSNRM: SNRM_SENT/CONN_MEDIA_SENSE"), 
                               pIrlapCb, &pIrlapCb->FinalTimer);
            }
            InitializeState(pIrlapCb, SECONDARY);

            if (QosInSNRM)
            {
                ExtractQosParms(&pIrlapCb->RemoteQos,
                                &pSnrmFormat->FirstQosByte, pEndQosUCHAR);
                if ((rc = NegotiateQosParms(pIrlapCb, &pIrlapCb->RemoteQos)))
                {
                    DEBUGMSG(1, (TEXT("Negotiation failed, rc=%\n"), rc));
                    ASSERT(0);
                    pIrlapCb->State = NDM;
                    return;
                }
            }

            if (AddrsInSNRM)
            {
                pIrlapCb->ConnAddr =
                    (int)IRLAP_GET_ADDR(pSnrmFormat->ConnAddr);
            }

            SendUA(pIrlapCb, TRUE);
            
            if (QosInSNRM)
            {
                ApplyQosParms(pIrlapCb);
            }
            
            IMsg.IRDA_MSG_pQos = &pIrlapCb->NegotiatedQos;
            IMsg.Prim = IRLAP_CONNECT_CONF;
            IMsg.IRDA_MSG_ConnStatus = IRLAP_CONNECTION_COMPLETED;
            IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);

            IrlapTimerStart(TEXT("ProcessSNRM: SNRM_SENT/CONN_MEDIA_SENSE/BACKOFF_WAIT"), 
                            pIrlapCb, &pIrlapCb->WDogTimer);
            pIrlapCb->State = S_NRM;
        }
        break;

      case P_RECV:
      case P_DISCONNECT_PEND:
      case P_CLOSE:
        IrlapTimerStop(TEXT("ProcessSNRM: P_RECV/P_DISCONNECT_PEND/P_CLOSE"), 
                       pIrlapCb, &pIrlapCb->FinalTimer);
        pIrlapCb->State = NDM;
        StationConflict(pIrlapCb);
        ReturnRxTxWinMsgs(pIrlapCb);
        if (pIrlapCb->State == P_CLOSE)
        {
            GotoNDMThenDscvOrConn(pIrlapCb);
        }
        break;

      case S_NRM:
      case S_CLOSE:
      case S_DISCONNECT_PEND:
        IrlapTimerStop(TEXT("ProcessSNRM: S_DISCONNECT_PEND"), 
                       pIrlapCb, &pIrlapCb->WDogTimer);
        SendDM(pIrlapCb);
        ApplyDefaultParms(pIrlapCb);
        IMsg.Prim = IRLAP_DISCONNECT_IND;
        if (pIrlapCb->State == S_NRM)
        {
            IMsg.IRDA_MSG_DiscStatus = IRLAP_DECLINE_RESET;
        }
        else
        {
            IMsg.IRDA_MSG_DiscStatus = IRLAP_DISCONNECT_COMPLETED;
        }
        pIrlapCb->State = NDM;
        IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
        break;

      case S_ERROR:
        IrlapTimerStop(TEXT("ProcessSNRM: S_ERROR"), 
                       pIrlapCb, &pIrlapCb->WDogTimer);
        SendFRMR(pIrlapCb, &pIrlapCb->Frmr);
        IrlapTimerStart(TEXT("ProcessSNRM: S_ERROR"), 
                        pIrlapCb, &pIrlapCb->WDogTimer);
        pIrlapCb->State = S_NRM;
        break;

      default:
        IRLAP_LOG_ACTION((pIrlapCb, TEXT("SNRM ignored in this state")));
    }

    return;
}
/******

⌨️ 快捷键说明

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