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