📄 irlap.c
字号:
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 + -