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

📄 irlap.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*****************************************************************************
*
*
*       @doc
*       @module irlap.c | Provides IrLAP API
*
*       Date: 4/15/95
*
*       @comm
*
*  This module exports the following API's:
*
*       IrlapDown(Message)
*           Receives from LMP:
*               - Discovery request
*               - Connect request/response
*               - Disconnect request
*               - Data/UData request
*
*       IrlapUp(Message)
*           Receives from MAC:
*               - Data indications
*               - Control confirmations
*
*       IrlapTimerExp(Timer)
*           Receives from timer thread timer expiration notifications
*
*       IrlapCloseLink()
*           Shut down IRLAP and IRMAC.
*
*       IrlapGetQosParmVal()
*           Allows IRLMP to decode Qos.
*
*                |---------|
*                |  IRLMP  |
*                |---------|
*                  /|\  |
*                   |   |
*        IrlmpUp()  |   | IrlapDown()
*                   |   |
*                   |  \|/
*                |---------|  IRDA_TimerStart/Stop()   |-------|
*                |         |-------------------------->|       |
*                |  IRLAP  |                           | TIMER |
*                |         |<--------------------------|       |
*                |---------|      XTimerExp()          |-------|
*                  /|\  |
*                   |   |
*        IrlapUp()  |   |IrmacDown()
*                   |   |
*                   |  \|/
*                |---------|
*                |  IRMAC  |
*                |---------|
*
*
*  Discovery Request
*
*  |-------|  IRLAP_DISCOVERY_REQ                                |-------|
*  |       |---------------------------------------------------->|       |
*  | IRLMP |                                                     | IRLAP |
*  |       |<----------------------------------------------------|       |
*  |-------|   IRLAP_DISCOVERY_CONF                              |-------|
*                  DscvStatus = IRLAP_DISCOVERY_COMPLETE
*                               IRLAP_DISCOVERY_COLLISION
*                               MAC_MEDIA_BUSY
*
*  Connect Request
*
*  |-------|  IRLAP_CONNECT_REQ                                  |-------|
*  |       |---------------------------------------------------->|       |
*  | IRLMP |                                                     | IRLAP |
*  |       |<----------------------------------------------------|       |
*  |-------|   IRLAP_CONNECT_CONF                                |-------|
*                  ConnStatus = IRLAP_CONNECTION_COMPLETE
*              IRLAP_DISCONNECT_IND
*                  DiscStatus = IRLAP_NO_RESPONSE
*                               MAC_MEDIA_BUSY
*
*  Disconnect Request
*
*  |-------|  IRLAP_DISCONNECT_REQ                               |-------|
*  |       |---------------------------------------------------->|       |
*  | IRLMP |                                                     | IRLAP |
*  |       |<----------------------------------------------------|       |
*  |-------|   IRLAP_DISCONNECT_IND                              |-------|
*                  DiscStatus = IRLAP_DISCONNECT_COMPLETE
*                               IRLAP_NO_RESPONSE
*
*  UData/Data Request
*
*  |-------|  IRLAP_DATA/UDATA_REQ                               |-------|
*  |       |---------------------------------------------------->|       |
*  | IRLMP |                                                     | IRLAP |
*  |       |<----------------------------------------------------|       |
*  |-------|   IRLAP_DATA_CONF                                   |-------|
*                  DataStatus =  IRLAP_DATA_REQUEST_COMPLETED
*                                IRLAP_DATA_REQUEST_FAILED_LINK_RESET
*
* See irda.h for complete message definitions
*/

#include <irda.h>
#ifdef UNDER_CE
#include <linklist.h>

// defined in NT irioctl.h
#define LINK_STATUS_IDLE            0
#define LINK_STATUS_DISCOVERING     1
#define LINK_STATUS_CONNECTED       2
#define LINK_STATUS_INTERRUPTED     3
#else // UNDER_CE
#include <irioctl.h>
#endif // !UNDER_CE
#include <irlap.h>
#include <irlmp.h>
#include <irlapp.h>
#include <irlapio.h>
#include <irlaplog.h>


// In IrNDIS.c.
extern UINT SlotTimeout;
extern UINT DiscoverTimeout;

#ifdef TEMPERAMENTAL_SERIAL_DRIVER
int TossedDups;
#endif

UINT    IrlapSlotTable[] = {1, 6, 8, 16};

UCHAR   IrlapBroadcastDevAddr[IRDA_DEV_ADDR_LEN] = {0xFF,0xFF,0xFF,0xFF};

// Parameter Value (PV) tables used for negotation
//                      bit0        1       2        3      4
//                         5        6       7        8
//                     --------------------------------------------
UINT vBaudTable[]     = {2400,   9600,   19200,   38400,  57600,\
                         115200, 576000, 1152000, 4000000,16000000};
UINT vMaxTATTable[]   = {500,    250,    100,     50,     25,   \
                         10,     5,      0,       0,      0     };
UINT vMinTATTable[]   = {10000,  5000,   1000,    500,    100,  \
                         50,     10,     0,       0,      0     };
UINT vDataSizeTable[] = {64,     128,    256,     512,    1024, \
                         2048,   0,      0,       0,      0     };
UINT vWinSizeTable[]  = {1,      2,      3,       4,      5,    \
                         6,      7,      0,       0,      0     };
UINT vBOFSTable[]     = {48,     24,     12,      5,      3,    \
                         2,      1,      0,       0,      0     };
UINT vDiscTable[]     = {3,      8,      12,      16,    20,    \
                         25,     30,     40,      0,     0      };
UINT vThreshTable[]   = {0,      3,      3,       3,     3,     \
                         3,      3,      3,       0,     0      };
UINT vBOFSDivTable[]  = {48,     12,     6,       3,     2,     \
                         1,      1,      1,       1,     1      };

// Tables for determining maximum line capacity for baud, max turn time
//      max turn time - 500ms   250ms   100ms  50ms  25ms  10ms   5ms
//      -------------------------------------------------------------
UINT MAXCAP_9600[]    = {400,       200,    80,     0,      0,      0,      0,      0,      0,      0};
UINT MAXCAP_19200[]   = {800,       400,    160,    0,      0,      0,      0,      0,      0,      0};
UINT MAXCAP_38400[]   = {1600,      800,    320,    0,      0,      0,      0,      0,      0,      0};
UINT MAXCAP_57600[]   = {2360,      1180,   472,    0,      0,      0,      0,      0,      0,      0};
UINT MAXCAP_115200[]  = {4800,      2400,   960,    480,    240,    96,     48,     24,     12,     6};
UINT MAXCAP_576000[]  = {28800,     11520,  5760,   2880,   1440,   720,    360,    180,    90,     45};
UINT MAXCAP_1152000[] = {57600,     28800,  11520,  5760,   2880,   1440,   720,    360,    180,    90};
UINT MAXCAP_4000000[] = {200000,    100000, 40000,  20000,  10000,  5000,   2500,   1200,   600,    300};
UINT MAXCAP_16000000[] ={800000,    400000, 160000, 80000,  40000,  20000,  10000,  5000,   2500,   1200};

// prototypes
STATIC VOID InitializeState(PIRLAP_CB, IRLAP_STN_TYPE);
STATIC VOID ReturnRxTxWinMsgs(PIRLAP_CB);
STATIC UINT ProcessLinkControlReq(PIRLAP_CB, PIRDA_MSG);
STATIC UINT ProcessConnectReq(PIRLAP_CB, PIRDA_MSG);
STATIC VOID ProcessConnectResp(PIRLAP_CB, PIRDA_MSG);
STATIC UINT ProcessDiscoveryReq(PIRLAP_CB, PIRDA_MSG);
STATIC VOID ProcessDisconnectReq(PIRLAP_CB);
STATIC UINT ProcessDataAndUDataReq(PIRLAP_CB, PIRDA_MSG);
STATIC VOID XmitTxMsgList(PIRLAP_CB, BOOLEAN, BOOLEAN *);
STATIC VOID GotoPCloseState(PIRLAP_CB);
STATIC VOID GotoNDMThenDscvOrConn(PIRLAP_CB);
STATIC VOID ProcessMACControlConf(PIRLAP_CB, PIRDA_MSG);
STATIC VOID ProcessMACDataInd(PIRLAP_CB, PIRDA_MSG , BOOLEAN *);
STATIC VOID ProcessDscvXIDCmd(PIRLAP_CB, IRLAP_XID_DSCV_FORMAT *, UCHAR *);
STATIC VOID ProcessDscvXIDRsp(PIRLAP_CB, IRLAP_XID_DSCV_FORMAT *, UCHAR *);
STATIC VOID ExtractQosParms(IRDA_QOS_PARMS *, UCHAR *, UCHAR *);
STATIC VOID InitDscvCmdProcessing(PIRLAP_CB, IRLAP_XID_DSCV_FORMAT *);
STATIC VOID ExtractDeviceInfo(IRDA_DEVICE *, IRLAP_XID_DSCV_FORMAT *, UCHAR *);
STATIC BOOLEAN DevInDevList(UCHAR[], LIST_ENTRY *);
STATIC VOID AddDevToList(PIRLAP_CB, IRLAP_XID_DSCV_FORMAT *, UCHAR *);
STATIC VOID FreeDevList(LIST_ENTRY *);
STATIC VOID ProcessSNRM(PIRLAP_CB, IRLAP_SNRM_FORMAT *, UCHAR *);
STATIC VOID ProcessUA(PIRLAP_CB, IRLAP_UA_FORMAT *, UCHAR *);
STATIC VOID ProcessDISC(PIRLAP_CB);
STATIC VOID ProcessRD(PIRLAP_CB);
STATIC VOID ProcessRNRM(PIRLAP_CB);
STATIC VOID ProcessDM(PIRLAP_CB);
STATIC VOID ProcessFRMR(PIRLAP_CB);
STATIC VOID ProcessTEST(PIRLAP_CB, PIRDA_MSG, IRLAP_UA_FORMAT *, int, int);
STATIC VOID ProcessUI(PIRLAP_CB, PIRDA_MSG, int, int);
STATIC VOID ProcessREJ_SREJ(PIRLAP_CB, int, PIRDA_MSG, int, int, UINT);
STATIC VOID ProcessRR_RNR(PIRLAP_CB, int, PIRDA_MSG, int, int, UINT);
STATIC VOID ProcessIFrame(PIRLAP_CB, PIRDA_MSG, int, int, UINT, UINT, BOOLEAN *);
STATIC BOOLEAN InvalidNs(PIRLAP_CB, UINT);
STATIC BOOLEAN InvalidNr(PIRLAP_CB, UINT);
STATIC BOOLEAN InWindow(UINT, UINT, UINT);
STATIC VOID ProcessInvalidNsOrNr(PIRLAP_CB, int);
STATIC VOID ProcessInvalidNr(PIRLAP_CB, int);
STATIC VOID InsertRxWinAndForward(PIRLAP_CB, PIRDA_MSG, UINT, BOOLEAN *);
STATIC VOID ResendRejects(PIRLAP_CB, UINT);
STATIC VOID ConfirmAckedTxMsgs(PIRLAP_CB, UINT);
STATIC VOID MissingRxFrames(PIRLAP_CB);
STATIC VOID IFrameOtherStates(PIRLAP_CB, int, int);
STATIC UINT NegotiateQosParms(PIRLAP_CB, IRDA_QOS_PARMS *);
STATIC VOID ApplyQosParms(PIRLAP_CB);
STATIC VOID StationConflict(PIRLAP_CB);
STATIC VOID ApplyDefaultParms(PIRLAP_CB);
STATIC VOID ResendDISC(PIRLAP_CB);
STATIC BOOLEAN IgnoreState(PIRLAP_CB);
STATIC BOOLEAN MyDevAddr(PIRLAP_CB, UCHAR []);
STATIC VOID SlotTimerExp(PVOID);
STATIC VOID FinalTimerExp(PVOID);
STATIC VOID PollTimerExp(PVOID);
STATIC VOID BackoffTimerExp(PVOID);
STATIC VOID WDogTimerExp(PVOID);
STATIC VOID QueryTimerExp(PVOID);

#if DBG
void _inline IrlapTimerStart(
    TCHAR *lpszFunc, 
    PIRLAP_CB pIrlapCb, 
    PIRDA_TIMER pTmr)
{
    IRLAP_LOG_ACTION((pIrlapCb, TEXT("Start %hs timer for %dms"), pTmr->pName,
                      pTmr->Timeout));

    DEBUGMSG(DBG_TIMER,
             (TEXT("%hs timer started @ %d (%s)\r\n"),
              pTmr->pName, 
              GetTickCount(),
              lpszFunc));
    
    IrdaTimerStart(pTmr);
}

void _inline IrlapTimerStop(
    TCHAR *lpszFunc, 
    PIRLAP_CB pIrlapCb, 
    PIRDA_TIMER pTmr)
{
    IRLAP_LOG_ACTION((pIrlapCb, TEXT("Stop %hs timer"), pTmr->pName));

    IrdaTimerStop(pTmr);

    DEBUGMSG(DBG_TIMER,
             (TEXT("%hs timer stop @ %d (%s) - %hs\r\n"),
              pTmr->pName, 
              GetTickCount(),
              lpszFunc,
              pTmr->Late ? "LATE" : "not late"));
}
#else
#define IrlapTimerStart(f,c,t)   IrdaTimerStart(t)
#define IrlapTimerStop(f,c,t)    IrdaTimerStop(t)
#endif

VOID
IrlapOpenLink(OUT PNTSTATUS           Status,
              IN  PIRDA_LINK_CB       pIrdaLinkCb,
              IN  IRDA_QOS_PARMS      *pQos,
              IN  UCHAR               *pDscvInfo,
              IN  int                 DscvInfoLen,
              IN  UINT                MaxSlot,
              IN  UCHAR               *pDeviceName,
              IN  int                 DeviceNameLen,
              IN  UCHAR               CharSet)
{
    UINT        rc = SUCCESS;
    int         i;
    IRDA_MSG    IMsg;
    PIRLAP_CB   pIrlapCb;
    NDIS_STRING AStr = NDIS_STRING_CONST("InfraredTransceiverType");
    
    DEBUGMSG(DBG_IRLAP, (TEXT("IrlapOpenLink\n")));
    
    if (IRDA_ALLOC_MEM(pIrlapCb, sizeof(IRLAP_CB), MT_IRLAPCB) == NULL)
    {
        DEBUGMSG(DBG_ERROR, (TEXT("Alloc failed\n")));
        *Status = STATUS_INSUFFICIENT_RESOURCES;
        return;
    }
                
    IrlmpOpenLink(Status,
                  pIrdaLinkCb,
                  pDeviceName,
                  DeviceNameLen,
                  CharSet);

    if (*Status != STATUS_SUCCESS)
    {
        DEBUGMSG(DBG_ERROR, (TEXT("IrlmpOpenLink failed\n")));
        IRDA_FREE_MEM(pIrlapCb);
        return;
    }
        
    pIrdaLinkCb->IrlapContext = pIrlapCb;

    DscvInfoLen = DscvInfoLen > IRLAP_DSCV_INFO_LEN ?
        IRLAP_DSCV_INFO_LEN : DscvInfoLen;
    
    CTEMemCopy(pIrlapCb->LocalDevice.DscvInfo, pDscvInfo, DscvInfoLen);

    pIrlapCb->LocalDevice.DscvInfoLen = DscvInfoLen;

    CTEMemCopy(&pIrlapCb->LocalQos, pQos, sizeof(IRDA_QOS_PARMS));

    pIrlapCb->MaxSlot       = MaxSlot;
    pIrlapCb->pIrdaLinkCb   = pIrdaLinkCb;
    
    InitMsgList(&pIrlapCb->TxMsgList);
    
    InitializeListHead(&pIrlapCb->DevList);
    
    for (i = 0; i < IRLAP_MOD; i++)
    {
        pIrlapCb->TxWin.pMsg[i] = NULL;
        pIrlapCb->RxWin.pMsg[i] = NULL;
    }

    // Get the local MAX TAT (for final timeout)
    if ((pIrlapCb->LocalMaxTAT =
         IrlapGetQosParmVal(vMaxTATTable,
                            pIrlapCb->LocalQos.bfMaxTurnTime, NULL)) == -1)
    {
        *Status = STATUS_UNSUCCESSFUL;
        return /*IRLAP_BAD_QOS*/;
    }

    if ((pIrlapCb->LocalWinSize =
         IrlapGetQosParmVal(vWinSizeTable,
                            pIrlapCb->LocalQos.bfWindowSize, NULL)) == -1)
    {
        *Status = STATUS_UNSUCCESSFUL;
        return /*IRLAP_BAD_QOS*/;
    }
        
    // initialize as PRIMARY so UI frames in contention
    // state sends CRBit = cmd
    InitializeState(pIrlapCb, PRIMARY);
    
    pIrlapCb->State = NDM;

    // Generate random local address
    StoreULAddr(pIrlapCb->LocalDevice.DevAddr, (ULONG) GetMyDevAddr(FALSE));

    pIrlapCb->LocalDevice.IRLAP_Version = 0; 

    pIrlapCb->Baud              = IRLAP_CONTENTION_BAUD;
    pIrlapCb->RemoteMaxTAT      = IRLAP_CONTENTION_MAX_TAT;
    pIrlapCb->RemoteDataSize    = IRLAP_CONTENTION_DATA_SIZE;
    pIrlapCb->RemoteWinSize     = IRLAP_CONTENTION_WIN_SIZE; 
    pIrlapCb->RemoteNumBOFS     = IRLAP_CONTENTION_BOFS;

    pIrlapCb->ConnAddr = IRLAP_BROADCAST_CONN_ADDR;

    pIrlapCb->N1 = 0;  // calculated at negotiation
    pIrlapCb->N2 = 0;
    pIrlapCb->N3 = 5;  // recalculated after negotiation ??

#if DBG
    pIrlapCb->PollTimer.pName       = "Poll";
    pIrlapCb->FinalTimer.pName      = "Final" ;
    pIrlapCb->SlotTimer.pName       = "Slot";
    pIrlapCb->QueryTimer.pName      = "Query";
    pIrlapCb->WDogTimer.pName       = "WatchDog";
    pIrlapCb->BackoffTimer.pName    = "Backoff";    
#endif
    
    IrdaTimerInitialize(&pIrlapCb->PollTimer,
                        PollTimerExp,
                        pIrlapCb->RemoteMaxTAT,
                        pIrlapCb,
                        pIrdaLinkCb);

    IrdaTimerInitialize(&pIrlapCb->FinalTimer,
                        FinalTimerExp,
                        pIrlapCb->LocalMaxTAT,
                        pIrlapCb,
                        pIrdaLinkCb);

    IrdaTimerInitialize(&pIrlapCb->SlotTimer,
                        SlotTimerExp,
                        SlotTimeout,
                        pIrlapCb,
                        pIrdaLinkCb);

⌨️ 快捷键说明

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