summaryrefslogtreecommitdiffstats
path: root/private/ntos/tdi/irda
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/tdi/irda
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/tdi/irda')
-rw-r--r--private/ntos/tdi/irda/dirs10
-rw-r--r--private/ntos/tdi/irda/driver/irda.c132
-rw-r--r--private/ntos/tdi/irda/driver/irndis.c706
-rw-r--r--private/ntos/tdi/irda/driver/makefile7
-rw-r--r--private/ntos/tdi/irda/driver/sources15
-rw-r--r--private/ntos/tdi/irda/inc/af_irda.h100
-rw-r--r--private/ntos/tdi/irda/inc/decdirda.h174
-rw-r--r--private/ntos/tdi/irda/inc/irda.h857
-rw-r--r--private/ntos/tdi/irda/inc/irdalink.h34
-rw-r--r--private/ntos/tdi/irda/inc/irerr.h110
-rw-r--r--private/ntos/tdi/irda/inc/irlap.h66
-rw-r--r--private/ntos/tdi/irda/inc/irlaplog.h44
-rw-r--r--private/ntos/tdi/irda/inc/irlmp.h60
-rw-r--r--private/ntos/tdi/irda/inc/irmac.h32
-rw-r--r--private/ntos/tdi/irda/inc/oscfg.h62
-rw-r--r--private/ntos/tdi/irda/inc/tmp.h31
-rw-r--r--private/ntos/tdi/irda/irlap/irlap.c4519
-rw-r--r--private/ntos/tdi/irda/irlap/irlapio.c900
-rw-r--r--private/ntos/tdi/irda/irlap/irlapio.h32
-rw-r--r--private/ntos/tdi/irda/irlap/irlaplog.c265
-rw-r--r--private/ntos/tdi/irda/irlap/irlapp.h299
-rw-r--r--private/ntos/tdi/irda/irlap/makefile6
-rw-r--r--private/ntos/tdi/irda/irlap/sources23
23 files changed, 8484 insertions, 0 deletions
diff --git a/private/ntos/tdi/irda/dirs b/private/ntos/tdi/irda/dirs
new file mode 100644
index 000000000..0ea6a777b
--- /dev/null
+++ b/private/ntos/tdi/irda/dirs
@@ -0,0 +1,10 @@
+DIRS= irlap \
+ driver
+
+
+
+
+
+
+
+
diff --git a/private/ntos/tdi/irda/driver/irda.c b/private/ntos/tdi/irda/driver/irda.c
new file mode 100644
index 000000000..72bdf3881
--- /dev/null
+++ b/private/ntos/tdi/irda/driver/irda.c
@@ -0,0 +1,132 @@
+/*
+ * IRDA.C
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+
+//#include <precomp.h>
+#include <irda.h>
+#include <irdalink.h>
+#include <irmac.h>
+#include <irlap.h>
+#include <irlmp.h>
+#include <tmp.h>
+
+int irdaDbgSettings = 1 + \
+ DBG_ERROR + \
+ DBG_WARN + \
+/*DBG_FUNCTION + */ \
+ /*DBG_NDIS +*/ \
+/* DBG_IRLAPLOG +*/ \
+ DBG_IRLAP;
+
+LIST_ENTRY IrdaLinkCbList;
+
+/*
+ ********************************************************************************
+ * DriverEntry
+ ********************************************************************************
+ *
+ *
+ *
+ */
+NTSTATUS DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath)
+{
+
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DEBUGMSG(DBG_FUNCTION,("+DriverEntry(IRDA)\n"));
+
+ InitializeListHead(&IrdaLinkCbList);
+
+ // IRLMP initialize
+ // IRLAP initialize
+
+ if ((Status = IrdaNdisInitialize()) != STATUS_SUCCESS)
+ {
+ goto done;
+ }
+
+done:
+
+ DEBUGMSG(DBG_FUNCTION, ("-DriverEntry(IRDA), rc %x\n", Status));
+
+ return Status;
+}
+
+void
+IrdaTimerInitialize(PIRDA_TIMER pTimer,
+ VOID (*ExpFunc)(PVOID Context),
+ UINT Timeout,
+ PVOID Context)
+{
+ CTEInitTimer(&pTimer->CteTimer);
+ pTimer->ExpFunc = ExpFunc;
+ pTimer->Context = Context;
+ pTimer->Timeout = Timeout;
+
+ DEBUGMSG(DBG_FUNCTION, ("IrdaTimerIntialize %s\n", pTimer->pName));
+}
+
+void
+TimerFunc(CTEEvent *Event, void *Arg)
+{
+ PIRDA_TIMER pIrdaTimer = (PIRDA_TIMER) Arg;
+ int rc;
+
+ DEBUGMSG(DBG_FUNCTION, ("Timer expired, context %x\n",
+ pIrdaTimer));
+
+ if (pIrdaTimer->Late != TRUE)
+ {
+ pIrdaTimer->ExpFunc(pIrdaTimer->Context);
+ }
+ else
+ {
+ DEBUGMSG(DBG_WARN,
+ (TEXT("IRDA TIMER LATE, ignoring\r\n")));
+
+ pIrdaTimer->Late = FALSE;
+ }
+
+ return;
+}
+
+VOID
+IrdaTimerStart(PIRDA_TIMER pIrdaTimer)
+{
+
+ pIrdaTimer->Late = FALSE;
+ CTEStartTimer(&pIrdaTimer->CteTimer, pIrdaTimer->Timeout,
+ TimerFunc, (PVOID) pIrdaTimer);
+
+ DEBUGMSG(DBG_FUNCTION, ("Start timer %s (%dms) context %x\n",
+ pIrdaTimer->pName,
+ pIrdaTimer->Timeout,
+ pIrdaTimer));
+ return;
+}
+
+VOID
+IrdaTimerStop(PIRDA_TIMER pIrdaTimer)
+{
+ if (CTEStopTimer(&pIrdaTimer->CteTimer) == 0)
+ {
+ pIrdaTimer->Late = TRUE;
+ }
+ DEBUGMSG(DBG_FUNCTION, ("Timer %s stopped\n", pIrdaTimer->pName));
+
+ return;
+}
+
diff --git a/private/ntos/tdi/irda/driver/irndis.c b/private/ntos/tdi/irda/driver/irndis.c
new file mode 100644
index 000000000..903e53570
--- /dev/null
+++ b/private/ntos/tdi/irda/driver/irndis.c
@@ -0,0 +1,706 @@
+/*
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+
+//#include <precomp.h>
+#include <irda.h>
+#include <irdalink.h>
+#include <ntddndis.h>
+#include <ndis.h>
+#include <irlap.h>
+
+NDIS_HANDLE NdisIrdaHandle = NULL;
+
+// Translate an OID query to LAP definition
+VOID
+OidToLapQos(
+ UINT ParmTable[],
+ UINT ValArray[],
+ UINT Cnt,
+ PUINT pBitField)
+{
+ UINT i, j;
+
+ *pBitField = 0;
+ for (i = 0; i < Cnt; i++)
+ for (j = 0; j <= PV_TABLE_MAX_BIT; j++)
+ if (ValArray[i] == ParmTable[j])
+ *pBitField |= 1<<j;
+}
+
+// Synchronous request for an OID
+NDIS_STATUS
+IrdaQueryOid(
+ IN PIRDA_LINK_CB pIrdaLinkCb,
+ IN NDIS_OID Oid,
+ OUT PUINT pQBuf,
+ IN OUT PUINT pQBufLen)
+{
+ NDIS_REQUEST NdisRequest;
+ NDIS_STATUS Status;
+
+ NdisResetEvent(&pIrdaLinkCb->SyncEvent);
+
+ NdisRequest.RequestType = NdisRequestQueryInformation;
+ NdisRequest.DATA.QUERY_INFORMATION.Oid = Oid;
+ NdisRequest.DATA.QUERY_INFORMATION.InformationBuffer = pQBuf;
+ NdisRequest.DATA.QUERY_INFORMATION.InformationBufferLength =
+ *pQBufLen * sizeof(UINT);
+
+ NdisRequest(&Status, pIrdaLinkCb->NdisBindingHandle, &NdisRequest);
+
+ if (Status == NDIS_STATUS_PENDING)
+ {
+ NdisWaitEvent(&pIrdaLinkCb->SyncEvent, 0);
+ Status = pIrdaLinkCb->SyncStatus;
+ }
+
+ *pQBufLen = NdisRequest.DATA.QUERY_INFORMATION.BytesWritten / sizeof(UINT);
+
+ return Status;
+}
+
+// Sync request to set an Oid
+NDIS_STATUS
+IrdaSetOid(
+ IN PIRDA_LINK_CB pIrdaLinkCb,
+ IN NDIS_OID Oid,
+ IN UINT Val)
+{
+ NDIS_REQUEST NdisRequest;
+ NDIS_STATUS Status;
+
+ NdisResetEvent(&pIrdaLinkCb->SyncEvent);
+
+ NdisRequest.RequestType = NdisRequestSetInformation;
+ NdisRequest.DATA.SET_INFORMATION.Oid = Oid;
+ NdisRequest.DATA.SET_INFORMATION.InformationBuffer = &Val;
+ NdisRequest.DATA.SET_INFORMATION.InformationBufferLength = sizeof(UINT);
+
+ NdisRequest(&Status, pIrdaLinkCb->NdisBindingHandle, &NdisRequest);
+
+ if (Status == NDIS_STATUS_PENDING)
+ {
+ NdisWaitEvent(&pIrdaLinkCb->SyncEvent, 0);
+ Status = pIrdaLinkCb->SyncStatus;
+ }
+ return Status;
+}
+
+// Allocate a message for LAP to use for internally generated frames.
+IRDA_MSG *
+AllocMacIMsg(PIRDA_LINK_CB pIrdaLinkCb)
+{
+ NDIS_PHYSICAL_ADDRESS pa = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
+ IRDA_MSG *pIMsg;
+
+ pIMsg = (IRDA_MSG *) NdisInterlockedRemoveHeadList(
+ &pIrdaLinkCb->IMsgList, &pIrdaLinkCb->SpinLock);
+
+ if (pIMsg == NULL)
+ {
+ NdisAllocateMemory(&pIMsg, sizeof(IRDA_MSG) + IRDA_MSG_DATA_SIZE,
+ 0, pa);
+ if (pIMsg == NULL)
+ return NULL;
+ pIrdaLinkCb->IMsgListLen++;
+ }
+
+ // Indicate driver owns message
+ pIMsg->IRDA_MSG_pOwner = &pIrdaLinkCb->IMsgList;
+
+ // Setup the pointers
+ pIMsg->IRDA_MSG_pHdrWrite = \
+ pIMsg->IRDA_MSG_pHdrRead = pIMsg->IRDA_MSG_Header + IRDA_HEADER_LEN;
+ pIMsg->IRDA_MSG_pBase = \
+ pIMsg->IRDA_MSG_pRead = \
+ pIMsg->IRDA_MSG_pWrite = (BYTE *) pIMsg + sizeof(IRDA_MSG);
+ pIMsg->IRDA_MSG_pLimit = pIMsg->IRDA_MSG_pBase + IRDA_MSG_DATA_SIZE-1;
+
+ return pIMsg;
+}
+
+void IrdaRequestComplete(
+ IN NDIS_HANDLE IrdaBindingContext,
+ IN PNDIS_REQUEST NdisRequest,
+ IN NDIS_STATUS Status
+ )
+{
+ PIRDA_LINK_CB pIrdaLinkCb = (PIRDA_LINK_CB) IrdaBindingContext;
+
+ DEBUGMSG(DBG_NDIS, ("+IrdaRequestComplete()\n"));
+
+ pIrdaLinkCb->SyncStatus = Status;
+ NdisSetEvent(&pIrdaLinkCb->SyncEvent);
+
+ return;
+}
+
+VOID IrdaOpenAdapterComplete(
+ IN NDIS_HANDLE IrdaBindingContext,
+ IN NDIS_STATUS Status,
+ IN NDIS_STATUS OpenErrorStatus
+ )
+{
+ PIRDA_LINK_CB pIrdaLinkCb = (PIRDA_LINK_CB) IrdaBindingContext;
+
+ DEBUGMSG(DBG_NDIS, ("+IrdaOpenAdapterComplete() IrdaBindingContext %x, Status %x\n",
+ IrdaBindingContext, Status));
+
+ pIrdaLinkCb->SyncStatus = Status;
+ NdisSetEvent(&pIrdaLinkCb->SyncEvent);
+
+ DEBUGMSG(DBG_NDIS, ("-IrdaOpenAdapterComplete()\n"));
+
+ return;
+}
+
+VOID IrdaCloseAdapterComplete(
+ IN NDIS_HANDLE IrdaBindingContext,
+ IN NDIS_STATUS Status
+ )
+{
+ PIRDA_LINK_CB pIrdaLinkCb = (PIRDA_LINK_CB) IrdaBindingContext;
+
+ DEBUGMSG(DBG_NDIS, ("+IrdaCloseAdapterComplete()\n"));
+
+ pIrdaLinkCb->SyncStatus = Status;
+ NdisSetEvent(&pIrdaLinkCb->SyncEvent);
+
+ DEBUGMSG(DBG_NDIS, ("-IrdaCloseAdapterComplete()\n"));
+
+ return;
+}
+
+VOID IrdaSendComplete(
+ IN NDIS_HANDLE Context,
+ IN PNDIS_PACKET NdisPacket,
+ IN NDIS_STATUS Status
+ )
+{
+ PIRDA_LINK_CB pIrdaLinkCb = (PIRDA_LINK_CB) Context;
+ PIRDA_PROTOCOL_RESERVED ProtocolReserved = \
+ (PIRDA_PROTOCOL_RESERVED) NdisPacket->ProtocolReserved;
+ PIRDA_MSG pIMsg = ProtocolReserved->pIMsg;
+ PNDIS_BUFFER NdisBuffer;
+
+ if (pIMsg->IRDA_MSG_pOwner == &pIrdaLinkCb->IMsgList)
+ {
+ NdisInterlockedInsertTailList(&pIrdaLinkCb->IMsgList,
+ &pIMsg->Linkage,
+ &pIrdaLinkCb->SpinLock);
+ }
+
+ if (NdisPacket){
+ NdisUnchainBufferAtFront(NdisPacket, &NdisBuffer);
+ while (NdisBuffer){
+ NdisFreeBuffer(NdisBuffer);
+ NdisUnchainBufferAtFront(NdisPacket, &NdisBuffer);
+ }
+
+ NdisFreePacket(NdisPacket);
+ }
+
+ DEBUGMSG(DBG_NDIS, ("+IrdaSendComplete()\n"));
+ return;
+}
+
+VOID IrdaTransferDataComplete(
+ IN NDIS_HANDLE IrdaBindingContext,
+ IN PNDIS_PACKET Packet,
+ IN NDIS_STATUS Status,
+ IN UINT BytesTransferred
+ )
+{
+ DEBUGMSG(DBG_NDIS, ("+IrdaTransferDataComplete()\n"));
+ return;
+}
+
+void IrdaResetComplete(
+ IN NDIS_HANDLE IrdaBindingContext,
+ IN NDIS_STATUS Status
+ )
+{
+ DEBUGMSG(DBG_NDIS, ("+IrdaResetComplete()\n"));
+ return;
+}
+
+NDIS_STATUS IrdaReceive(
+ IN NDIS_HANDLE IrdaBindingContext,
+ IN NDIS_HANDLE MacReceiveContext,
+ IN PVOID HeaderBuffer,
+ IN UINT HeaderBufferSize,
+ IN PVOID LookAheadBuffer,
+ IN UINT LookaheadBufferSize,
+ IN UINT PacketSize
+ )
+{
+ DEBUGMSG(DBG_NDIS, ("+IrdaReceive()\n"));
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+VOID IrdaReceiveComplete(
+ IN NDIS_HANDLE IrdaBindingContext
+ )
+{
+ DEBUGMSG(DBG_NDIS, ("+IrdaReceiveComplete()\n"));
+
+ return;
+}
+
+VOID IrdaStatus(
+ IN NDIS_HANDLE IrdaBindingContext,
+ IN NDIS_STATUS GeneralStatus,
+ IN PVOID StatusBuffer,
+ IN UINT StatusBufferSize
+ )
+{
+ PIRDA_LINK_CB pIrdaLinkCb = (PIRDA_LINK_CB) IrdaBindingContext;
+
+ if (GeneralStatus == NDIS_STATUS_MEDIA_BUSY)
+ {
+ DEBUGMSG(DBG_NDIS, ("STATUS_MEDIA_BUSY\n"));
+ }
+#ifdef DEBUG
+ else
+ {
+ DEBUGMSG(DBG_NDIS, ("Unknown Status indication\n"));
+ }
+#endif
+
+ return;
+}
+
+VOID IrdaStatusComplete(
+ IN NDIS_HANDLE IrdaBindingContext
+ )
+{
+ DEBUGMSG(DBG_NDIS, ("IrdaStatusComplete()\n"));
+
+ return;
+}
+
+INT IrdaReceivePacket(
+ IN NDIS_HANDLE IrdaBindingContext,
+ IN PNDIS_PACKET Packet
+ )
+{
+ UINT BufCnt, TotalLen, BufLen;
+ PNDIS_BUFFER pNdisBuf;
+ IRDA_MSG IMsg;
+ BYTE *pData;
+ PIRDA_LINK_CB pIrdaLinkCb = IrdaBindingContext;
+
+ DEBUGMSG(DBG_NDIS, ("+IrdaReceivePacket(%x)\n", pIrdaLinkCb));
+
+ NdisQueryPacket(Packet, NULL, &BufCnt, &pNdisBuf, &TotalLen);
+
+ DEBUGMSG(DBG_NDIS, (" BufCnt %d, TotalLen %d\n", BufCnt, TotalLen));
+
+ NdisQueryBuffer(pNdisBuf, &pData, &BufLen);
+
+ IMsg.Prim = MAC_DATA_IND;
+ IMsg.IRDA_MSG_pRead = pData;
+ IMsg.IRDA_MSG_pWrite = pData + BufLen;
+
+ IrlapUp(pIrdaLinkCb->IrlapContext, &IMsg);
+
+ return 0;
+}
+
+VOID IrdaBindAdapter(
+ OUT PNDIS_STATUS pStatus,
+ IN NDIS_HANDLE BindContext,
+ IN PNDIS_STRING AdapterName,
+ IN PVOID SystemSpecific1,
+ IN PVOID SystemSpecific2
+ )
+{
+ NDIS_STATUS OpenErrorStatus;
+ NDIS_MEDIUM MediumArray[] = {NdisMediumIrda};
+ UINT SelectedMediumIndex;
+ PIRDA_LINK_CB pIrdaLinkCb;
+ NDIS_PHYSICAL_ADDRESS pa = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
+ UINT UintArray[8];
+ UINT UintArrayCnt;
+ IRDA_MSG *pIMsg;
+ // *******************************************************
+ // *******************************************************
+ // TEMP - some these will come out of the registry
+ IRDA_QOS_PARMS LocalQos;
+ BYTE DscvInfoBuf[64];
+ int DscvInfoLen;
+ DWORD Val, Mask;
+ int i;
+#define DISCOVERY_HINT_CHARSET 0x820400
+#define DISCOVERY_NICKNAME "Aoxomoxoa"
+#define DISCOVERY_NICKNAME_LEN 9
+#define DISCOVERY_SLOTS 8
+
+ LocalQos.bfBaud = BPS_9600 | BPS_19200 | BPS_115200;
+ LocalQos.bfMaxTurnTime = MAX_TAT_500;
+ LocalQos.bfDataSize = DATA_SIZE_64|DATA_SIZE_128|DATA_SIZE_256;
+ LocalQos.bfWindowSize = FRAMES_1|FRAMES_2|FRAMES_3;
+ LocalQos.bfBofs = BOFS_3;
+ LocalQos.bfMinTurnTime = MIN_TAT_10;
+ LocalQos.bfDisconnectTime = DISC_TIME_12;
+
+ Val = DISCOVERY_HINT_CHARSET;
+
+ // Build the discovery info
+ DscvInfoLen = 0;
+ for (i = 0, Mask = 0xFF000000; i < 4; i++, Mask >>= 8)
+ {
+ if (Mask & Val || DscvInfoLen > 0)
+ {
+ DscvInfoBuf[DscvInfoLen++] = (BYTE) ((Mask & Val) >> (8 * (3-i)));
+ }
+ }
+ memcpy(DscvInfoBuf+DscvInfoLen, DISCOVERY_NICKNAME, DISCOVERY_NICKNAME_LEN);
+ DscvInfoLen += DISCOVERY_NICKNAME_LEN;
+ // TEMP ******************************************************
+ // *******************************************************
+
+ DEBUGMSG(1, ("+IrdaBindAdapter() \"%ws\", BindContext %x\n",
+ AdapterName->Buffer, BindContext));
+
+ NdisAllocateMemory((PVOID *)&pIrdaLinkCb, sizeof(IRDA_LINK_CB), 0, pa);
+
+ if (!pIrdaLinkCb)
+ {
+ *pStatus = STATUS_INSUFFICIENT_RESOURCES;
+ goto exit10;
+ }
+
+ NdisZeroMemory(pIrdaLinkCb, sizeof(IRDA_LINK_CB));
+ // Add a signature
+ NdisInitializeEvent(&pIrdaLinkCb->SyncEvent);
+ NdisResetEvent(&pIrdaLinkCb->SyncEvent);
+ NdisAllocateSpinLock(&pIrdaLinkCb->SpinLock);
+
+ NdisAllocateBufferPool(pStatus,
+ &pIrdaLinkCb->BufferPool,
+ IRDA_NDIS_BUFFER_POOL_SIZE);
+ if (*pStatus != NDIS_STATUS_SUCCESS)
+ {
+ DEBUGMSG(DBG_ERROR, ("NdisAllocateBufferPool failed\n"));
+ goto error10; // free pIrdaLinkCB
+ }
+
+ NdisAllocatePacketPool(pStatus,
+ &pIrdaLinkCb->PacketPool,
+ IRDA_NDIS_PACKET_POOL_SIZE,
+ sizeof(IRDA_PROTOCOL_RESERVED)-1 + \
+ sizeof(NDIS_IRDA_PACKET_INFO));
+ if (*pStatus != NDIS_STATUS_SUCCESS)
+ {
+ DEBUGMSG(DBG_ERROR, ("NdisAllocatePacketPool failed\n"));
+ goto error20; // free pIrdaLinkCb, Buffer pool
+ }
+
+ NdisInitializeListHead(&pIrdaLinkCb->IMsgList);
+
+ // For internally generated LAP messages
+ pIrdaLinkCb->IMsgListLen = 0;
+ for (i = 0; i < IRDA_MSG_LIST_LEN; i++)
+ {
+ NdisAllocateMemory(&pIMsg, sizeof(IRDA_MSG) + IRDA_MSG_DATA_SIZE,
+ 0, pa);
+ if (pIMsg == NULL)
+ {
+ *pStatus = STATUS_INSUFFICIENT_RESOURCES;
+ goto error40;
+ }
+ NdisInterlockedInsertTailList(&pIrdaLinkCb->IMsgList,
+ &pIMsg->Linkage,
+ &pIrdaLinkCb->SpinLock);
+ pIrdaLinkCb->IMsgListLen++;
+ }
+
+ NdisOpenAdapter(
+ pStatus,
+ &OpenErrorStatus,
+ &pIrdaLinkCb->NdisBindingHandle,
+ &SelectedMediumIndex,
+ MediumArray,
+ 1,
+ NdisIrdaHandle,
+ pIrdaLinkCb,
+ AdapterName,
+ 0,
+ NULL);
+
+ DEBUGMSG(DBG_NDIS, ("NdisOpenAdapter(), status %x\n",
+ pIrdaLinkCb->NdisBindingHandle, *pStatus));
+
+ if (*pStatus == NDIS_STATUS_PENDING)
+ {
+ NdisWaitEvent(&pIrdaLinkCb->SyncEvent, 0);
+ *pStatus = pIrdaLinkCb->SyncStatus;
+ }
+
+ if (*pStatus != NDIS_STATUS_SUCCESS)
+ {
+ goto error30; // free pIrdaLinkCb, Buffer pool, Packet pool
+ }
+
+ // Query adapters capabilities
+
+ UintArrayCnt = sizeof(UintArray)/sizeof(UINT);
+ *pStatus = IrdaQueryOid(pIrdaLinkCb,
+ OID_IRDA_SUPPORTED_SPEEDS,
+ UintArray, &UintArrayCnt);
+ if (*pStatus != NDIS_STATUS_SUCCESS)
+ {
+ DEBUGMSG(DBG_ERROR,
+ ("Query IRDA_SUPPORTED_SPEEDS failed %x\n",
+ *pStatus));
+ goto error30;
+ }
+
+ OidToLapQos(vBaudTable,
+ UintArray,
+ UintArrayCnt,
+ &LocalQos.bfBaud);
+
+ UintArrayCnt = sizeof(UintArray)/sizeof(UINT);
+ *pStatus = IrdaQueryOid(pIrdaLinkCb,
+ OID_IRDA_TURNAROUND_TIME,
+ UintArray, &UintArrayCnt);
+
+ if (*pStatus != NDIS_STATUS_SUCCESS)
+ {
+ DEBUGMSG(DBG_ERROR,
+ ("Query IRDA_SUPPORTED_SPEEDS failed %x\n",
+ *pStatus));
+ goto error30;
+ }
+
+ OidToLapQos(vMinTATTable,
+ UintArray,
+ UintArrayCnt,
+ &LocalQos.bfMinTurnTime);
+
+ IrlapOpenLink(pStatus,
+ pIrdaLinkCb,
+ &LocalQos,
+ DscvInfoBuf,
+ DscvInfoLen,
+ DISCOVERY_SLOTS);
+
+ if (*pStatus != STATUS_SUCCESS)
+ {
+ goto error30;
+ }
+
+ InsertTailList(&IrdaLinkCbList, &pIrdaLinkCb->Linkage);
+
+ goto exit10;
+
+error40:
+
+ pIMsg = (IRDA_MSG *) NdisInterlockedRemoveHeadList(
+ &pIrdaLinkCb->IMsgList, &pIrdaLinkCb->SpinLock);
+
+ while (pIMsg != NULL)
+ {
+ NdisFreeMemory(pIMsg, sizeof(IRDA_MSG) + IRDA_MSG_DATA_SIZE, 0);
+ pIMsg = (IRDA_MSG *) NdisInterlockedRemoveHeadList(
+ &pIrdaLinkCb->IMsgList, &pIrdaLinkCb->SpinLock);
+ pIMsg = (IRDA_MSG *) RemoveHeadList(&pIrdaLinkCb->IMsgList);
+ }
+
+error30:
+ NdisFreePacketPool(pIrdaLinkCb->PacketPool);
+
+error20:
+ NdisFreeBufferPool(pIrdaLinkCb->BufferPool);
+
+error10:
+
+ NdisFreeMemory(pIrdaLinkCb, sizeof(IRDA_LINK_CB), 0);
+
+exit10:
+ DEBUGMSG(DBG_NDIS, ("-IrdaBindAdapter() status %x\n",
+ *pStatus));
+
+ return;
+}
+
+VOID IrdaUnbindAdapter(
+ OUT PNDIS_STATUS pStatus,
+ IN NDIS_HANDLE IrdaBindingContext,
+ IN NDIS_HANDLE UnbindContext
+ )
+{
+ PIRDA_LINK_CB pIrdaLinkCb = (PIRDA_LINK_CB) IrdaBindingContext;
+
+ DEBUGMSG(DBG_NDIS, ("+IrdaUnbindAdapter()\n"));
+
+ NdisInitializeEvent(&pIrdaLinkCb->SyncEvent);
+ NdisResetEvent(&pIrdaLinkCb->SyncEvent);
+
+ NdisCloseAdapter(pStatus, pIrdaLinkCb->NdisBindingHandle);
+
+ if(*pStatus == NDIS_STATUS_PENDING)
+ {
+ NdisWaitEvent(&pIrdaLinkCb->SyncEvent, 0);
+ *pStatus = pIrdaLinkCb->SyncStatus;
+ }
+
+ if (*pStatus == NDIS_STATUS_SUCCESS){
+ NdisFreeMemory(pIrdaLinkCb, sizeof(IRDA_LINK_CB), 0);
+ }
+
+ DEBUGMSG(DBG_NDIS, ("-IrdaUnbindAdapter() Status %x\n",
+ *pStatus));
+
+ return;
+}
+
+VOID IrdaUnload(
+ VOID
+ )
+{
+ DEBUGMSG(DBG_NDIS, ("+IrdaUnload()\n"));
+
+ return;
+}
+
+NTSTATUS IrdaNdisInitialize()
+{
+ NDIS_STATUS Status;
+ NDIS40_PROTOCOL_CHARACTERISTICS pc;
+ NDIS_STRING ProtocolName = NDIS_STRING_CONST("IRDA");
+ UINT ProtocolReservedLength;
+
+ DEBUGMSG(DBG_NDIS,("+IrdaNdisInitialize()\n"));
+
+ NdisZeroMemory((PVOID)&pc, sizeof(NDIS40_PROTOCOL_CHARACTERISTICS));
+ pc.MajorNdisVersion = 0x04;
+ pc.MinorNdisVersion = 0x00;
+ pc.OpenAdapterCompleteHandler = IrdaOpenAdapterComplete;
+ pc.CloseAdapterCompleteHandler = IrdaCloseAdapterComplete;
+ pc.SendCompleteHandler = IrdaSendComplete;
+ pc.TransferDataCompleteHandler = IrdaTransferDataComplete;
+ pc.ResetCompleteHandler = IrdaResetComplete;
+ pc.RequestCompleteHandler = IrdaRequestComplete;
+ pc.ReceiveHandler = IrdaReceive;
+ pc.ReceiveCompleteHandler = IrdaReceiveComplete;
+ pc.StatusHandler = IrdaStatus;
+ pc.StatusCompleteHandler = IrdaStatusComplete;
+ pc.BindAdapterHandler = IrdaBindAdapter;
+ pc.UnbindAdapterHandler = IrdaUnbindAdapter;
+ pc.UnloadHandler = IrdaUnload;
+ pc.Name = ProtocolName;
+ pc.ReceivePacketHandler = IrdaReceivePacket;
+ pc.TranslateHandler = NULL;
+
+ NdisRegisterProtocol(&Status,
+ &NdisIrdaHandle,
+ (PNDIS_PROTOCOL_CHARACTERISTICS)&pc,
+ sizeof(NDIS40_PROTOCOL_CHARACTERISTICS));
+
+ // Do any LAP/LMP initialization here
+
+ DEBUGMSG(DBG_NDIS, ("-IrdaNdisInitialize(), rc %x\n", Status));
+
+ return Status;
+}
+
+UINT
+MacConfigRequest(
+ PIRDA_LINK_CB pIrdaLinkCb,
+ PIRDA_MSG pMsg)
+{
+ switch (pMsg->IRDA_MSG_Op)
+ {
+ case MAC_INITIALIZE_LINK:
+ case MAC_RECONFIG_LINK:
+ pIrdaLinkCb->ExtraBofs = pMsg->IRDA_MSG_NumBOFs;
+ pIrdaLinkCb->MinTat = pMsg->IRDA_MSG_MinTat;
+ return IrdaSetOid(pIrdaLinkCb,
+ OID_IRDA_LINK_SPEED,
+ (UINT) pMsg->IRDA_MSG_Baud);
+
+ case MAC_MEDIA_SENSE:
+ ASSERT(0);
+
+ }
+
+ return SUCCESS;
+
+}
+UINT IrmacDown(
+ IN PVOID Context,
+ PIRDA_MSG pMsg)
+{
+ NDIS_STATUS Status;
+ PNDIS_PACKET NdisPacket = NULL;
+ PNDIS_BUFFER NdisBuffer = NULL;
+ PIRDA_PROTOCOL_RESERVED ProtocolReserved;
+ PNDIS_IRDA_PACKET_INFO IrdaPacketInfo;
+ PIRDA_LINK_CB pIrdaLinkCb = (PIRDA_LINK_CB) Context;
+
+ DEBUGMSG(DBG_FUNCTION, ("+IrmacDown()\n"));
+
+
+ if (pMsg->Prim == MAC_CONTROL_REQ)
+ {
+ return MacConfigRequest(pIrdaLinkCb, pMsg);
+ }
+
+ NdisAllocatePacket(&Status, &NdisPacket, pIrdaLinkCb->PacketPool);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ return 1;
+ }
+
+ NdisAllocateBuffer(&Status, &NdisBuffer, pIrdaLinkCb->PacketPool,
+ pMsg->IRDA_MSG_pHdrRead,
+ pMsg->IRDA_MSG_pHdrWrite-pMsg->IRDA_MSG_pHdrRead);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ return 1;
+ }
+ NdisChainBufferAtFront(NdisPacket, NdisBuffer);
+
+ NdisAllocateBuffer(&Status, &NdisBuffer, pIrdaLinkCb->PacketPool,
+ pMsg->IRDA_MSG_pRead,
+ pMsg->IRDA_MSG_pWrite-pMsg->IRDA_MSG_pRead);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ return 1;
+ }
+ NdisChainBufferAtBack(NdisPacket, NdisBuffer);
+
+ ProtocolReserved = (PIRDA_PROTOCOL_RESERVED)(NdisPacket->ProtocolReserved);
+
+ ProtocolReserved->pIMsg = pMsg;
+
+ IrdaPacketInfo = (PNDIS_IRDA_PACKET_INFO) \
+ (ProtocolReserved->MediaInfo.ClassInformation);
+
+ IrdaPacketInfo->ExtraBOFs = pIrdaLinkCb->ExtraBofs;
+ IrdaPacketInfo->MinTurnAroundTime = pIrdaLinkCb->MinTat;
+
+ NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(NdisPacket,
+ &ProtocolReserved->MediaInfo,
+ sizeof(MEDIA_SPECIFIC_INFORMATION) -1 +
+ sizeof(NDIS_IRDA_PACKET_INFO));
+ NdisSend(&Status, pIrdaLinkCb->NdisBindingHandle, NdisPacket);
+
+ return 0;
+}
diff --git a/private/ntos/tdi/irda/driver/makefile b/private/ntos/tdi/irda/driver/makefile
new file mode 100644
index 000000000..58189757d
--- /dev/null
+++ b/private/ntos/tdi/irda/driver/makefile
@@ -0,0 +1,7 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the driver components of the Windows NT DDK
+#
+
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ntos/tdi/irda/driver/sources b/private/ntos/tdi/irda/driver/sources
new file mode 100644
index 000000000..70d52d5e4
--- /dev/null
+++ b/private/ntos/tdi/irda/driver/sources
@@ -0,0 +1,15 @@
+TARGETNAME=irda
+TARGETPATH=$(BASEDIR)\public\sdk\lib
+TARGETTYPE=DRIVER
+
+TARGETLIBS= \
+ $(BASEDIR)\public\sdk\lib\*\ndis.lib \
+ $(BASEDIR)\public\sdk\lib\*\tdi.lib \
+ ..\lib\*\irlap.lib
+
+INCLUDES=$(BASEDIR)\private\inc;$(BASEDIR)\private\ntos\inc;..\..\inc;..\inc
+
+C_DEFINES=$(C_DEFINES) -DNT -D_NTDRIVER_ -DIRDA
+
+SOURCES= irda.c \
+ irndis.c
diff --git a/private/ntos/tdi/irda/inc/af_irda.h b/private/ntos/tdi/irda/inc/af_irda.h
new file mode 100644
index 000000000..5e5d36b0d
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/af_irda.h
@@ -0,0 +1,100 @@
+//
+// this is the header file that describes the IRDA address family
+//
+// CREATED 4/28: AldenG
+//
+
+#ifndef __AFIRDA__
+#define __AFIRDA__
+
+#include <winsock.h>
+
+#define AF_IRDA 22 // see winsock.h
+#define PF_IRDA AF_IRDA
+
+#define SOL_IRLMP 0x00FF
+
+#define IRLMP_ENUMDEVICES 0x00000010
+#define IRLMP_IAS_SET 0x00000011
+#define IRLMP_IAS_QUERY 0x00000012
+#define IRLMP_SEND_PDU_LEN 0x00000013
+#define IRLMP_EXCLUSIVE_MODE 0x00000014
+#define IRLMP_IRLPT_MODE 0x00000015
+#define IRLMP_9WIRE_MODE 0x00000016
+
+#define IAS_ATTRIB_NO_CLASS 0x00000010
+#define IAS_ATTRIB_NO_ATTRIB 0x00000000
+#define IAS_ATTRIB_INT 0x00000001
+#define IAS_ATTRIB_OCTETSEQ 0x00000002
+#define IAS_ATTRIB_STR 0x00000003
+
+typedef struct _SOCKADDR_IRDA
+{
+ u_short irdaAddressFamily;
+ u_char irdaDeviceID[4];
+ char irdaServiceName[25];
+} SOCKADDR_IRDA, *PSOCKADDR_IRDA;
+
+typedef struct _IRDA_DEVICE_INFO
+{
+ u_char irdaDeviceID[4];
+ char irdaDeviceName[22];
+ u_char Reserved[2];
+} IRDA_DEVICE_INFO, *PIRDA_DEVICE_INFO, FAR *LPIRDA_DEVICE_INFO;
+
+typedef struct _DEVICELIST
+{
+ ULONG numDevice;
+ IRDA_DEVICE_INFO Device[1];
+} DEVICELIST, *PDEVICELIST, FAR *LPDEVICELIST;
+
+typedef struct _IAS_SET
+{
+ char irdaClassName[61];
+ char irdaAttribName[61];
+ u_short irdaAttribType;
+ union
+ {
+ int irdaAttribInt;
+ struct
+ {
+ int Len;
+ u_char OctetSeq[1];
+ u_char Reserved[3];
+ } irdaAttribOctetSeq;
+ struct
+ {
+ int Len;
+ u_char CharSet;
+ u_char UsrStr[1];
+ u_char Reserved[2];
+ } irdaAttribUsrStr;
+ } irdaAttribute;
+} IAS_SET, *PIAS_SET, FAR *LPIAS_SET;
+
+typedef struct _IAS_QUERY
+{
+ u_char irdaDeviceID[4];
+ char irdaClassName[61];
+ char irdaAttribName[61];
+ u_short irdaAttribType;
+ union
+ {
+ int irdaAttribInt;
+ struct
+ {
+ int Len;
+ u_char OctetSeq[1];
+ u_char Reserved[3];
+ } irdaAttribOctetSeq;
+ struct
+ {
+ int Len;
+ u_char CharSet;
+ u_char UsrStr[1];
+ u_char Reserved[2];
+ } irdaAttribUsrStr;
+ } irdaAttribute;
+} IAS_QUERY, *PIAS_QUERY, FAR *LPIAS_QUERY;
+
+#endif // __AFIRDA__
diff --git a/private/ntos/tdi/irda/inc/decdirda.h b/private/ntos/tdi/irda/inc/decdirda.h
new file mode 100644
index 000000000..d93b0d9e3
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/decdirda.h
@@ -0,0 +1,174 @@
+// returns pointers pOutStr
+TCHAR *DecodeIRDA(int *pFrameType,// return frame type (-1 = bad frame)
+ BYTE *pFrameBuf, // pointer to buffer containing IRLAP frame
+ UINT FrameLen, // length of buffer
+ TCHAR *pOutStr, // string where decode packet is placed
+ UINT DecodeLayer,// 2-LAP only, 3-LAP/LMP, 4-LAP/LMP/TTP
+ BOOL fNoConnAddr,// TRUE->Don't show connection address in str
+ int DispMode // DISP_ASCII/HEX/BOTH
+);
+
+#define DISP_ASCII 1
+#define DISP_HEX 2
+#define DISP_BOTH 3
+
+extern int BaudBitMask;
+
+#define IRLAP_BOF 0xC0
+#define IRLAP_EOF 0xC1
+#define IRLAP_ESC 0x7D
+#define IRLAP_COMP_BIT 0x20
+
+#define IRLAP_BROADCAST 0xfe
+#define _IRLAP_CMD 0x01
+#define _IRLAP_RSP 0x00
+
+#define IRLAP_I_FRM 0x00
+#define IRLAP_S_FRM 0x01
+#define IRLAP_U_FRM 0x03
+
+/*
+** Unnumbered Frame types with P/F bit set to 0
+*/
+#define IRLAP_UI 0x03
+#define IRLAP_XID_CMD 0x2f
+#define IRLAP_TEST 0xe3
+#define IRLAP_SNRM 0x83
+#define IRLAP_DISC 0x43
+#define IRLAP_UA 0x63
+#define IRLAP_FRMR 0x87
+#define IRLAP_DM 0x0f
+#define IRLAP_XID_RSP 0xaf
+
+/*
+** Supervisory Frames
+*/
+#define IRLAP_RR 0x01
+#define IRLAP_RNR 0x05
+#define IRLAP_REJ 0x09
+#define IRLAP_SREJ 0x0d
+
+
+#define IRLAP_GET_ADDR(addr) (addr >> 1)
+#define IRLAP_GET_CRBIT(addr) (addr & 1)
+#define IRLAP_GET_PFBIT(cntl) ((cntl >>4) & 1)
+#define IRLAP_GET_UCNTL(cntl) (cntl & 0xEF)
+#define IRLAP_GET_SCNTL(cntl) (cntl & 0x0F)
+#define IRLAP_FRAME_TYPE(cntl) (cntl & 0x01 ? (cntl & 3) : 0)
+#define IRLAP_GET_NR(cntl) ((cntl & 0xE0) >> 5)
+#define IRLAP_GET_NS(cntl) ((cntl & 0xE) >> 1)
+
+/*
+** XID stuff
+*/
+#define XID_DISCV_FORMAT_ID 0x01
+#define XID_NEGPARMS_FORMAT_ID 0x02
+
+typedef struct
+{
+ BYTE SrcAddr[4];
+ BYTE DestAddr[4];
+ BYTE NoOfSlots:2;
+ BYTE GenNewAddr:1;
+ BYTE Reserved:5;
+ BYTE SlotNo;
+ BYTE Version;
+} XID_DISCV_FORMAT;
+
+/*
+** SNRM
+*/
+typedef struct
+{
+ BYTE SrcAddr[4];
+ BYTE DestAddr[4];
+ BYTE ConnAddr;
+ BYTE FirstPI;
+} SNRM_FORMAT;
+
+/*
+** UA
+*/
+typedef struct
+{
+ BYTE SrcAddr[4];
+ BYTE DestAddr[4];
+ BYTE FirstPI;
+} UA_FORMAT;
+
+/*
+** LM-PDU stuff
+*/
+typedef struct
+{
+ BYTE DLSAP_SEL:7;
+ BYTE CntlBit:1;
+ BYTE SLSAP_SEL:7;
+ BYTE RsvrdBi1:1;
+} LM_HEADER;
+
+/* LM-PDU frame types */
+#define LM_PDU_CNTL_FRAME 1
+#define LM_PDU_DATA_FRAME 0
+
+typedef struct
+{
+ BYTE OpCode:7;
+ BYTE ABit:1;
+} LM_CNTL_FORMAT;
+
+/* Opcodes */
+#define LM_PDU_CONNECT 1
+#define LM_PDU_DISCONNECT 2
+#define LM_PDU_ACCESSMODE 3
+
+#define LM_PDU_REQUEST 0
+#define LM_PDU_CONFIRM 1
+
+#define LM_PDU_SUCCESS 0
+#define LM_PDU_FAILURE 1
+#define LM_PDU_UNSUPPORTED 0xFF
+
+#define LM_PDU_MULTIPLEXED 0
+#define LM_PDU_EXCLUSIVE 1
+
+/* Max disconnect reason code, see _LM_PDU_DscReason[] in decdirda.c */
+#define LM_PDU_MAX_DSC_REASON 0x8
+
+/*
+** Negotiation Parameter Identifiers
+*/
+#define NEG_PI_BAUD 0x01
+#define NEG_PI_MAX_TAT 0x82
+#define NEG_PI_DATA_SZ 0x83
+#define NEG_PI_WIN_SZ 0x84
+#define NEG_PI_BOFS 0x85
+#define NEG_PI_MIN_TAT 0x86
+#define NEG_PI_DISC_THRESH 0x08
+
+// Tiny TP!
+
+#define TTP_PFLAG_NO_PARMS 0
+#define TTP_PFLAG_PARMS 1
+
+#define TTP_MBIT_NOT_FINAL 1
+#define TTP_MBIT_FINAL 0
+
+typedef struct
+{
+ BYTE InitialCredit : 7;
+ BYTE ParmFlag : 1;
+} TTP_CONN_HEADER;
+
+typedef struct
+{
+ BYTE AdditionalCredit : 7;
+ BYTE MoreBit : 1;
+} TTP_DATA_HEADER;
+
+#define net_short(x) ((((x)&0xff) << 8) | (((x)&0xff00) >> 8))
+
+#define net_long(x) (((((DWORD UNALIGNED)(x))&0xffL)<<24) | \
+ ((((DWORD UNALIGNED)(x))&0xff00L)<<8) | \
+ ((((DWORD UNALIGNED)(x))&0xff0000L)>>8) | \
+ ((((DWORD UNALIGNED)(x))&0xff000000L)>>24))
diff --git a/private/ntos/tdi/irda/inc/irda.h b/private/ntos/tdi/irda/inc/irda.h
new file mode 100644
index 000000000..ab9d55674
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/irda.h
@@ -0,0 +1,857 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: irda.h
+*
+* Description: Definitions used across the IRDA stack
+*
+* Author: mbert
+*
+* Date: 4/15/95
+*
+* This file primarily defines the IRDA message (IRDA_MSG) used for
+* communicating with the stack and communication between the layers
+* of the stack. IRDA_MSG provides the following services:
+* MAC_CONTROL_SERVICE
+* IRLAP_DISCOVERY_SERVICE
+* IRDA_DISCONNECT_SERVICE
+* IRDA_CONNECT_SERVICE
+* IRDA_DATA_SERVICE
+* IRLMP_ACCESSMODE_SERVICE
+* IRLMP_IAS_SERVICE
+*
+* IRDA_MSG usage:
+*
+* +-------+
+* | IRLAP |
+* +-------+
+* |
+* | IRMAC_Down(IRDA_MSG)
+* \|/
+* +-------+
+* | IRMAC |
+* +-------+
+* |**************************************************************************|
+* | Prim | MsgType and parameters |
+* |==========================================================================|
+* | MAC_DATA_REQ | IRDA_DATA_SERVICE |
+* | | o IRDA_MSG_pHdrRead = start of IRDA headers |
+* | | o IRDA_MSG_pHdrWrite = end of header |
+* | | o IRDA_MSG_pRead = start of data |
+* | | o IRDA_MSG_pWrite = end of data |
+* |--------------------------+-----------------------------------------------|
+* | MAC_CONTROL_REQ | MAC_CONTROL_SERVICE |
+* | | o IRDA_MSG_Op = MAC_INITIALIZIE_LINK |
+* | | - IRDA_MSG_Port |
+* | | - IRDA_MSG_Baud |
+* | | - IRDA_MSG_MinTat = min turn time |
+* | | - IRDA_MSG_NumBOFs = # added when tx'ing |
+* | | - IRDA_MSG_DataSize = max rx frame |
+* | | - IRDA_MSG_SetIR = TRUE/FALSE (does an |
+* | | EscapeComm(SETIR) to select int/ext |
+* | | dongle) |
+* | | o IRDA_MSG_Op = MAC_MEDIA_SENSE |
+* | | - IRDA_MSG_SenseTime (in ms) |
+* | | o IRDA_MSG_Op = MAC_RECONFIG_LINK |
+* | | - IRDA_MSG_Baud |
+* | | - IRDA_MSG_NumBOFs = # added when tx'ing |
+* | | - IRDA_MSG_DataSize = max rx frame |
+* | | - IRDA_MSG_MinTat = min turn time |
+* | | o IRDA_MSG_OP = MAC_SHUTDOWN_LINK |
+* |--------------------------------------------------------------------------|
+*
+* +-------+
+* | IRLAP |
+* +-------+
+* /|\
+* | IRLAP_Up(IRDA_MSG)
+* |
+* +-------+
+* | IRMAC |
+* +-------+
+* |**************************************************************************|
+* | Prim | MsgType and parameters |
+* |==========================================================================|
+* | MAC_DATA_IND | IRDA_DATA_SERVICE |
+* | | o IRDA_MSG_pRead = start of frame |
+* | | (includes IRLAP header) |
+* | | o IRDA_MSG_pWrite = end of frame |
+* | | (excludes FCS) |
+* |--------------------------+-----------------------------------------------|
+* | MAC_CONTROL_CONF | MAC_CONTROL_SERVICE |
+* | | o IRDA_MSG_Op = MAC_MEDIA_SENSE |
+* | | - IRDA_MSG_OpStatus = MAC_MEDIA_BUSY |
+* | | MAC_MEDIA_CLEAR |
+* |--------------------------------------------------------------------------|
+*
+* +-------+
+* | IRLMP |
+* +-------+
+* |
+* | IRLAP_Down(IRDA_MSG)
+* \|/
+* +-------+
+* | IRLAP |
+* +-------+
+* |**************************************************************************|
+* | Prim | MsgType and parameters |
+* |==========================================================================|
+* | IRLAP_DISCOVERY_REQ | IRLAP_DISCOVERY_SERVICE |
+* | IRLAP_Down() returns | o IRDA_MSG_SenseMedia = TRUE/FALSE |
+* | IRLAP_REMOTE_DISCOVERY_IN_PROGRESS_ERR or |
+* | IRLAP_REMOTE_CONNECT_IN_PROGRESS_ERR when indicated |
+* |--------------------------+-----------------------------------------------|
+* | IRLAP_CONNECT_REQ | IRDA_CONNECT_SERVICE |
+* | | o IRDA_MSG_RemoteDevAddr |
+* | IRLAP_Down() returns | |
+* | IRLAP_REMOTE_DISCOVERY_IN_PROGRESS_ERR when indicated |
+* |--------------------------+-----------------------------------------------|
+* | IRLAP_CONNECT_RESP | no parms |
+* |--------------------------+-----------------------------------------------|
+* | IRLAP_DISCONNECT_REQ | no parms |
+* |--------------------------+-----------------------------------------------|
+* | IRLAP_DATA_REQ | IRDA_DATA_SERVICE |
+* | IRLAP_UDATA_REQ | o IRDA_MSG_pHdrRead = start of IRLMP header |
+* | IRLAP_Down() returns | o IRDA_MSG_pHdrWrite = end of header |
+* | IRLAP_REMOTE_BUSY to | o IRDA_MSG_pRead = start of data |
+* | to flow off LMP. | o IRDA_MSG_pWrite = end of data |
+* |--------------------------------------------------------------------------|
+* | IRLAP_FLOWON_REQ | no parms |
+* |--------------------------------------------------------------------------|
+*
+* +-------+
+* | IRLMP |
+* +-------+
+* /|\
+* | IRLMP_Up(IRDA_MSG)
+* |
+* +-------+
+* | IRLAP |
+* +-------+
+* |**************************************************************************|
+* | Prim | MsgType and parameters |
+* |==========================================================================|
+* | IRLAP_DISCOVERY_IND | IRLAP_DISCOVERY_SERVICE |
+* | | o pDevList = Discovery info of device that |
+* | | initiated discovery |
+* |--------------------------+-----------------------------------------------|
+* | IRLAP_DISCOVERY_CONF | IRLAP_DISCOVERY_SERVICE |
+* | | o IRDA_MSG_pDevList = list of discovered |
+* | | devices, NULL when |
+* | | status != IRLAP_DISCOVERY_COMPLETED |
+* | | o IRDA_MSG_DscvStatus = |
+* | | MAC_MEDIA_BUSY |
+* | | IRLAP_REMOTE_DISCOVERY_IN_PROGRESS |
+* | | IRLAP_DISCOVERY_COLLISION |
+* | | IRLAP_REMOTE_CONNECTION_IN_PROGRESS |
+* | | IRLAP_DISCOVERY_COMPLETED |
+* |--------------------------+-----------------------------------------------|
+* | IRLAP_CONNECT_IND | IRDA_CONNECT_SERVICE |
+* | | o IRDA_MSG_RemoteDevAddr |
+* | | o IRDA_MSG_pQOS = Negotiated QOS |
+* |--------------------------------------------------------------------------|
+* | IRLAP_CONNECT_CONF | IRDA_CONNECT_SERVICE |
+* | | o IRDA_MSG_pQOS = Negotiated QOS, only when |
+* | | successful |
+* | | o IRDA_MSG_ConnStatus = |
+* | | IRLAP_CONNECTION_COMPLETE |
+* |--------------------------+-----------------------------------------------|
+* | IRLAP_DISCONNECT_IND | IRDA_DISCONNECT_SERVICE |
+* | | o IRDA_MSG_DiscStatus = |
+* | | IRLAP_DISCONNECT_COMPLETED |
+* | | IRLAP_REMOTED_INITIATED |
+* | | IRLAP_PRIMARY_CONFLICT |
+* | | IRLAP_REMOTE_DISCOVERY_IN_PROGRESS |
+* | | IRLAP_NO_RESPONSE |
+* | | IRLAP_DECLINE_RESET |
+* | | MAC_MEDIA_BUSY |
+* |--------------------------+-----------------------------------------------|
+* | IRLAP_DATA_IND | IRDA_DATA_SERVICE |
+* | IRLAP_UDATA_IND | o IRDA_MSG_pRead = start of IRLMP packet |
+* | | o IRDA_MSG_pWrite = end of IRLMP packet |
+* |--------------------------+-----------------------------------------------|
+* | IRLAP_DATA_CONF | IRDA_DATA_SERVICE |
+* | IRLAP_UDATA_CONF | o IRDA_MSG_DataStatus = |
+* | | ILAP_DATA_REQUEST_COMPLETED |
+* | | IRLAP_DATA_REQUEST_FAILED_LINK_RESET |
+* |--------------------------+-----------------------------------------------|
+* | IRLAP_STATUS_IND | no parms |
+* |--------------------------------------------------------------------------|
+*
+* +--------------+
+* | TransportAPI |
+* +--------------+
+* |
+* | IRLMP_Down(IRLMPContext, IRDA_MSG)
+* \|/
+* +-------+
+* | IRLMP |
+* +-------+
+* |**************************************************************************|
+* | Prim | MsgType and parameters |
+* |==========================================================================|
+* | IRLMP_DISCOVERY_REQ | no parms |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_CONNECT_REQ | IRDA_CONNECT_SERVICE |
+* | IRLMP_Down() returns | o IRDA_MSG_RemoteDevAddr |
+* | IRLMP_LINK_IN_USE | o IRDA_MSG_RemoteLSAPSel |
+* | when the requested | o IRDA_MSG_pQOS (may be NULL) |
+* | connection is to a | o IRDA_MSG_pConnData |
+* | remote device other | o IRDA_MSG_ConnDataLen |
+* | than the one the link | o IRDA_MSG_LocalLSAPSel |
+* | is currently connected | o IRDA_MSG_pContext |
+* | or connecting to. | o IRDA_MSG_UseTTP |
+* | | o IRDA_MSG_TTPCredits |
+* | | o IRDA_MSG_MaxSDUSize - Max size that this |
+* | | IRLMP client can receive. |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_CONNECT_RESP | IRDA_CONNECT_SERVICE |
+* | | o IRDA_MSG_pConnData |
+* | | o IRDA_MSG_ConnDataLen |
+* | | o IRDA_MSG_pContext |
+* | | o IRDA_MSG_MaxSDUSize - Max size that this |
+* | | IRLMP client can receive. |
+* | | o IRDA_MSG_TTPCredits |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_DISCONNECT_REQ | IRDA_DISCONNECT_SERVICE |
+* | | o IRDA_MSG_pDiscData |
+* | | o IRDA_MSG_DiscDataLen |
+* | | |
+* | | |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_DATA/UDATA_REQ | IRDA_DATA_SERVICE |
+* | IRLMP_Down() may return| o IRDA_MSG_pDataContext = ptr to NDIS_BUFFER|
+* | IRLMP_REMOTE_BUSY, | o IRDA_MSG_IrCOMM_9Wire = TRUE/FALSE |
+* | when tx cred exhausted| |
+* | in multiplexed mode. | |
+* | IRLAP_REMOTE_BUSY, | |
+* | when remote IRLAP | |
+* | flowed off in exclMode| |
+* | In either case the req | |
+* | was successful. | |
+* |--------------------------------------------------------------------------|
+* | IRLMP_ACCESSMODE_REQ | IRLMP_ACCESSMODE_SERVICE |
+* | IRLMP_Down() may return| o IRDA_MSG_AccessMode = IRLMP_MULTIPLEXED |
+* | IRLMP_IN_EXCLUSIVE_MODE| IRLMP_EXCLUSIVE |
+* | if already in excl-mode| o IRDA_MSG_IrLPTMode - TRUE, doesn't send |
+* | IRLMP_IN_MULTIPLEXED...| the Access PDU |
+* | if other LSAPs exist or| |
+* | requesting trans to this state when already in it. |
+* |--------------------------------------------------------------------------|
+* | IRLMP_FLOWON_REQ | no parms |
+* |--------------------------------------------------------------------------|
+* | IRLMP_MORECREDIT_REQ | IRDA_CONNECT_SERVICE (cuz parm is defined) |
+* | | o IRDA_MSG_TTPCredits |
+* |--------------------------------------------------------------------------|
+* | IRLMP_GETVALUEBYCLASS_REQ| IRDA_IAS_SERVICE |
+* | | o IRDA_MSG_pIASQuery |
+* | | o IRDA_MSG_AttribLen |
+* | | o IRDA_MSG_IASQueryPerms |
+* |--------------------------------------------------------------------------|
+*
+*
+* +--------------+
+* | TransportAPI |
+* +--------------+
+* /|\
+* | TransportAPI_Up(TransportAPIContext, IRDA_MSG)
+* |
+* +-------+
+* | IRLMP |
+* +-------+
+* |**************************************************************************|
+* | Prim | MsgType and parameters |
+* |==========================================================================|
+* | IRLAP_DISCOVERY_IND | IRLAP_DISCOVERY_SERVICE |
+* | | o pDevList = aged Discovery list |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_DISCOVERY_CONF | same as IRLAP_DISCOVERY_CONF. The device list |
+* | | however is the one maintained in IRLMP |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_DISCONNECT_IND | IRDA_DISCONNECT_SERVICE |
+* | | o IRDA_MSG_DiscReason = |
+* | | see IRLMP_DISC_REASON below |
+* | | o IRDA_MSG_pDiscData - may be NULL |
+* | | o IRDA_MSG_DiscDataLen |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_CONNECT_IND | IRDA_CONNECT_SERVICE |
+* | | o IRDA_MSG_RemoteDevAddr |
+* | | o IRDA_MSG_RemoteLSAPSel; |
+* | | o IRDA_MSG_LocalLSAPSel; |
+* | | o IRDA_MSG_pQOS |
+* | | o IRDA_MSG_pConnData |
+* | | o IRDA_MSG_ConnDataLen |
+* | | o IRDA_MSG_pContext |
+* | | o IRDA_MSG_MaxSDUSize - Max size that this |
+* | | IRLMP client can send to peer |
+* | | o IRDA_MSG_MaxPDUSize |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_CONNECT_CONF | IRDA_CONNECT_SERVICE |
+* | | o IRDA_MSG_pQOS |
+* | | o IRDA_MSG_pConnData |
+* | | o IRDA_MSG_ConnDataLen |
+* | | o IRDA_MSG_pContext |
+* | | o IRDA_MSG_MaxSDUSize - Max size that this |
+* | | IRLMP client can send to peer |
+* | | o IRDA_MSG_MaxPDUSize |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_DATA_IND | IRDA_DATA_SERVICE |
+* | | o IRDA_MSG_pRead = start of User Data |
+* | | o IRDA_MSG_pWrite = end of User Data |
+* | | o IRDA_MSG_FinalSeg = TRUE/FALSE |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_DATA_CONF | IRDA_DATA_SERVICE |
+* | | o IRDA_MSG_pDataContext = ptr to NDIS_BUFFER|
+* | | o IRDA_MSG_DataStatus = |
+* | | IRLMP_DATA_REQUEST_COMPLETED |
+* | | IRLMP_DATA_REQUEST_FAILED |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_ACCESSMODE_IND | IRLMP_ACCESSMODE_SERVICE |
+* | | o IRDA_MSG_AccessMode = |
+* | | IRLMP_EXCLUSIVE |
+* | | IRLMP_MULTIPLEXED |
+* |--------------------------+-----------------------------------------------|
+* | IRLMP_ACCESSMODE_CONF | IRLMP_ACCESSMODE_SERVICE |
+* | | o IRDA_MSG_AccessMode = |
+* | | IRLMP_EXCLUSIVE |
+* | | IRLMP_MULTIPLEXED |
+* | | o IRDA_MSG_ModeStatus = |
+* | | IRLMP_ACCESSMODE_SUCCESS |
+* | | IRLMP_ACCESSMODE_FAILURE |
+* |--------------------------+-----------------------------------------------|
+* |IRLMP_GETVALUEBYCLASS_CONF| IRDA_DATA_SERVICE |
+* | | o IRDA_MSG_pIASQuery |
+* | | o IRDA_MSG_IASStatus = An IRLMP_DISC_REASON |
+* | | (see below) |
+* |--------------------------------------------------------------------------|
+*/
+
+#include <nt.h>
+#include <ntos.h>
+#include <ntrtl.h>
+#include <nturtl.h>
+
+#include <windef.h>
+#include <winbase.h>
+#include <winsock.h>
+#include <wsahelp.h>
+#include <basetyps.h>
+
+#include <ndis.h>
+
+#include <af_irda.h>
+
+#include <cxport.h>
+
+#include <irerr.h>
+
+#include <tmp.h>
+
+#define TEMPERAMENTAL_SERIAL_DRIVER // drivers busted. intercharacter delays cause
+ // IrLAP to reset.
+
+#ifdef DEBUG
+// Prototypes for Debugging Output
+void IRDA_DebugOut (TCHAR *pFormat, ...);
+void IRDA_DebugStartLog (void);
+void IRDA_DebugEndLog (void *, void *);
+#endif
+
+// Debug zone definitions.
+/*
+#define ZONE_IRDA DEBUGZONE(0)
+#define ZONE_IRLAP DEBUGZONE(2)
+#ifdef PEG
+#define ZONE_IRMAC DEBUGZONE(1)
+#define ZONE_IRLMP DEBUGZONE(3)
+#define ZONE_IRLMP_CONN DEBUGZONE(4)
+#define ZONE_IRLMP_CRED DEBUGZONE(5)
+#else
+extern int ZONE_IRMAC;
+extern int ZONE_IRLMP;
+extern int ZONE_IRLMP_CONN;
+extern int ZONE_IRLMP_CRED;
+#endif
+#define ZONE_DISCOVER DEBUGZONE(8)
+#define ZONE_PRINT DEBUGZONE(9)
+#define ZONE_ADDR DEBUGZONE(10)
+#define ZONE_MISC DEBUGZONE(11)
+#define ZONE_ALLOC DEBUGZONE(12)
+#define ZONE_FUNCTION DEBUGZONE(13)
+#define ZONE_WARN DEBUGZONE(14)
+#define ZONE_ERROR DEBUGZONE(15)
+*/
+
+
+#define IRDA_ALLOC_MEM(ptr, sz, id) ((ptr) = CTEAllocMem(sz))
+#define IRDA_FREE_MEM(ptr) CTEFreeMem((ptr))
+
+//extern CRITICAL_SECTION IrdaCS;
+
+// Time how low we wait for the critical section
+/*
+#define ENTER_IRDA_WITH_CRITICAL_SECTION(s) do { \
+ LPWSTR Owner = IrdaCSOwner; \
+ DWORD StartTick = GetTickCount(); \
+ EnterCriticalSection (&IrdaCS); \
+ IrdaCSOwner = s; \
+ StartTick = GetTickCount() - StartTick; \
+ if (StartTick > MaxWaitIrdaCS) { \
+ DEBUGMSG (1, (TEXT("%s: IRDA Wait for CS %dms (Owner=%s)\r\n"), \
+ s, StartTick, Owner)); \
+ MaxWaitIrdaCS = StartTick; \
+ } \
+ } while (0)
+
+
+#define LEAVE_IRDA_WITH_CRITICAL_SECTION IrdaCSOwner = TEXT(""), LeaveCriticalSection(&IrdaCS)
+
+#else // TIME_CS
+#define ENTER_IRDA_WITH_CRITICAL_SECTION(s) EnterCriticalSection(&IrdaCS)
+
+#define LEAVE_IRDA_WITH_CRITICAL_SECTION LeaveCriticalSection(&IrdaCS)
+#endif // TIME_CS
+*/
+#define STATIC static
+
+#define RetOnErr(func) do {if((_rc = func) != SUCCESS) return _rc;} while(0)
+
+typedef struct
+{
+ CTETimer CteTimer;
+ VOID (*ExpFunc)(PVOID Context);
+ PVOID Context;
+ UINT Timeout;
+ BOOL Late;
+#ifdef DEBUG
+ char *pName;
+#endif
+} IRDA_TIMER, *PIRDA_TIMER;
+
+#define IRMAC_CONTEXT(ilcb) ((ilcb)->IrmacContext)
+#define IRLAP_CONTEXT(ilcb) ((ilcb)->IrlapContext)
+#define IRLMP_CONTEXT(ilcb) ((ilcb)->IrlmpContext)
+
+// Device/Discovery Information
+#define IRLAP_DSCV_INFO_LEN 32
+#define IRDA_DEV_ADDR_LEN 4
+
+typedef struct
+{
+ LIST_ENTRY Linkage;
+ BYTE DevAddr[IRDA_DEV_ADDR_LEN];
+ int DscvMethod;
+ int IRLAP_Version;
+ BYTE DscvInfo[IRLAP_DSCV_INFO_LEN];
+ int DscvInfoLen;
+ int NotSeenCnt; // used by IRLMP to determine when to remove
+ // the device from its list
+ PVOID LinkContext; // Link on which device was discovered
+} IRDA_DEVICE;
+
+// IRLAP Quality of Service
+#define BIT_0 1
+#define BIT_1 2
+#define BIT_2 4
+#define BIT_3 8
+#define BIT_4 16
+#define BIT_5 32
+#define BIT_6 64
+#define BIT_7 128
+#define BIT_8 256
+
+#define BPS_2400 BIT_0 // Baud Rates
+#define BPS_9600 BIT_1
+#define BPS_19200 BIT_2
+#define BPS_38400 BIT_3
+#define BPS_57600 BIT_4
+#define BPS_115200 BIT_5
+#define BPS_4000000 BIT_8
+
+#define MAX_TAT_500 BIT_0 // Maximum Turnaround Time (millisecs)
+#define MAX_TAT_250 BIT_1
+#define MAX_TAT_100 BIT_2
+#define MAX_TAT_50 BIT_3
+#define MAX_TAT_25 BIT_4
+#define MAX_TAT_10 BIT_5
+#define MAX_TAT_5 BIT_6
+
+#define DATA_SIZE_64 BIT_0 // Data Size (bytes)
+#define DATA_SIZE_128 BIT_1
+#define DATA_SIZE_256 BIT_2
+#define DATA_SIZE_512 BIT_3
+#define DATA_SIZE_1024 BIT_4
+#define DATA_SIZE_2048 BIT_5
+
+#define FRAMES_1 BIT_0 // Window Size
+#define FRAMES_2 BIT_1
+#define FRAMES_3 BIT_2
+#define FRAMES_4 BIT_3
+#define FRAMES_5 BIT_4
+#define FRAMES_6 BIT_5
+#define FRAMES_7 BIT_6
+
+#define BOFS_48 BIT_0 // Additional Beginning of Frame Flags
+#define BOFS_24 BIT_1
+#define BOFS_12 BIT_2
+#define BOFS_5 BIT_3
+#define BOFS_3 BIT_4
+#define BOFS_2 BIT_5
+#define BOFS_1 BIT_6
+#define BOFS_0 BIT_7
+
+#define MIN_TAT_10 BIT_0 // Minumum Turnaround Time (millisecs)
+#define MIN_TAT_5 BIT_1
+#define MIN_TAT_1 BIT_2
+#define MIN_TAT_0_5 BIT_3
+#define MIN_TAT_0_1 BIT_4
+#define MIN_TAT_0_05 BIT_5
+#define MIN_TAT_0_01 BIT_6
+#define MIN_TAT_0 BIT_7
+
+#define DISC_TIME_3 BIT_0 // Link Disconnect/Threshold Time (seconds)
+#define DISC_TIME_8 BIT_1
+#define DISC_TIME_12 BIT_2
+#define DISC_TIME_16 BIT_3
+#define DISC_TIME_20 BIT_4
+#define DISC_TIME_25 BIT_5
+#define DISC_TIME_30 BIT_6
+#define DISC_TIME_40 BIT_7
+
+typedef struct
+{
+ UINT bfBaud;
+ UINT bfMaxTurnTime;
+ UINT bfDataSize;
+ UINT bfWindowSize;
+ UINT bfBofs;
+ UINT bfMinTurnTime;
+ UINT bfDisconnectTime; // holds threshold time also
+} IRDA_QOS_PARMS;
+
+
+// IrDA Message Primitives
+typedef enum
+{
+ MAC_DATA_REQ = 0, // Keep in sync with table in irlaplog.c
+ MAC_DATA_IND,
+ MAC_CONTROL_REQ,
+ MAC_CONTROL_CONF,
+ IRLAP_DISCOVERY_REQ,
+ IRLAP_DISCOVERY_IND,
+ IRLAP_DISCOVERY_CONF,
+ IRLAP_CONNECT_REQ,
+ IRLAP_CONNECT_IND,
+ IRLAP_CONNECT_RESP,
+ IRLAP_CONNECT_CONF,
+ IRLAP_DISCONNECT_REQ,
+ IRLAP_DISCONNECT_IND,
+ IRLAP_DATA_REQ, // Don't fuss with the order, CONF must be 2 from REQ
+ IRLAP_DATA_IND,
+ IRLAP_DATA_CONF,
+ IRLAP_UDATA_REQ,
+ IRLAP_UDATA_IND,
+ IRLAP_UDATA_CONF,
+ IRLAP_STATUS_IND,
+ IRLAP_FLOWON_REQ,
+ IRLAP_FLOWON_IND,
+ IRLMP_DISCOVERY_REQ,
+ IRLMP_DISCOVERY_IND,
+ IRLMP_DISCOVERY_CONF,
+ IRLMP_CONNECT_REQ,
+ IRLMP_CONNECT_IND,
+ IRLMP_CONNECT_RESP,
+ IRLMP_CONNECT_CONF,
+ IRLMP_DISCONNECT_REQ,
+ IRLMP_DISCONNECT_IND,
+ IRLMP_DATA_REQ,
+ IRLMP_DATA_IND,
+ IRLMP_DATA_CONF,
+ IRLMP_UDATA_REQ,
+ IRLMP_UDATA_IND,
+ IRLMP_UDATA_CONF,
+ IRLMP_ACCESSMODE_REQ,
+ IRLMP_ACCESSMODE_IND,
+ IRLMP_ACCESSMODE_CONF,
+ IRLMP_FLOWON_REQ,
+ IRLMP_FLOWON_IND,
+ IRLMP_MORECREDIT_REQ,
+ IRLMP_GETVALUEBYCLASS_REQ,
+ IRLMP_GETVALUEBYCLASS_CONF
+} IRDA_SERVICE_PRIM;
+
+typedef enum
+{
+ MAC_MEDIA_BUSY, // keep in sync with IRDA_StatStr in irlaplog.c
+ MAC_MEDIA_CLEAR,
+ IRLAP_DISCOVERY_COLLISION,
+ IRLAP_REMOTE_DISCOVERY_IN_PROGRESS,
+ IRLAP_REMOTE_CONNECT_IN_PROGRSS,
+ IRLAP_DISCOVERY_COMPLETED,
+ IRLAP_REMOTE_CONNECTION_IN_PROGRESS,
+ IRLAP_CONNECTION_COMPLETED,
+ IRLAP_REMOTE_INITIATED,
+ IRLAP_PRIMARY_CONFLICT,
+ IRLAP_DISCONNECT_COMPLETED,
+ IRLAP_NO_RESPONSE,
+ IRLAP_DECLINE_RESET,
+ IRLAP_DATA_REQUEST_COMPLETED,
+ IRLAP_DATA_REQUEST_FAILED_LINK_RESET,
+ IRLAP_DATA_REQUEST_FAILED_REMOTE_BUSY,
+ IRLMP_NO_RESPONSE,
+ IRLMP_ACCESSMODE_SUCCESS,
+ IRLMP_ACCESSMODE_FAILURE,
+ IRLMP_DATA_REQUEST_COMPLETED,
+ IRLMP_DATA_REQUEST_FAILED
+} IRDA_SERVICE_STATUS;
+
+// MAC Control Service Request Message - MAC_CONTROL_REQ/CONF
+typedef enum
+{
+ MAC_INITIALIZE_LINK, // keep in sync with MAC_OpStr in irlaplog.c
+ MAC_SHUTDOWN_LINK,
+ MAC_RECONFIG_LINK,
+ MAC_MEDIA_SENSE,
+} MAC_CONTROL_OPERATION;
+
+typedef struct
+{
+ MAC_CONTROL_OPERATION Op;
+ int Port;
+ int Baud;
+ int NumBOFs;
+ int MinTat;
+ int DataSize;
+ int SenseTime;
+ IRDA_SERVICE_STATUS OpStatus;
+ BOOL SetIR;
+} MAC_CONTROL_SERVICE;
+
+// IRLAP Discovery Service Request Message - IRLAP_DISCOVERY_IND/CONF
+typedef struct
+{
+ LIST_ENTRY *pDevList;
+ IRDA_SERVICE_STATUS DscvStatus;
+ BOOL SenseMedia;
+} IRLAP_DISCOVERY_SERVICE;
+
+// IRDA Connection Service Request Message - IRLAP_CONNECT_REQ/IND/CONF
+// IRLMP_CONNECT_REQ/CONF
+typedef struct
+{
+ BYTE RemoteDevAddr[IRDA_DEV_ADDR_LEN];
+ IRDA_QOS_PARMS *pQOS;
+ int LocalLSAPSel;
+ int RemoteLSAPSel;
+ BYTE *pConnData;
+ int ConnDataLen;
+ void *pContext;
+ int MaxPDUSize;
+ int MaxSDUSize;
+ int TTPCredits;
+ IRDA_SERVICE_STATUS ConnStatus;
+ BOOL UseTTP;
+} IRDA_CONNECT_SERVICE;
+
+// IRDA Disconnection Service Request Message - IRLAP_DISCONNECT_REQ/IND
+// IRLMP_DISCONNECT_REQ/IND
+typedef enum
+{
+ IRLMP_USER_REQUEST = 1,
+ IRLMP_UNEXPECTED_IRLAP_DISC,
+ IRLMP_IRLAP_CONN_FAILED,
+ IRLMP_IRLAP_RESET,
+ IRLMP_LM_INITIATED_DISC,
+ IRLMP_DISC_LSAP,
+ IRLMP_NO_RESPONSE_LSAP,
+ IRLMP_NO_AVAILABLE_LSAP,
+ IRLMP_MAC_MEDIA_BUSY,
+ IRLMP_IRLAP_REMOTE_DISCOVERY_IN_PROGRESS,
+
+ IRLMP_IAS_NO_SUCH_OBJECT, // these are added for the IAS_GetValueByClass.Conf
+ IRLMP_IAS_NO_SUCH_ATTRIB,
+ IRLMP_IAS_SUCCESS,
+ IRLMP_IAS_SUCCESS_LISTLEN_GREATER_THAN_ONE,
+
+ IRLMP_UNSPECIFIED_DISC = 0xFF
+} IRLMP_DISC_REASON;
+
+typedef struct
+{
+ BYTE *pDiscData; // IRLMP_DISCONNECT_REQ/IND only
+ int DiscDataLen; // IRLMP_DISCONNECT_REQ/IND only
+ IRLMP_DISC_REASON DiscReason; // IRLMP_DISCONNECT_REQ/IND only
+ IRDA_SERVICE_STATUS DiscStatus; // Indication only
+} IRDA_DISCONNECT_SERVICE;
+
+// IRDA Data Service Request Message
+#define IRLAP_HEADER_LEN 2
+#define IRLMP_HEADER_LEN 6
+#define TTP_HEADER_LEN 8
+#define IRDA_HEADER_LEN IRLAP_HEADER_LEN+IRLMP_HEADER_LEN+TTP_HEADER_LEN+1
+ // + 1 IRComm WACK!!
+
+typedef struct
+{
+ void *pOwner;
+ void *pDataContext; // How IRDA gets user data
+ int SegCount; // Number of segments
+ BOOL FinalSeg;
+ BYTE *pBase;
+ BYTE *pLimit;
+ BYTE *pRead;
+ BYTE *pWrite;
+ void *pTdiSendComp;
+ void *pTdiSendCompCnxt;
+ BOOL IrCOMM_9Wire;
+#ifdef TEMPERAMENTAL_SERIAL_DRIVER
+ int FCS;
+#endif
+ IRDA_SERVICE_STATUS DataStatus; // for CONF
+ // |------------------------|
+ // | pRead o-------------
+ // |------------------------| |
+ // | pWrite o---------- |
+ // |------------------------| | |
+ // | pBase o------- | |
+ // |------------------------| | | |
+ // | pLimit o---- | | |
+ // |------------------------| | | | |
+ // | | | | |
+ // ------------------------ | | | |
+ // | |<---- | |
+ // | | | | |
+ // | |<--------<-
+ // | | |
+ // | |<-
+ // ------------------------
+ BYTE *pHdrRead;
+ BYTE *pHdrWrite;
+ BYTE Header[IRDA_HEADER_LEN];
+ // |------------------------|
+ // | pHdrRead o-------------
+ // |------------------------| |
+ // | pHdrWrite o---------- |
+ // |------------------------| | |
+ // Header--->| | | |
+ // | | | |
+ // | |<--------<-
+ // | | |
+ // | |<-------
+ // ------------------------
+ //
+ // On the receive side, all headers are contained
+ // at pRead, not in the above Header array
+ //
+} IRDA_DATA_SERVICE;
+
+typedef enum
+{
+ IRLMP_MULTIPLEXED,
+ IRLMP_EXCLUSIVE
+} IRLMP_ACCESSMODE;
+
+typedef struct
+{
+ IRLMP_ACCESSMODE AccessMode;
+ IRDA_SERVICE_STATUS ModeStatus;
+ BOOL IrLPTMode; // if true don't send PDU
+} IRLMP_ACCESSMODE_SERVICE;
+
+typedef struct
+{
+ IAS_QUERY *pIASQuery;
+ int AttribLen; // OctetSeq or UsrStr len
+ int IASQueryPerms;
+ IRLMP_DISC_REASON IASStatus;
+} IRLMP_IAS_SERVICE;
+
+typedef struct irda_msg
+{
+ LIST_ENTRY Linkage;
+ IRDA_SERVICE_PRIM Prim;
+ union
+ {
+ MAC_CONTROL_SERVICE MAC_ControlService;
+ IRLAP_DISCOVERY_SERVICE IRLAP_DiscoveryService;
+ IRDA_DISCONNECT_SERVICE IRDA_DisconnectService;
+ IRDA_CONNECT_SERVICE IRDA_ConnectService;
+ IRDA_DATA_SERVICE IRDA_DataService;
+ IRLMP_ACCESSMODE_SERVICE IRLMP_AccessModeService;
+ IRLMP_IAS_SERVICE IRLMP_IASService;
+ } MsgType;
+
+} IRDA_MSG, *PIRDA_MSG;
+
+#define IRDA_MSG_Op MsgType.MAC_ControlService.Op
+#define IRDA_MSG_Port MsgType.MAC_ControlService.Port
+#define IRDA_MSG_Baud MsgType.MAC_ControlService.Baud
+#define IRDA_MSG_NumBOFs MsgType.MAC_ControlService.NumBOFs
+#define IRDA_MSG_MinTat MsgType.MAC_ControlService.MinTat
+#define IRDA_MSG_DataSize MsgType.MAC_ControlService.DataSize
+#define IRDA_MSG_OpStatus MsgType.MAC_ControlService.OpStatus
+#define IRDA_MSG_SetIR MsgType.MAC_ControlService.SetIR
+#define IRDA_MSG_SenseTime MsgType.MAC_ControlService.SenseTime
+
+#define IRDA_MSG_pOwner MsgType.IRDA_DataService.pOwner
+#define IRDA_MSG_pDataContext MsgType.IRDA_DataService.pDataContext
+#define IRDA_MSG_SegCount MsgType.IRDA_DataService.SegCount
+#define IRDA_MSG_FinalSeg MsgType.IRDA_DataService.FinalSeg
+#define IRDA_MSG_pHdrRead MsgType.IRDA_DataService.pHdrRead
+#define IRDA_MSG_pHdrWrite MsgType.IRDA_DataService.pHdrWrite
+#define IRDA_MSG_Header MsgType.IRDA_DataService.Header
+#define IRDA_MSG_pBase MsgType.IRDA_DataService.pBase
+#define IRDA_MSG_pLimit MsgType.IRDA_DataService.pLimit
+#define IRDA_MSG_pRead MsgType.IRDA_DataService.pRead
+#define IRDA_MSG_pWrite MsgType.IRDA_DataService.pWrite
+#define IRDA_MSG_DataStatus MsgType.IRDA_DataService.DataStatus
+#define IRDA_MSG_pTdiSendComp MsgType.IRDA_DataService.pTdiSendComp
+#define IRDA_MSG_pTdiSendCompCnxt MsgType.IRDA_DataService.pTdiSendCompCnxt
+#define IRDA_MSG_IrCOMM_9Wire MsgType.IRDA_DataService.IrCOMM_9Wire
+#ifdef TEMPERAMENTAL_SERIAL_DRIVER
+#define IRDA_MSG_FCS MsgType.IRDA_DataService.FCS
+#endif
+
+#define IRDA_MSG_pDevList MsgType.IRLAP_DiscoveryService.pDevList
+#define IRDA_MSG_DscvStatus MsgType.IRLAP_DiscoveryService.DscvStatus
+#define IRDA_MSG_SenseMedia MsgType.IRLAP_DiscoveryService.SenseMedia
+
+#define IRDA_MSG_RemoteDevAddr MsgType.IRDA_ConnectService.RemoteDevAddr
+#define IRDA_MSG_pQOS MsgType.IRDA_ConnectService.pQOS
+#define IRDA_MSG_LocalLSAPSel MsgType.IRDA_ConnectService.LocalLSAPSel
+#define IRDA_MSG_RemoteLSAPSel MsgType.IRDA_ConnectService.RemoteLSAPSel
+#define IRDA_MSG_pConnData MsgType.IRDA_ConnectService.pConnData
+#define IRDA_MSG_ConnDataLen MsgType.IRDA_ConnectService.ConnDataLen
+#define IRDA_MSG_ConnStatus MsgType.IRDA_ConnectService.ConnStatus
+#define IRDA_MSG_pContext MsgType.IRDA_ConnectService.pContext
+#define IRDA_MSG_UseTTP MsgType.IRDA_ConnectService.UseTTP
+#define IRDA_MSG_MaxSDUSize MsgType.IRDA_ConnectService.MaxSDUSize
+#define IRDA_MSG_MaxPDUSize MsgType.IRDA_ConnectService.MaxPDUSize
+#define IRDA_MSG_TTPCredits MsgType.IRDA_ConnectService.TTPCredits
+
+#define IRDA_MSG_pDiscData MsgType.IRDA_DisconnectService.pDiscData
+#define IRDA_MSG_DiscDataLen MsgType.IRDA_DisconnectService.DiscDataLen
+#define IRDA_MSG_DiscReason MsgType.IRDA_DisconnectService.DiscReason
+#define IRDA_MSG_DiscStatus MsgType.IRDA_DisconnectService.DiscStatus
+
+#define IRDA_MSG_AccessMode MsgType.IRLMP_AccessModeService.AccessMode
+#define IRDA_MSG_ModeStatus MsgType.IRLMP_AccessModeService.ModeStatus
+#define IRDA_MSG_IrLPTMode MsgType.IRLMP_AccessModeService.IrLPTMode
+
+#define IRDA_MSG_pIASQuery MsgType.IRLMP_IASService.pIASQuery
+#define IRDA_MSG_AttribLen MsgType.IRLMP_IASService.AttribLen
+#define IRDA_MSG_IASQueryPerms MsgType.IRLMP_IASService.IASQueryPerms
+#define IRDA_MSG_IASStatus MsgType.IRLMP_IASService.IASStatus
+
+extern LIST_ENTRY IrdaLinkCbList;
+
+VOID IrdaTimerInitialize(PIRDA_TIMER pTimer,
+ VOID (*ExpFunc)(PVOID Context),
+ UINT Timeout,
+ PVOID Context);
+
+VOID IrdaTimerStart(PIRDA_TIMER pTimer);
+
+VOID IrdaTimerStop(PIRDA_TIMER pTimer);
+
diff --git a/private/ntos/tdi/irda/inc/irdalink.h b/private/ntos/tdi/irda/inc/irdalink.h
new file mode 100644
index 000000000..e96f13665
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/irdalink.h
@@ -0,0 +1,34 @@
+NTSTATUS IrdaNdisInitialize();
+
+#define IRDA_NDIS_BUFFER_POOL_SIZE 4
+#define IRDA_NDIS_PACKET_POOL_SIZE 4
+#define IRDA_MSG_LIST_LEN 2
+#define IRDA_MSG_DATA_SIZE 64
+
+typedef struct
+{
+ PIRDA_MSG pIMsg;
+ MEDIA_SPECIFIC_INFORMATION MediaInfo;
+} IRDA_PROTOCOL_RESERVED, *PIRDA_PROTOCOL_RESERVED;
+
+typedef struct IrdaLinkControlBlock
+{
+ LIST_ENTRY Linkage;
+ NDIS_SPIN_LOCK SpinLock;
+ NDIS_HANDLE BindContext;
+ NDIS_HANDLE NdisBindingHandle;
+ NDIS_EVENT SyncEvent;
+ NDIS_STATUS SyncStatus;
+ int MediaBusy;
+ PVOID IrlapContext;
+ PVOID IrlmpContext;
+ NDIS_HANDLE BufferPool;
+ NDIS_HANDLE PacketPool;
+ LIST_ENTRY IMsgList;
+ int IMsgListLen;
+ UINT ExtraBofs; // These should be per connection for
+ UINT MinTat; // multipoint
+} IRDA_LINK_CB, *PIRDA_LINK_CB;
+
+IRDA_MSG *AllocMacIMsg(PIRDA_LINK_CB);
+
diff --git a/private/ntos/tdi/irda/inc/irerr.h b/private/ntos/tdi/irda/inc/irerr.h
new file mode 100644
index 000000000..7490c6fba
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/irerr.h
@@ -0,0 +1,110 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: irerr.h
+*
+* Description: IR error defines
+*
+* Author: mmiller
+*
+* Date: 4/25/95
+*
+*/
+
+#ifndef SUCCESS
+#define SUCCESS 0
+#endif
+
+#define IR_ERROR_BASE 20000
+#define IRLAP_ERROR_BASE IR_ERROR_BASE + 100
+#define IRLMP_ERROR_BASE IR_ERROR_BASE + 200
+
+#define IRMAC_TX_OVERFLOW (IR_ERROR_BASE+0)
+#define IRMAC_WRITE_FAILED (IR_ERROR_BASE+1)
+#define IRMAC_READ_FAILED (IR_ERROR_BASE+2)
+#define IRMAC_BAD_FCS (IR_ERROR_BASE+3)
+#define IRMAC_RX_OVERFLOW (IR_ERROR_BASE+4)
+#define IRMAC_TIMEOUT (IR_ERROR_BASE+5)
+#define IRMAC_BAD_PRIM (IR_ERROR_BASE+6)
+#define IRMAC_BAD_OP (IR_ERROR_BASE+7)
+#define IRMAC_OPEN_PORT_FAILED (IR_ERROR_BASE+8)
+#define IRMAC_SET_BAUD_FAILED (IR_ERROR_BASE+9)
+#define IRMAC_MALLOC_FAILED (IR_ERROR_BASE+10)
+#define IRMAC_ALREADY_INIT (IR_ERROR_BASE+11)
+#define IRMAC_BAD_TIMER (IR_ERROR_BASE+12)
+#define IRMAC_NOT_INITIALIZED (IR_ERROR_BASE+13)
+#define IRMAC_LINK_RESET (IR_ERROR_BASE+14)
+
+#define IRLAP_NOT_INITIALIZED (IRLAP_ERROR_BASE + 0)
+#define IRLAP_BAD_PRIM (IRLAP_ERROR_BASE + 1)
+#define IRLAP_BAD_STATE (IRLAP_ERROR_BASE + 2)
+#define IRLAP_BAD_OPSTATUS (IRLAP_ERROR_BASE + 3)
+#define IRLAP_BAD_OP (IRLAP_ERROR_BASE + 4)
+#define IRLAP_MALLOC_FAILED (IRLAP_ERROR_BASE + 5)
+#define IRLAP_BAUD_NEG_ERR (IRLAP_ERROR_BASE + 6)
+#define IRLAP_DISC_NEG_ERR (IRLAP_ERROR_BASE + 7)
+#define IRLAP_MAXTAT_NEG_ERR (IRLAP_ERROR_BASE + 8)
+#define IRLAP_MINTAT_NEG_ERR (IRLAP_ERROR_BASE + 9)
+#define IRLAP_DATASIZE_NEG_ERR (IRLAP_ERROR_BASE + 10)
+#define IRLAP_WINSIZE_NEG_ERR (IRLAP_ERROR_BASE + 11)
+#define IRLAP_BOFS_NEG_ERR (IRLAP_ERROR_BASE + 12)
+#define IRLAP_LINECAP_ERR (IRLAP_ERROR_BASE + 13)
+#define IRLAP_BAD_SLOTNO (IRLAP_ERROR_BASE + 14)
+#define IRLAP_XID_CMD_NOT_P (IRLAP_ERROR_BASE + 15)
+#define IRLAP_SNRM_NO_QOS (IRLAP_ERROR_BASE + 16)
+#define IRLAP_UA_NO_QOS (IRLAP_ERROR_BASE + 17)
+#define IRLAP_XID_CMD_RSP (IRLAP_ERROR_BASE + 18)
+#define IRLAP_SNRM_NOT_CMD (IRLAP_ERROR_BASE + 19)
+#define IRLAP_SNRM_NOT_P (IRLAP_ERROR_BASE + 20)
+#define IRLAP_UA_NOT_RSP (IRLAP_ERROR_BASE + 21)
+#define IRLAP_UA_NOT_F (IRLAP_ERROR_BASE + 22)
+#define IRLAP_MSG_LIST_EMPTY (IRLAP_ERROR_BASE + 23)
+#define IRLAP_MSG_LIST_FULL (IRLAP_ERROR_BASE + 24)
+#define IRLAP_RXD_BAD_FRAME (IRLAP_ERROR_BASE + 25)
+#define IRLAP_BAD_CRBIT_IFRAME (IRLAP_ERROR_BASE + 26)
+#define IRLAP_BAD_DATA_REQUEST (IRLAP_ERROR_BASE + 27)
+#define IRLAP_DISC_CMD_RSP (IRLAP_ERROR_BASE + 28)
+#define IRLAP_DISC_CMD_NOT_P (IRLAP_ERROR_BASE + 29)
+#define IRLAP_DM_RSP_NOT_F (IRLAP_ERROR_BASE + 30)
+#define IRLAP_DM_RSP_CMD (IRLAP_ERROR_BASE + 31)
+#define IRLAP_FRMR_RSP_CMD (IRLAP_ERROR_BASE + 32)
+#define IRLAP_FRMR_RSP_NOT_F (IRLAP_ERROR_BASE + 33)
+#define IRLAP_BAD_QOS (IRLAP_ERROR_BASE + 34)
+#define IRLAP_NULL_MSG (IRLAP_ERROR_BASE + 35)
+#define IRLAP_BAD_MAX_SLOT (IRLAP_ERROR_BASE + 36)
+#define IRLAP_REMOTE_DISCOVERY_IN_PROGRESS_ERR (IRLAP_ERROR_BASE + 37)
+#define IRLAP_REMOTE_CONNECTION_IN_PROGRESS_ERR (IRLAP_ERROR_BASE + 38)
+#define IRLAP_REMOTE_BUSY (IRLAP_ERROR_BASE + 39)
+
+#define IRLMP_NOT_INITIALIZED (IRLMP_ERROR_BASE + 0)
+#define IRLMP_LSAP_BAD_STATE (IRLMP_ERROR_BASE + 1)
+#define IRLMP_USER_DATA_LEN_EXCEEDED (IRLMP_ERROR_BASE + 2)
+#define IRLMP_LINK_IN_USE (IRLMP_ERROR_BASE + 3)
+#define IRLMP_TIMER_START_FAILED (IRLMP_ERROR_BASE + 4)
+#define IRLMP_ALLOC_FAILED (IRLMP_ERROR_BASE + 5)
+#define IRLMP_LINK_BAD_STATE (IRLMP_ERROR_BASE + 6)
+#define IRLMP_LSAP_SEL_IN_USE (IRLMP_ERROR_BASE + 7)
+#define IRLMP_CREDIT_CALC_ERROR (IRLMP_ERROR_BASE + 8)
+#define IRLMP_NO_TX_CREDIT (IRLMP_ERROR_BASE + 9)
+#define IRLMP_TX_DATA_LEN_EXCEEDED (IRLMP_ERROR_BASE + 10)
+#define IRLMP_DATA_IND_BAD_FRAME (IRLMP_ERROR_BASE + 11)
+#define IRLMP_SCHEDULE_EVENT_FAILED (IRLMP_ERROR_BASE + 12)
+#define IRLMP_LOCAL_BUSY (IRLMP_ERROR_BASE + 13)
+#define IRLMP_BAD_PRIM (IRLMP_ERROR_BASE + 14)
+#define IRLMP_BAD_ACCESSMODE (IRLMP_ERROR_BASE + 15)
+#define IRLMP_LINK_BUSY (IRLMP_ERROR_BASE + 16)
+#define IRLMP_IN_MULTIPLEXED_MODE (IRLMP_ERROR_BASE + 17)
+#define IRLMP_IN_EXCLUSIVE_MODE (IRLMP_ERROR_BASE + 18)
+#define IRLMP_NOT_LSAP_IN_EXCLUSIVE_MODE (IRLMP_ERROR_BASE + 19)
+#define IRLMP_INVALID_LSAP_CB (IRLMP_ERROR_BASE + 20)
+#define IRLMP_REMOTE_BUSY (IRLMP_ERROR_BASE + 21)
+#define IRLMP_TIMER_STOP_FAILED (IRLMP_ERROR_BASE + 22)
+#define IRLMP_BAD_IAS_OBJECT_ID (IRLMP_ERROR_BASE + 23)
+#define IRLMP_NO_SUCH_IAS_CLASS (IRLMP_ERROR_BASE + 24)
+#define IRLMP_NO_SUCH_IAS_ATTRIBUTE (IRLMP_ERROR_BASE + 25)
+#define IRLMP_UNSUPPORTED_IAS_OPERATION (IRLMP_ERROR_BASE + 26)
+#define IRLMP_BAD_IAS_QUERY_FROM_REMOTE (IRLMP_ERROR_BASE + 27)
+#define IRLMP_IAS_QUERY_IN_PROGRESS (IRLMP_ERROR_BASE + 28)
+#define IRLMP_UNSOLICITED_IAS_RESPONSE (IRLMP_ERROR_BASE + 29)
+#define IRLMP_SHUTDOWN_IN_PROGESS (IRLMP_ERROR_BASE + 30)
diff --git a/private/ntos/tdi/irda/inc/irlap.h b/private/ntos/tdi/irda/inc/irlap.h
new file mode 100644
index 000000000..dbcc68361
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/irlap.h
@@ -0,0 +1,66 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: irlap.h
+*
+* Description: IRLAP Protocol and control block definitions
+*
+* Author: mbert
+*
+* Date: 4/15/95
+*
+*/
+
+// Sequence number modulus
+#define IRLAP_MOD 8
+#define PV_TABLE_MAX_BIT 8
+
+extern UINT vBaudTable[];
+extern UINT vMaxTATTable[];
+extern UINT vMinTATTable[];
+extern UINT vDataSizeTable[];
+extern UINT vWinSizeTable[];
+extern UINT vBOFSTable[];
+extern UINT vDiscTable[];
+extern UINT vThreshTable[];
+extern UINT vBOFSDivTable[];
+
+VOID IrlapOpenLink(
+ OUT PNTSTATUS Status,
+ IN PIRDA_LINK_CB pIrdaLinkCb,
+ IN IRDA_QOS_PARMS *pQos,
+ IN BYTE *pDscvInfo,
+ IN int DscvInfoLen,
+ IN UINT MaxSlot);
+
+UINT IrlapDown(IN PVOID Context,
+ IN PIRDA_MSG);
+
+UINT IrlapUp(IN PVOID Context,
+ IN PIRDA_MSG);
+
+UINT IRLAP_Shutdown();
+
+UINT IrlapGetQosParmVal(UINT[], UINT, UINT *);
+
+void IRLAP_PrintState();
+
+
+
+typedef struct
+{
+ LIST_ENTRY ListHead;
+ int Len;
+} IRDA_MSG_LIST;
+
+// I've exported these for the tester
+UINT DequeMsgList(IRDA_MSG_LIST *, IRDA_MSG **);
+UINT EnqueMsgList(IRDA_MSG_LIST *, IRDA_MSG *, int);
+void InitMsgList(IRDA_MSG_LIST *);
+
+
+
+
+
+
diff --git a/private/ntos/tdi/irda/inc/irlaplog.h b/private/ntos/tdi/irda/inc/irlaplog.h
new file mode 100644
index 000000000..71f67866f
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/irlaplog.h
@@ -0,0 +1,44 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: irlaplog.h
+*
+* Description: IRLAP state machine logging and errors
+*
+* Author: mbert
+*
+* Date: 4/15/95
+*
+*/
+
+#ifdef DEBUG
+
+extern TCHAR *IRDA_PrimStr[];
+extern TCHAR *IRLAP_StateStr[];
+extern TCHAR *MAC_OpStr[];
+extern TCHAR *IRDA_TimerStr[];
+extern TCHAR *IRDA_StatStr[];
+
+#define SPRINT_BUF_LEN 1000
+
+#define EXPAND_ADDR(Addr) (Addr[0], Addr[1], Addr[2], Addr[3])
+
+void IRLAP_EventLogStart(PIRLAP_CB, TCHAR *pFormat, ...);
+void __cdecl IRLAP_LogAction(PIRLAP_CB, TCHAR *pFormat, ...);
+void IRLAP_EventLogComplete(PIRLAP_CB);
+TCHAR *FrameToStr(IRDA_MSG *);
+
+#define IRLAP_LOG_START(X) IRLAP_EventLogStart X
+#define IRLAP_LOG_ACTION(X) IRLAP_LogAction X
+#define IRLAP_LOG_COMPLETE(X) IRLAP_EventLogComplete(X)
+
+#else
+
+#define IRLAP_LOG_START(X) (0)
+#define IRLAP_LOG_ACTION(X) (0)
+#define IRLAP_LOG_COMPLETE(X) (0)
+
+#endif
+
+
diff --git a/private/ntos/tdi/irda/inc/irlmp.h b/private/ntos/tdi/irda/inc/irlmp.h
new file mode 100644
index 000000000..ac46e4107
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/irlmp.h
@@ -0,0 +1,60 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: irlmp.h
+*
+* Description: IRLMP Protocol and control block definitions
+*
+* Author: mbert
+*
+* Date: 4/15/95
+*
+*/
+
+#define IRLMP_MAX_USER_DATA_LEN 53
+
+// IrLMP Entry Points
+
+UINT IRLMP_Initialize(int Port, BOOL SetIR, BYTE DscvInfo[], int DscvInfoLen,
+ IRDA_QOS_PARMS *pQOS, int MaxSlot, CHAR *pDeviceName,
+ int DeviceNameLen);
+
+UINT IrlmpDown(PVOID IrlmpContext, PIRDA_MSG pIMsg);
+UINT IrlmpUp(PVOID IrlmpContext, PIRDA_MSG pIMsg);
+
+UINT IRLMP_RegisterLSAPProtocol(int LSAP, BOOL UseTTP);
+UINT IRLMP_Shutdown();
+
+#ifdef DEBUG
+void IRLMP_PrintState();
+#endif
+
+// IAS
+
+#define IAS_ASCII_CHAR_SET 0
+
+// IAS Attribute value types
+#define IAS_ATTRIB_VAL_MISSING 0
+#define IAS_ATTRIB_VAL_INTEGER 1
+#define IAS_ATTRIB_VAL_BINARY 2
+#define IAS_ATTRIB_VAL_STRING 3
+
+// IAS Operation codes
+#define IAS_OPCODE_GET_VALUE_BY_CLASS 4 // The only one I do
+
+extern const CHAR IAS_ClassName_Device[];
+extern const CHAR IAS_AttribName_DeviceName[];
+extern const CHAR IAS_AttribName_IrLMPSupport[];
+extern const CHAR IAS_AttribName_TTPLsapSel[];
+extern const CHAR IAS_AttribName_IrLMPLsapSel[];
+
+extern const BYTE IAS_ClassNameLen_Device;
+extern const BYTE IAS_AttribNameLen_DeviceName;
+extern const BYTE IAS_AttribNameLen_IRLMPSupport;
+extern const BYTE IAS_AttribNameLen_TTPLsapSel;
+extern const BYTE IAS_AttribNameLen_IrLMPLsapSel;
+
+UINT IAS_AddAttribute(IAS_SET *pIASSet);
+
+UINT IAS_DeleteObject(CHAR *pClassName);
diff --git a/private/ntos/tdi/irda/inc/irmac.h b/private/ntos/tdi/irda/inc/irmac.h
new file mode 100644
index 000000000..534e83525
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/irmac.h
@@ -0,0 +1,32 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: irmac.h
+*
+* Description: IRLAP MAC definitions and entry point prototypes
+*
+* Author: mbert
+*
+* Date: 4/15/95
+*
+*/
+
+// Entry Points
+
+UINT IrmacInitialize();
+
+UINT IrmacDown(
+ IN PVOID IrmacContext,
+ PIRDA_MSG pMsg);
+
+UINT IRMAC_RxFrame(IRDA_MSG *pMsg);
+UINT IRMAC_TimerExpired(IRDA_TIMER Timer);
+void IRMAC_PrintState();
+
+
+
+
+
+
+
diff --git a/private/ntos/tdi/irda/inc/oscfg.h b/private/ntos/tdi/irda/inc/oscfg.h
new file mode 100644
index 000000000..49eab5e00
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/oscfg.h
@@ -0,0 +1,62 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: oscfg.h
+*
+* Description: OS configuration section
+*
+* Author: mmiller
+*
+* Date: 4/25/95
+*
+*/
+#ifdef PEG
+
+// Pegasus specific includes/defines
+#include "peg.h"
+
+#define DbgPrint NKDbgPrintfW
+
+#else // PEG
+
+#include <ntos.h>
+//#include <nt.h>
+//#include <ntrtl.h>
+//#include <nturtl.h>
+
+//#include <zwapi.h>
+//#include <ntddk.h>
+//#include <windows.h>
+
+#define RETAILMSG(exp,p) (0)
+#define DEBUGMSG(exp,p) (0)
+
+// NT specific includes/defines
+//#include "windows.h"
+//#include "stdio.h"
+
+//#define DbgPrint printf
+//typedef char TCHAR;
+
+//#define RETAILMSG(exp,p) ((exp)?DbgPrint p,1:0)
+
+//#ifdef DEBUG
+
+//#define DEBUGMSG(exp,p) ((exp)?DbgPrint p,1:0)
+//#undef NDEBUG
+
+//#define DEBUGZONE(x) 1<<x
+
+//#else // DEBUG
+
+//#define DEBUGMSG(exp,p) (0)
+//#define NDEBUG
+
+//#endif // DEBUG
+
+//#define ASSERT assert
+//#include "assert.h"
+
+
+#endif // PEG
diff --git a/private/ntos/tdi/irda/inc/tmp.h b/private/ntos/tdi/irda/inc/tmp.h
new file mode 100644
index 000000000..85ca9f294
--- /dev/null
+++ b/private/ntos/tdi/irda/inc/tmp.h
@@ -0,0 +1,31 @@
+extern int irdaDbgSettings;
+
+#define DBG_NDIS (1 << 1)
+
+#define DBG_IRMAC (1 << 4)
+
+#define DBG_IRLAP (1 << 8)
+#define DBG_IRLAPLOG (1 << 9)
+
+#define DBG_IRLMP (1 << 12)
+#define DBG_IRLMP_CONN (1 << 13)
+#define DBG_IRLMP_CRED (1 << 14)
+
+#define DBG_DISCOVERY (1 << 16)
+#define DBG_PRINT (1 << 17)
+#define DBG_ADDR (1 << 18)
+
+#define DBG_MISC (1 << 27)
+#define DBG_ALLOC (1 << 28)
+#define DBG_FUNCTION (1 << 29)
+#define DBG_WARN (1 << 30)
+#define DBG_ERROR (1 << 31)
+
+
+#ifdef DEBUG
+#define DEBUGMSG(dbgs,format) ((dbgs & irdaDbgSettings)? DbgPrint format:0)
+#else
+#define DEBUGMSG(dbgs,format) (0)
+#endif
+
+
diff --git a/private/ntos/tdi/irda/irlap/irlap.c b/private/ntos/tdi/irda/irlap/irlap.c
new file mode 100644
index 000000000..c9978e60a
--- /dev/null
+++ b/private/ntos/tdi/irda/irlap/irlap.c
@@ -0,0 +1,4519 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* @doc
+* @module irlap.c | Provides IrLAP API
+*
+* Author: mbert
+*
+* 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
+*
+* IRLAP_GetRxMsg(&Message)
+* MAC requesting a message buffer from IRLAP
+* to receive next frame in
+*
+* IRLAP_TimerExp(Timer)
+* Receives from timer thread timer expiration notifications
+*
+* IRLAP_Shutdown()
+* Shut down IRLAP and IRMAC.
+*
+* IRLAP_GetControlBlock()
+* Returns pointer to IRLAP control block.
+*
+* IrlapGetQosParmVal()
+* Allows IRLMP to decode Qos.
+*
+* |---------|
+* | IRLMP |
+* |---------|
+* /|\ |
+* | |
+* IrlmpUp() | | IrlapDown()
+* | |
+* | \|/
+* |---------| IRDA_TimerStart/Stop() |-------|
+* | |-------------------------->| |
+* | IRLAP | | TIMER |
+* | |<--------------------------| |
+* |---------| IRLAP_TimerExp() |-------|
+* /|\ |
+* | |
+* IrlapUp() | |IrmacDown()
+* IRLAP_GetRxMsg() | |
+* | \|/
+* |---------|
+* | 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>
+#include <irdalink.h>
+#include <irmac.h>
+#include <irlap.h>
+#include <irlmp.h>
+#include <irlapp.h>
+#include <irlapio.h>
+#include <irlaplog.h>
+
+
+#ifdef TEMPERAMENTAL_SERIAL_DRIVER
+int TossedDups;
+#endif
+
+STATIC UINT _rc; // return code
+STATIC IRDA_MSG IMsg; // for locally generated messages to LMP/MAC
+STATIC UINT IRLAP_SlotTable[] = {1, 6, 8, 16};
+STATIC IRLAP_FRMR_FORMAT FrmRejFormat;
+
+BYTE IRLAP_BroadcastDevAddr[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,0, 0, 4000000};
+UINT vMaxTATTable[] = {500, 250, 100, 50, 25, 10, 5, 0, 0 };
+UINT vMinTATTable[] = {10000,5000, 1000, 500, 100, 50, 10,0, 0 };
+UINT vDataSizeTable[] = {64, 128, 256, 512, 1024, 2048, 0, 0, 0 };
+UINT vWinSizeTable[] = {1, 2, 3, 4, 5, 6, 7, 0, 0 };
+UINT vBOFSTable[] = {48, 24, 12, 5, 3, 2, 1, 0, 0 };
+UINT vDiscTable[] = {3, 8, 12, 16, 20, 25, 30,40,0 };
+UINT vThreshTable[] = {0, 3, 3, 3, 3, 3, 3, 3, 0 };
+UINT vBOFSDivTable[] = {48, 12, 6, 3, 2, 1, 1, 1, 0 };
+
+// Tables for determining number of BOFS for baud and min turn time
+// min turn time - 10ms 5ms 1ms 0.5ms 0.1ms 0.05ms 0.01ms
+// -------------------------------------------------------------
+UINT BOFS_9600[] = {10, 5, 1, 0, 0, 0, 0};
+UINT BOFS_19200[] = {20, 10, 2, 1, 0, 0, 0};
+UINT BOFS_38400[] = {40, 20, 4, 2, 0, 0, 0};
+UINT BOFS_57600[] = {58, 29, 6, 3, 1, 0, 0};
+UINT BOFS_115200[] = {115, 58, 12, 6, 1, 1, 0};
+
+// 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};
+UINT MAXCAP_19200[] = {800, 400, 160, 0, 0, 0, 0};
+UINT MAXCAP_38400[] = {1600, 800, 320, 0, 0, 0, 0};
+UINT MAXCAP_57600[] = {2360, 1180, 472, 0, 0, 0, 0};
+UINT MAXCAP_115200[] = {4800, 2400, 960, 480, 240, 96, 48};
+
+// prototypes
+STATIC UINT InitializeState(PIRLAP_CB, IRLAP_STN_TYPE);
+STATIC UINT ReturnTxMsgs(PIRLAP_CB);
+STATIC UINT ProcessConnectReq(PIRLAP_CB, PIRDA_MSG);
+STATIC UINT ProcessConnectResp(PIRLAP_CB, PIRDA_MSG);
+STATIC UINT ProcessDiscoveryReq(PIRLAP_CB, PIRDA_MSG);
+STATIC UINT ProcessDisconnectReq(PIRLAP_CB);
+STATIC UINT ProcessDataAndUDataReq(PIRLAP_CB, PIRDA_MSG);
+STATIC UINT XmitTxMsgList(PIRLAP_CB, BOOL, BOOL *);
+STATIC UINT GotoPCloseState(PIRLAP_CB);
+STATIC UINT GotoNDMThenDscvOrConn(PIRLAP_CB);
+STATIC UINT ProcessMACControlConf(PIRLAP_CB, PIRDA_MSG);
+STATIC UINT ProcessMACDataInd(PIRLAP_CB, PIRDA_MSG , BOOL *);
+STATIC UINT ProcessDscvXIDCmd(PIRLAP_CB, IRLAP_XID_DSCV_FORMAT *, BYTE *);
+STATIC UINT ProcessDscvXIDRsp(PIRLAP_CB, IRLAP_XID_DSCV_FORMAT *, BYTE *);
+STATIC void ExtractQosParms(IRDA_QOS_PARMS *, BYTE *, BYTE *);
+STATIC UINT InitDscvCmdProcessing(PIRLAP_CB, IRLAP_XID_DSCV_FORMAT *);
+STATIC void ExtractDeviceInfo(IRDA_DEVICE *, IRLAP_XID_DSCV_FORMAT *, BYTE *);
+STATIC BOOL DevInDevList(BYTE[], LIST_ENTRY *);
+STATIC UINT AddDevToList(PIRLAP_CB, IRLAP_XID_DSCV_FORMAT *, BYTE *);
+STATIC void ClearDevList(LIST_ENTRY *);
+STATIC UINT ProcessSNRM(PIRLAP_CB, IRLAP_SNRM_FORMAT *, BYTE *);
+STATIC UINT ProcessUA(PIRLAP_CB, IRLAP_UA_FORMAT *, BYTE *);
+STATIC UINT ProcessDISC(PIRLAP_CB);
+STATIC UINT ProcessRD(PIRLAP_CB);
+STATIC UINT ProcessRNRM(PIRLAP_CB);
+STATIC UINT ProcessDM(PIRLAP_CB);
+STATIC UINT ProcessFRMR(PIRLAP_CB);
+STATIC UINT ProcessTEST(PIRLAP_CB, PIRDA_MSG, IRLAP_UA_FORMAT *, int, int);
+STATIC UINT ProcessUI(PIRLAP_CB, PIRDA_MSG, int, int);
+STATIC UINT ProcessREJ_SREJ(PIRLAP_CB, int, PIRDA_MSG, int, int, UINT);
+STATIC UINT ProcessRR_RNR(PIRLAP_CB, int, PIRDA_MSG, int, int, UINT);
+STATIC UINT ProcessIFrame(PIRLAP_CB, PIRDA_MSG, int, int, UINT, UINT, BOOL *);
+STATIC BOOL InvalidNsOrNr(PIRLAP_CB, UINT, UINT);
+STATIC BOOL InvalidNr(PIRLAP_CB, UINT);
+STATIC BOOL InWindow(UINT, UINT, UINT);
+STATIC UINT ProcessInvalidNsOrNr(PIRLAP_CB, int);
+STATIC UINT ProcessInvalidNr(PIRLAP_CB, int);
+STATIC UINT InsertRxWinAndForward(PIRLAP_CB, PIRDA_MSG, UINT, BOOL *);
+STATIC UINT ResendRejects(PIRLAP_CB, UINT);
+STATIC UINT FreeAckedTxMsgs(PIRLAP_CB, UINT);
+STATIC UINT MissingRxFrames(PIRLAP_CB);
+STATIC UINT IFrameOtherStates(PIRLAP_CB, int, int);
+STATIC UINT NegotiateQosParms(PIRLAP_CB, IRDA_QOS_PARMS *);
+STATIC UINT ApplyQosParms(PIRLAP_CB);
+STATIC UINT StationConflict(PIRLAP_CB);
+STATIC UINT ApplyDefaultParms(PIRLAP_CB);
+STATIC UINT ResendDISC(PIRLAP_CB);
+STATIC BOOL IgnoreState(PIRLAP_CB);
+STATIC BOOL MyDevAddr(PIRLAP_CB, BYTE []);
+STATIC VOID SlotTimerExp(PVOID);
+STATIC VOID FinalTimerExp(PVOID);
+STATIC VOID PollTimerExp(PVOID);
+STATIC VOID BackoffTimerExp(PVOID);
+STATIC VOID WDogTimerExp(PVOID);
+STATIC VOID QueryTimerExp(PVOID);
+
+#ifdef DEBUG
+void _inline IRLAP_TimerStart(PIRLAP_CB pIrlapCb, PIRDA_TIMER pTmr)
+{
+ IRLAP_LOG_ACTION((pIrlapCb, "Start %s timer for %dms", pTmr->pName,
+ pTmr->Timeout));
+ IrdaTimerStart(pTmr);
+}
+
+void _inline IRLAP_TimerStop(PIRLAP_CB pIrlapCb, PIRDA_TIMER pTmr)
+{
+ IRLAP_LOG_ACTION((pIrlapCb, "Stop %s timer", pTmr->pName));
+ IrdaTimerStop(pTmr);
+}
+#else
+#define IRLAP_TimerStart(c,t) IrdaTimerStart(t)
+#define IRLAP_TimerStop(c,t) IrdaTimerStop(t)
+#endif
+
+VOID
+IrlapOpenLink(OUT PNTSTATUS Status,
+ IN PIRDA_LINK_CB pIrdaLinkCb,
+ IN IRDA_QOS_PARMS *pQos,
+ IN BYTE *pDscvInfo,
+ IN int DscvInfoLen,
+ IN UINT MaxSlot)
+{
+ UINT rc = SUCCESS;
+ int i;
+ IRDA_MSG *pMsg;
+ PIRLAP_CB pIrlapCb;
+
+ DEBUGMSG(DBG_IRLAP, ("IrlapOpenLink\n"));
+
+ if ((pIrlapCb = CTEAllocMem(sizeof(IRLAP_CB))) == NULL)
+ {
+ DEBUGMSG(DBG_ERROR, ("Alloc failed\n"));
+ *Status = STATUS_INSUFFICIENT_RESOURCES;
+ return;
+ }
+
+ pIrdaLinkCb->IrlapContext = pIrlapCb;
+
+ DscvInfoLen = DscvInfoLen > IRLAP_DSCV_INFO_LEN ?
+ IRLAP_DSCV_INFO_LEN : DscvInfoLen;
+
+ memcpy(pIrlapCb->LocalDevice.DscvInfo, pDscvInfo, DscvInfoLen);
+
+ pIrlapCb->LocalDevice.DscvInfoLen = DscvInfoLen;
+
+ memcpy(&pIrlapCb->LocalQos, pQos, sizeof(IRDA_QOS_PARMS));
+
+ pIrlapCb->Sig = IRLAP_CB_SIG;
+ 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*/;
+ }
+
+ // initialize as PRIMARY so UI frames in contention
+ // state sends CRBit = cmd
+ if ((rc = InitializeState(pIrlapCb, PRIMARY)) != SUCCESS)
+ {
+ CTEFreeMem(pIrlapCb);
+ *Status = STATUS_UNSUCCESSFUL;
+ return;
+ }
+
+ pIrlapCb->State = NDM;
+
+ // Generate random local address
+ StoreULAddr(pIrlapCb->LocalDevice.DevAddr, (ULONG) GetMyDevAddr(FALSE));
+
+ pIrlapCb->LocalDevice.IRLAP_Version = 1;
+
+ pIrlapCb->Baud = IRLAP_DEFAULT_BAUD;
+ pIrlapCb->RemoteMaxTAT = IRLAP_DEFAULT_MAX_TAT;
+ pIrlapCb->RemoteDataSize = IRLAP_DEFAULT_DATA_SIZE;
+ pIrlapCb->RemoteWinSize = IRLAP_DEFAULT_WIN_SIZE;
+ pIrlapCb->RemoteNumBOFS = IRLAP_DEFAULT_BOFS;
+
+ pIrlapCb->ConnAddr = IRLAP_BROADCAST_CONN_ADDR;
+
+ pIrlapCb->N1 = 0; // calculated at negotiation
+ pIrlapCb->N2 = 0;
+ pIrlapCb->N3 = 5; // recalculated after negotiation ??
+
+#ifdef DEBUG
+ 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);
+
+ IrdaTimerInitialize(&pIrlapCb->FinalTimer,
+ FinalTimerExp,
+ pIrlapCb->LocalMaxTAT,
+ pIrlapCb);
+
+ IrdaTimerInitialize(&pIrlapCb->SlotTimer,
+ SlotTimerExp,
+ IRLAP_SLOT_TIMEOUT,
+ pIrlapCb);
+
+ IrdaTimerInitialize(&pIrlapCb->QueryTimer,
+ QueryTimerExp,
+ (IRLAP_MAX_SLOTS + 4) * IRLAP_SLOT_TIMEOUT*2,
+ pIrlapCb);
+
+ IrdaTimerInitialize(&pIrlapCb->WDogTimer,
+ WDogTimerExp,
+ 3000,
+ pIrlapCb);
+
+ IrdaTimerInitialize(&pIrlapCb->BackoffTimer,
+ BackoffTimerExp,
+ 0,
+ pIrlapCb);
+
+ // Initialize Link
+ IMsg.Prim = MAC_CONTROL_REQ;
+ IMsg.IRDA_MSG_Op = MAC_INITIALIZE_LINK;
+ IMsg.IRDA_MSG_Baud = IRLAP_DEFAULT_BAUD;
+ IMsg.IRDA_MSG_NumBOFs = IRLAP_DEFAULT_BOFS;
+ IMsg.IRDA_MSG_DataSize = IRLAP_DEFAULT_DATA_SIZE;
+ IMsg.IRDA_MSG_MinTat = 0;
+
+ rc = IrmacDown(pIrlapCb->pIrdaLinkCb, &IMsg);
+
+ *Status = rc;
+ return;
+}
+
+
+VOID
+IrlapCloseLink(PIRLAP_CB pIrlapCb)
+{
+ return;
+}
+
+/*****************************************************************************
+*
+* @func UINT | InitializeState | resets link control block
+*
+* @parm IRLAP_STN_TYPE | StationType| sets station type and the CRBit
+* in the control block
+*/
+UINT
+InitializeState(PIRLAP_CB pIrlapCb,
+ IRLAP_STN_TYPE StationType)
+{
+ 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;
+
+ ClearDevList(&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 window
+ RetOnErr(ReturnTxMsgs(pIrlapCb));
+
+ // Cleanup RxWin
+ pIrlapCb->RxWin.Start = 0;
+ pIrlapCb->RxWin.End = 0;
+ for (i = 0; i < IRLAP_MOD; i++)
+ {
+ // Receive window
+ if (pIrlapCb->RxWin.pMsg[i] != NULL)
+ {
+ /* RETURN THESE BACK TO NDIS
+ RetOnErr(EnqueMsgList(&pIrlapCb->RxMsgFreeList,
+ pIrlapCb->RxWin.pMsg[i],
+ pIrlapCb->MaxRxMsgFreeListLen));
+ */
+ pIrlapCb->RxWin.pMsg[i] = NULL;
+ }
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc return desc
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*/
+/*
+UINT
+IRLAP_Shutdown()
+{
+ UINT rc = SUCCESS;
+
+ IRLAP_LOG_START(pIrlapCb, (TEXT("IRLAP Shutdown")));
+
+ if ((rc = ReturnTxMsgs(pIrlapCb)) == SUCCESS)
+ {
+ // Shutdown Link
+ IMsg.Prim = MAC_CONTROL_REQ;
+ IMsg.IRDA_MSG_Op = MAC_SHUTDOWN_LINK;
+ rc = IrmacDown(pIrlapCb->pIrdaLinkCb,&IMsg);
+ }
+ if (pIrlapCb->pRxMsgOut != NULL)
+ {
+ IRDA_FREE_MEM(pIrlapCb->pRxMsgOut);
+ }
+
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->SlotTimer);
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->QueryTimer);
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->PollTimer);
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->BackoffTimer);
+ IRLAP_TimerStop(pIrlapCb, IRMAC_MediaSenseTimer);
+
+ IRLAP_LOG_COMPLETE(pIrlapCb);
+
+ return rc;
+}
+*/
+/*****************************************************************************
+*
+* @func UINT | IrlapDown | Entry point into IRLAP for LMP
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag IRLAP_BAD_PRIMITIVE | Received message that didn't contain one
+* of the primitives defined below
+* IRLAP_NOT_INITIALIZED | IRLAP has not been intialize with
+* IrlapInitialize()
+*
+* @parm IRDA_MSG * | pMsg | Pointer to an IRDA Message
+*
+* @comm Processes the following service requests:
+* IRLAP_DISCOVERY_REQ,
+* IRLAP_CONNECT_REQ,
+* IRLAP_CONNECT_RESP,
+* IRLAP_DISCONNECT_REQ,
+* IRLAP_DATA_REQ,
+* IRLAP_UDATA_REQ,
+*/
+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:
+ rc = ProcessConnectResp(pIrlapCb, pMsg);
+ break;
+
+ case IRLAP_DISCONNECT_REQ:
+ rc = 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;
+
+ default:
+ rc = IRLAP_BAD_PRIM;
+
+ }
+
+ IRLAP_LOG_COMPLETE(pIrlapCb);
+
+ return (rc);
+}
+/*****************************************************************************
+*
+* @func UINT | IrlapUp | Entry point into IRLAP for MAC
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag IRLAP_BAD_PRIMITIVE | Received message that didn't contain one
+* of the primitives defined below
+* IRLAP_NOT_INITIALIZED | IRLAP has not been intialize with
+* IrlapInitialize()
+*
+* @parm IRDA_MSG * | pMsg | Pointer to an IRDA Message
+*
+* @comm Processes the following service requests:
+* MAC_DATA_IND
+* MAC_CONTROL_CONF
+*/
+UINT
+IrlapUp(PVOID Context, PIRDA_MSG pMsg)
+{
+ UINT rc = SUCCESS;
+ BOOL FreeMsg = TRUE;
+ PIRLAP_CB pIrlapCb = (PIRLAP_CB) Context;
+
+ // Whats this again ??? !!! pIrlapCb->pRxMsgOut = NULL;
+
+ ASSERT(pIrlapCb->Sig == IRLAP_CB_SIG);
+
+ 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")));
+
+ rc = ProcessMACDataInd(pIrlapCb, pMsg, &FreeMsg);
+
+ /* What dis all about?
+ if (FreeMsg && SUCCESS == rc)
+ {
+ rc = EnqueMsgList(&pIrlapCb->RxMsgFreeList, pMsg,
+ pIrlapCb->MaxRxMsgFreeListLen);
+ }
+ */
+ break;
+
+ case MAC_CONTROL_CONF:
+ IRLAP_LOG_START((pIrlapCb, IRDA_PrimStr[pMsg->Prim]));
+ rc = ProcessMACControlConf(pIrlapCb, pMsg);
+ break;
+
+ default:
+ IRLAP_LOG_START((pIrlapCb, IRDA_PrimStr[pMsg->Prim]));
+ rc = IRLAP_BAD_PRIM;
+
+ }
+
+ IRLAP_LOG_COMPLETE(pIrlapCb);
+
+ return (rc);
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc return desc
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+
+/* THIS FUCKER GOES
+UINT
+IRLAP_GetRxMsg(IRDA_MSG **ppMsg)
+{
+ UINT rc = SUCCESS;
+
+ ASSERT(pIrlapCb->pRxMsgOut == NULL);
+
+ if ((rc = DequeMsgList(&pIrlapCb->RxMsgFreeList, ppMsg)) == SUCCESS)
+ {
+ (*ppMsg)->IRDA_MSG_pBase = ((BYTE *) (*ppMsg)) + sizeof(IRDA_MSG);
+ (*ppMsg)->IRDA_MSG_pLimit = ((BYTE *) (*ppMsg)) +
+ sizeof(IRDA_MSG)+ 5 + pIrlapCb->LocalDataSize;
+
+ pIrlapCb->pRxMsgOut = *ppMsg;
+ }
+
+ return rc;
+}
+*/
+
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ReturnTxMsgs(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;
+ RetOnErr(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;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, pIrlapCb->TxWin.pMsg[i]));
+
+ pIrlapCb->TxWin.pMsg[i] = NULL;
+ }
+ }
+
+ return SUCCESS;
+}
+
+/*****************************************************************************
+*
+* @func BOOL | MyDevAddr | Determines if DevAddr matches the local
+* device address or is the broadcast
+*
+* @rdesc TRUE if address is mine or broadcast else FALS
+*
+* @parm BYTE [] | DevAddr | Device Address
+*
+*/
+BOOL
+MyDevAddr(PIRLAP_CB pIrlapCb,
+ BYTE DevAddr[])
+{
+ if (memcmp(DevAddr, IRLAP_BroadcastDevAddr, IRDA_DEV_ADDR_LEN) != 0 &&
+ memcmp(DevAddr, pIrlapCb->LocalDevice.DevAddr, IRDA_DEV_ADDR_LEN) != 0)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*****************************************************************************
+*
+* @func UINT | ProcessConnectReq | Process connect request from LMP
+*
+* @rdesc 0, otherwise one of the following errors:
+* @flag IRLAP_BAD_STATE | Requested connection in an invalid state
+*
+* @parm IRDA_MSG * | pMsg | pointer to an IRDA_MSG
+*
+* @comm
+* comments
+*/
+UINT
+ProcessConnectReq(PIRLAP_CB pIrlapCb,
+ PIRDA_MSG pMsg)
+{
+ switch (pIrlapCb->State)
+ {
+ case NDM:
+ // Save Remote Address for later use
+ memcpy(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;
+
+ RetOnErr(IrmacDown(pIrlapCb->pIrdaLinkCb,&IMsg));
+ pIrlapCb->State = CONN_MEDIA_SENSE;
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ (media sense)")));
+ break;
+
+ case DSCV_REPLY:
+ return IRLAP_REMOTE_DISCOVERY_IN_PROGRESS_ERR;
+
+ case P_CLOSE:
+ memcpy(pIrlapCb->RemoteDevice.DevAddr,
+ pMsg->IRDA_MSG_RemoteDevAddr, IRDA_DEV_ADDR_LEN);
+ pIrlapCb->ConnAfterClose = TRUE;
+ break;
+
+ default:
+ return IRLAP_BAD_STATE;
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func UINT | ProcessConnectResp | Process connect response from LMP
+*
+* @rdesc 0, otherwise one of the following errors:
+* @flag IRLAP_BAD_STATE | Requested connection in an invalid state
+*
+* @parm IRDA_MSG * | pMsg | pointer to an IRDA_MSG
+*
+* @comm
+* comments
+*/
+UINT
+ProcessConnectResp(PIRLAP_CB pIrlapCb,
+ PIRDA_MSG pMsg)
+{
+
+ if (pIrlapCb->State != SNRM_RECEIVED)
+ {
+ return IRLAP_BAD_STATE;
+ }
+
+ pIrlapCb->ConnAddr = pIrlapCb->SNRMConnAddr;
+ RetOnErr(SendUA(pIrlapCb, TRUE));
+ RetOnErr(ApplyQosParms(pIrlapCb));
+
+ RetOnErr(InitializeState(pIrlapCb, SECONDARY));
+ // start watchdog timer with poll timeout
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ pIrlapCb->State = S_NRM;
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func UINT | ProcessDiscoveryReq | Process Discovery request from LMP
+*
+* @rdesc 0, otherwise one of the following errors:
+* @flag IRLAP_BAD_STATE | Requested discovery in an invalid state
+*
+* @comm
+* comments
+*/
+UINT
+ProcessDiscoveryReq(PIRLAP_CB pIrlapCb,
+ PIRDA_MSG pMsg)
+{
+ IRDA_MSG IMsg;
+
+ switch (pIrlapCb->State)
+ {
+ case NDM:
+ if (pMsg->IRDA_MSG_SenseMedia == TRUE)
+ {
+ IMsg.Prim = MAC_CONTROL_REQ;
+ IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
+ IMsg.IRDA_MSG_SenseTime = IRLAP_MEDIA_SENSE_TIME;
+ RetOnErr(IrmacDown(pIrlapCb->pIrdaLinkCb,&IMsg));
+ pIrlapCb->State = DSCV_MEDIA_SENSE;
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ (media sense)")));
+ }
+ else
+ {
+ pIrlapCb->SlotCnt = 0;
+ pIrlapCb->GenNewAddr = FALSE;
+
+ ClearDevList(&pIrlapCb->DevList);
+
+ RetOnErr(SendDscvXIDCmd(pIrlapCb));
+
+ IMsg.Prim = MAC_CONTROL_REQ;
+ IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
+ IMsg.IRDA_MSG_SenseTime = IRLAP_DSCV_SENSE_TIME;
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ (dscv sense)")));
+ RetOnErr(IrmacDown(pIrlapCb->pIrdaLinkCb,&IMsg));
+
+ pIrlapCb->State = DSCV_QUERY;
+ }
+ break;
+
+ case DSCV_REPLY:
+ return IRLAP_REMOTE_DISCOVERY_IN_PROGRESS_ERR;
+
+ case SNRM_RECEIVED:
+ return IRLAP_REMOTE_CONNECTION_IN_PROGRESS_ERR;
+
+ case P_CLOSE:
+ pIrlapCb->DscvAfterClose = TRUE;
+ break;
+
+ default:
+ return IRLAP_BAD_STATE;
+ }
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func UINT | ProcessDisconnectReq | Process disconnect request from LMP
+*
+* @rdesc 0, otherwise one of the following errors:
+* @flag IRLAP_BAD_STATE | Requested disconnect in an invalid state
+*
+* @comm
+* comments
+*/
+UINT
+ProcessDisconnectReq(PIRLAP_CB pIrlapCb)
+{
+ RetOnErr(ReturnTxMsgs(pIrlapCb));
+
+ switch (pIrlapCb->State)
+ {
+ case NDM:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ break;
+
+ case SNRM_SENT:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ case DSCV_MEDIA_SENSE:
+ case DSCV_QUERY:
+ case DSCV_REPLY:
+ case CONN_MEDIA_SENSE:
+ pIrlapCb->State = NDM;
+ break;
+
+ case BACKOFF_WAIT:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->BackoffTimer);
+ pIrlapCb->State = NDM;
+ break;
+
+ case SNRM_RECEIVED:
+ pIrlapCb->ConnAddr = pIrlapCb->SNRMConnAddr;
+ RetOnErr(SendDM(pIrlapCb));
+ pIrlapCb->ConnAddr = IRLAP_BROADCAST_CONN_ADDR;
+ pIrlapCb->State = NDM;
+ break;
+
+ case P_XMIT:
+ pIrlapCb->LocalDiscReq = TRUE;
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->PollTimer);
+ RetOnErr(SendDISC(pIrlapCb));
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ pIrlapCb->RetryCnt = 0;
+ pIrlapCb->State = P_CLOSE;
+ break;
+
+ case P_RECV:
+ pIrlapCb->LocalDiscReq = TRUE;
+ pIrlapCb->State = P_DISCONNECT_PEND;
+ break;
+
+ case S_NRM:
+ pIrlapCb->LocalDiscReq = TRUE;
+ pIrlapCb->State = S_DISCONNECT_PEND;
+ break;
+
+ default:
+ return IRLAP_BAD_STATE;
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func UINT | ProcessDataReq | Process data request from LMP
+*
+* @rdesc 0, otherwise one of the following errors:
+* @flag IRLAP_BAD_STATE | Requested data in an invalid state
+* @flag IRLAP_TX_MSG_LIST_FULL | Tx Msg List has become full, can't process
+*
+* @comm
+* comments
+*/
+UINT
+ProcessDataAndUDataReq(PIRLAP_CB pIrlapCb,
+ PIRDA_MSG pMsg)
+{
+ BOOL LinkTurned;
+ int DataSize = (pMsg->IRDA_MSG_pHdrWrite - pMsg->IRDA_MSG_pHdrRead) +
+ (pMsg->IRDA_MSG_pWrite - pMsg->IRDA_MSG_pRead);
+
+ if (DataSize > pIrlapCb->RemoteDataSize)
+ {
+ return IRLAP_BAD_DATA_REQUEST;
+ }
+
+ switch (pIrlapCb->State)
+ {
+ case P_XMIT:
+ // Enque message, then drain the message list. If the link
+ // was turned in the process of draining messages stop Poll Timer,
+ // start Final Timer and enter P_RECV. Otherwise we'll stay in P_XMIT
+ // waiting for more data requests from LMP or Poll Timer expiration
+ RetOnErr(EnqueMsgList(&pIrlapCb->TxMsgList, pMsg, -1));
+
+ RetOnErr(XmitTxMsgList(pIrlapCb, FALSE, &LinkTurned));
+
+ if (LinkTurned)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->PollTimer);
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ pIrlapCb->State = P_RECV;
+ }
+ return SUCCESS;
+
+ case P_DISCONNECT_PEND: // For pending disconnect states, take the message.
+ case S_DISCONNECT_PEND: // They will be returned when the link disconnects
+ case P_RECV:
+ case S_NRM:
+ // Que the message for later transmission
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Queueing request")));
+
+ RetOnErr(EnqueMsgList(&pIrlapCb->TxMsgList, pMsg, -1));
+
+ return SUCCESS;
+
+ default:
+ if (pMsg->Prim == IRLAP_DATA_REQ)
+ {
+ return IRLAP_BAD_STATE;
+ }
+ else
+ {
+ if (pIrlapCb->State == NDM)
+ {
+ return SendUIFrame(pIrlapCb, pMsg);
+ }
+ else
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ }
+ }
+ }
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+XmitTxMsgList(PIRLAP_CB pIrlapCb, BOOL AlwaysTurnLink, BOOL *pLinkTurned)
+{
+ UINT rc = SUCCESS;
+ IRDA_MSG *pMsg;
+ UINT LinkTurned;
+
+ LinkTurned = FALSE;
+
+ // If the remote is not busy send data
+ // If we need to clear the local busy condition, don't send data send RR
+ if (!pIrlapCb->RemoteBusy && !pIrlapCb->ClrLocalBusy)
+ {
+ while ((rc == SUCCESS) && !LinkTurned &&
+ (DequeMsgList(&pIrlapCb->TxMsgList, &pMsg) == SUCCESS))
+ {
+ if (pMsg->Prim == IRLAP_DATA_REQ)
+ {
+ // Insert message into transmit window
+ pIrlapCb->TxWin.pMsg[pIrlapCb->Vs] = pMsg;
+
+ // Send message. If full window or there are no
+ // more data requests, send with PF Set (turns link).
+ if ((pIrlapCb->Vs == (pIrlapCb->TxWin.Start +
+ pIrlapCb->RemoteWinSize-1) % IRLAP_MOD) ||
+ (0 == pIrlapCb->TxMsgList.Len /*AlwaysTurnLink*/))
+ {
+ rc = SendIFrame(pIrlapCb,
+ pMsg,
+ pIrlapCb->Vs,
+ IRLAP_PFBIT_SET);
+ LinkTurned = TRUE;
+ }
+ else
+ {
+ rc = SendIFrame(pIrlapCb,
+ pMsg,
+ pIrlapCb->Vs,
+ IRLAP_PFBIT_CLEAR);
+ }
+ pIrlapCb->Vs = (pIrlapCb->Vs + 1) % IRLAP_MOD;
+ }
+ else // IRLAP_UDATA_REQUEST
+ {
+ // For now, always turn link
+ rc = SendUIFrame(pIrlapCb, pMsg);
+ pMsg->Prim = IRLAP_UDATA_CONF;
+ pMsg->IRDA_MSG_DataStatus = IRLAP_DATA_REQUEST_COMPLETED;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, pMsg));
+ LinkTurned = TRUE;
+ }
+ }
+ pIrlapCb->TxWin.End = pIrlapCb->Vs;
+ }
+
+ if (rc == SUCCESS)
+ {
+ if ((AlwaysTurnLink && !LinkTurned) || pIrlapCb->ClrLocalBusy)
+ {
+ rc = SendRR_RNR(pIrlapCb);
+ LinkTurned = TRUE;
+ if (pIrlapCb->ClrLocalBusy)
+ {
+ pIrlapCb->ClrLocalBusy = FALSE;
+ }
+ }
+ }
+
+ if (pLinkTurned != NULL)
+ {
+ *pLinkTurned = LinkTurned;
+ }
+
+ return (rc);
+}
+
+UINT
+GotoPCloseState(PIRLAP_CB pIrlapCb)
+{
+ if (!pIrlapCb->LocalDiscReq)
+ {
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_REMOTE_INITIATED;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ }
+
+ pIrlapCb->State = P_CLOSE;
+
+ return SUCCESS;
+}
+
+UINT
+GotoNDMThenDscvOrConn(PIRLAP_CB pIrlapCb)
+{
+ if (pIrlapCb->ConnAfterClose)
+ {
+ pIrlapCb->ConnAfterClose = FALSE;
+ IMsg.Prim = MAC_CONTROL_REQ;
+ IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
+ IMsg.IRDA_MSG_SenseTime = IRLAP_MEDIA_SENSE_TIME;
+
+ RetOnErr(IrmacDown(pIrlapCb->pIrdaLinkCb,&IMsg));
+ pIrlapCb->State = CONN_MEDIA_SENSE;
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ (media sense)")));
+
+ return SUCCESS;
+ }
+
+ if (pIrlapCb->DscvAfterClose)
+ {
+ pIrlapCb->DscvAfterClose = FALSE;
+ IMsg.Prim = MAC_CONTROL_REQ;
+ IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
+ IMsg.IRDA_MSG_SenseTime = IRLAP_MEDIA_SENSE_TIME;
+ RetOnErr(IrmacDown(pIrlapCb->pIrdaLinkCb,&IMsg));
+ pIrlapCb->State = DSCV_MEDIA_SENSE;
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ (media sense)")));
+ return SUCCESS;
+ }
+ pIrlapCb->State = NDM;
+ return SUCCESS;
+}
+
+/*****************************************************************************
+*
+* @func UINT | ProcessMACControlConf | Process a control confirm from MAC
+*
+* @rdesc SUCCESS, otherwise one of the following error codes
+* @flag IRLAP_BAD_OP | Bad Operation, must be MAC_MEDIA_SENSE
+* @flag IRLAP_BAD_OPSTATUS | Invalid return status for operation
+* @flag IRLAP_BAD_STATE | CONTROL_CONF in invalid state
+*
+* @parm IRDA_MSG * | pMsg | pointer to an IRDA_MSG
+*
+* @comm
+* comments
+*
+*/
+UINT
+ProcessMACControlConf(PIRLAP_CB pIrlapCb, PIRDA_MSG pMsg)
+{
+ if (pMsg->IRDA_MSG_Op != MAC_MEDIA_SENSE)
+ return IRLAP_BAD_OP;
+
+ switch (pIrlapCb->State)
+ {
+ case DSCV_MEDIA_SENSE:
+ switch (pMsg->IRDA_MSG_OpStatus)
+ {
+ case MAC_MEDIA_CLEAR:
+ pIrlapCb->SlotCnt = 0;
+ pIrlapCb->GenNewAddr = FALSE;
+
+ ClearDevList(&pIrlapCb->DevList);
+
+ RetOnErr(SendDscvXIDCmd(pIrlapCb));
+
+ pMsg->Prim = MAC_CONTROL_REQ;
+ pMsg->IRDA_MSG_Op = MAC_MEDIA_SENSE;
+ pMsg->IRDA_MSG_SenseTime = IRLAP_DSCV_SENSE_TIME;
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ (dscv sense)")));
+ RetOnErr(IrmacDown(pIrlapCb->pIrdaLinkCb,pMsg));
+
+ pIrlapCb->State = DSCV_QUERY;
+ break;
+
+ case MAC_MEDIA_BUSY:
+ IMsg.Prim = IRLAP_DISCOVERY_CONF;
+ IMsg.IRDA_MSG_pDevList = NULL;
+ IMsg.IRDA_MSG_DscvStatus = MAC_MEDIA_BUSY;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ pIrlapCb->State = NDM;
+ break;
+
+ default:
+ return IRLAP_BAD_OPSTATUS;
+ }
+ break;
+
+ case CONN_MEDIA_SENSE:
+ switch (pMsg->IRDA_MSG_OpStatus)
+ {
+ case MAC_MEDIA_CLEAR:
+
+ // Generate a random connection address
+ pIrlapCb->ConnAddr = IRLAP_RAND(1, 0x7e);
+
+ pIrlapCb->RetryCnt = 0;
+
+ RetOnErr(SendSNRM(pIrlapCb, TRUE));
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ pIrlapCb->State = SNRM_SENT;
+ break;
+
+ case MAC_MEDIA_BUSY:
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ IMsg.IRDA_MSG_DiscStatus = MAC_MEDIA_BUSY;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ pIrlapCb->State = NDM;
+ break;
+
+ default:
+ return IRLAP_BAD_OPSTATUS;
+ }
+ break;
+
+ case DSCV_QUERY:
+ switch (pMsg->IRDA_MSG_OpStatus)
+ {
+ case MAC_MEDIA_CLEAR:
+ // Nobody responded, procede as if the slot timer expired
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Media clear, making fake slot exp")));
+
+ SlotTimerExp(pIrlapCb);
+ break;
+
+ case MAC_MEDIA_BUSY:
+ // Some responding, give'm more time
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Media busy, starting slot timer")));
+
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->SlotTimer);
+ break;
+ }
+ break;
+
+ default:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func UINT | ProcessMACDataInd | Processes MAC Data
+*
+* @rdesc SUCCESS, otherwise one of the following error codes
+* @flag ?? | invalid return status for operation
+*
+* @parm IRDA_MSG * | pMsg | pointer to an IRDA_MSG
+*
+* @comm
+*
+*/
+UINT
+ProcessMACDataInd(PIRLAP_CB pIrlapCb, PIRDA_MSG pMsg, BOOL *pFreeMsg)
+{
+ int Addr = (int) IRLAP_GET_ADDR(*(pMsg->IRDA_MSG_pRead));
+ int CRBit = (int) IRLAP_GET_CRBIT(*(pMsg->IRDA_MSG_pRead));
+ int Cntl = (int) *(pMsg->IRDA_MSG_pRead + 1);
+ int PFBit = IRLAP_GET_PFBIT(Cntl);
+ UINT Ns = IRLAP_GET_NS(Cntl);
+ UINT Nr = IRLAP_GET_NR(Cntl);
+ int XIDFormatID = (int) *(pMsg->IRDA_MSG_pRead+2);
+ IRLAP_XID_DSCV_FORMAT *pXIDFormat = (IRLAP_XID_DSCV_FORMAT *)
+ (pMsg->IRDA_MSG_pRead + 3);
+ IRLAP_SNRM_FORMAT *pSNRMFormat = (IRLAP_SNRM_FORMAT *)
+ (pMsg->IRDA_MSG_pRead + 2);
+ IRLAP_UA_FORMAT *pUAFormat = (IRLAP_UA_FORMAT *)
+ (pMsg->IRDA_MSG_pRead + 2);
+
+ if (Addr != pIrlapCb->ConnAddr && Addr != IRLAP_BROADCAST_CONN_ADDR)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb,
+ TEXT("Ignoring, connection address %02X"), Addr));
+ return SUCCESS;
+ }
+
+ pIrlapCb->StatusSent = FALSE; // don't ask
+
+ FrmRejFormat.CntlField = Cntl; // for later maybe
+
+ // Peer has sent a frame so clear the NoResponse condition
+ if (pIrlapCb->NoResponse)
+ {
+ pIrlapCb->NoResponse = FALSE;
+ pIrlapCb->RetryCnt = 0;
+ pIrlapCb->WDogExpCnt = 0;
+ }
+
+ switch (IRLAP_FRAME_TYPE(Cntl))
+ {
+ /*****************/
+ case IRLAP_I_FRAME:
+ /*****************/
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("I-frame")));
+ return ProcessIFrame(pIrlapCb, pMsg,
+ CRBit, PFBit, Ns, Nr, pFreeMsg);
+
+ /*****************/
+ case IRLAP_S_FRAME:
+ /*****************/
+ switch (IRLAP_GET_SCNTL(Cntl))
+ {
+ /*-----------*/
+ case IRLAP_RR:
+ case IRLAP_RNR:
+ /*-----------*/
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("RR/RNR-frame")));
+ return ProcessRR_RNR(pIrlapCb,
+ IRLAP_GET_SCNTL(Cntl),
+ pMsg, CRBit, PFBit, Nr);
+ /*------------*/
+ case IRLAP_SREJ:
+ case IRLAP_REJ:
+ /*------------*/
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("SJREJ/REJ-frame")));
+ return ProcessREJ_SREJ(pIrlapCb,
+ IRLAP_GET_SCNTL(Cntl),
+ pMsg, CRBit, PFBit, Nr);
+ }
+ break;
+
+ /*****************/
+ case IRLAP_U_FRAME:
+ /*****************/
+ switch (IRLAP_GET_UCNTL(Cntl))
+ {
+ /*---------------*/
+ case IRLAP_XID_CMD:
+ /*---------------*/
+ // Should always be a command
+ if (CRBit != IRLAP_CMD)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Received XID cmd with CRBit = rsp")));
+ return IRLAP_XID_CMD_RSP;
+ }
+ // Poll bit should always be set
+ if (PFBit != IRLAP_PFBIT_SET)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb,
+ TEXT("Received XID command without Poll set")));
+ return IRLAP_XID_CMD_NOT_P;
+ }
+
+ if (XIDFormatID == IRLAP_XID_DSCV_FORMAT_ID)
+ {
+ // Slot No is less than max slot or 0xff
+ if (pXIDFormat->SlotNo>IRLAP_SlotTable[pXIDFormat->NoOfSlots]
+ && pXIDFormat->SlotNo != IRLAP_END_DSCV_SLOT_NO)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Invalid slot number %d"),
+ pXIDFormat->SlotNo));
+ return IRLAP_BAD_SLOTNO;
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("DscvXIDCmd")));
+ return ProcessDscvXIDCmd(pIrlapCb,
+ pXIDFormat,
+ pMsg->IRDA_MSG_pWrite);
+ }
+ else
+ {
+ return SUCCESS; // ignore per errata
+ }
+
+ /*---------------*/
+ case IRLAP_XID_RSP:
+ /*---------------*/
+ if (XIDFormatID == IRLAP_XID_DSCV_FORMAT_ID)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("DscvXIDRsp")));
+ return ProcessDscvXIDRsp(pIrlapCb,
+ pXIDFormat,pMsg->IRDA_MSG_pWrite);
+ }
+ else
+ {
+ return SUCCESS; // ignore per errata
+ }
+
+ /*------------*/
+ case IRLAP_SNRM: // or IRLAP_RNRM
+ /*------------*/
+ if (IRLAP_PFBIT_SET != PFBit)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Received SNRM/RNRM without P set")));
+ return IRLAP_SNRM_NOT_P;
+ }
+ if (IRLAP_CMD == CRBit)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("SNRM")));
+ return ProcessSNRM(pIrlapCb,
+ pSNRMFormat,
+ pMsg->IRDA_MSG_pWrite);
+ }
+ else
+ {
+ return ProcessRNRM(pIrlapCb);
+ }
+
+ /*----------*/
+ case IRLAP_UA:
+ /*----------*/
+ if (CRBit != IRLAP_RSP)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Received UA as a command")));
+ return IRLAP_UA_NOT_RSP;
+ }
+ if (PFBit != IRLAP_PFBIT_SET)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Received UA without F set")));
+ return IRLAP_UA_NOT_F;
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("UA")));
+ return ProcessUA(pIrlapCb, pUAFormat, pMsg->IRDA_MSG_pWrite);
+
+ /*------------*/
+ case IRLAP_DISC: // or IRLAP_RD
+ /*------------*/
+ if (IRLAP_PFBIT_SET != PFBit)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb,
+ TEXT("Received DISC/RD command without Poll set")));
+ return IRLAP_DISC_CMD_NOT_P;
+ }
+ if (IRLAP_CMD == CRBit)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("DISC")));
+ return ProcessDISC(pIrlapCb);
+ }
+ else
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("RD")));
+ return ProcessRD(pIrlapCb);
+ }
+
+ /*----------*/
+ case IRLAP_UI:
+ /*----------*/
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("UI")));
+ return ProcessUI(pIrlapCb, pMsg, CRBit, PFBit);
+
+ /*------------*/
+ case IRLAP_TEST:
+ /*------------*/
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("TEST")));
+ return ProcessTEST(pIrlapCb, pMsg, pUAFormat, CRBit, PFBit);
+
+ /*------------*/
+ case IRLAP_FRMR:
+ /*------------*/
+ if (IRLAP_RSP != CRBit)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Received FRMR cmd (must be resp)")));
+ return IRLAP_FRMR_RSP_CMD;
+ }
+ if (IRLAP_PFBIT_SET != PFBit)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb,
+ TEXT("Received FRMR resp without Final set")));
+ return IRLAP_FRMR_RSP_NOT_F;
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("FRMR")));
+ return ProcessFRMR(pIrlapCb);
+
+ /*----------*/
+ case IRLAP_DM:
+ /*----------*/
+ if (IRLAP_RSP != CRBit)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb,
+ TEXT("Received DM command (must be response)")));
+ return IRLAP_DM_RSP_CMD;
+ }
+ if (IRLAP_PFBIT_SET != PFBit)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb,
+ TEXT("Received DM response without Final set")));
+ return IRLAP_DM_RSP_NOT_F;
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("DM")));
+ return ProcessDM(pIrlapCb);
+ }
+ break;
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func UINT | ProcessDscvXIDCmd | Process received XID Discovery command
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*/
+UINT
+ProcessDscvXIDCmd(PIRLAP_CB pIrlapCb,
+ IRLAP_XID_DSCV_FORMAT *pXIDFormat,
+ BYTE *pEndDscvInfoByte)
+{
+ if (!MyDevAddr(pIrlapCb, pXIDFormat->DestAddr))
+ {
+/* IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring XID addressed to:%02X%02X%02X%02X"),
+ EXPAND_ADDR(pXIDFormat->DestAddr)));*/
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring XID addressed to %X"),
+ pXIDFormat->DestAddr));
+ return SUCCESS;
+ }
+
+ if (pXIDFormat->SlotNo == IRLAP_END_DSCV_SLOT_NO)
+ {
+ pIrlapCb->GenNewAddr = FALSE;
+ switch (pIrlapCb->State)
+ {
+ case DSCV_QUERY:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->SlotTimer);
+
+ IMsg.Prim = IRLAP_DISCOVERY_CONF;
+ IMsg.IRDA_MSG_pDevList = NULL;
+ IMsg.IRDA_MSG_DscvStatus =
+ IRLAP_REMOTE_DISCOVERY_IN_PROGRESS;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ // fall through. Send indication to LMP
+
+ case DSCV_REPLY:
+ if (pIrlapCb->State == DSCV_REPLY)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->QueryTimer);
+ }
+
+ // Place the device information in the control block
+ ExtractDeviceInfo(&pIrlapCb->RemoteDevice, pXIDFormat,
+ pEndDscvInfoByte);
+
+ if (!DevInDevList(pXIDFormat->SrcAddr, &pIrlapCb->DevList))
+ {
+ RetOnErr(AddDevToList(pIrlapCb,
+ pXIDFormat,
+ pEndDscvInfoByte));
+ }
+
+ // Notifiy LMP
+ IMsg.Prim = IRLAP_DISCOVERY_IND;
+ IMsg.IRDA_MSG_pDevList = &pIrlapCb->DevList;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ pIrlapCb->State = NDM;
+ break;
+
+ default:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring End XID in this state")));
+ }
+ }
+ else // in middle of discovery process
+ {
+ switch (pIrlapCb->State)
+ {
+ case DSCV_MEDIA_SENSE:
+ IMsg.Prim = IRLAP_DISCOVERY_CONF;
+ IMsg.IRDA_MSG_pDevList = NULL;
+ IMsg.IRDA_MSG_DscvStatus =
+ IRLAP_REMOTE_DISCOVERY_IN_PROGRESS;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ // fall through
+
+ case NDM:
+ RetOnErr(InitDscvCmdProcessing(pIrlapCb, pXIDFormat));
+ pIrlapCb->State = DSCV_REPLY;
+ break;
+
+ case DSCV_QUERY:
+ IMsg.Prim = IRLAP_DISCOVERY_CONF;
+ IMsg.IRDA_MSG_pDevList = NULL;
+ IMsg.IRDA_MSG_DscvStatus = IRLAP_DISCOVERY_COLLISION;
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->SlotTimer);
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ pIrlapCb->State = NDM;
+ break;
+
+ case DSCV_REPLY:
+ if (pXIDFormat->GenNewAddr)
+ {
+ pIrlapCb->GenNewAddr = TRUE;
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->QueryTimer);
+ RetOnErr(InitDscvCmdProcessing(pIrlapCb, pXIDFormat));
+ }
+ else
+ {
+ if (pIrlapCb->RespSlot <= pXIDFormat->SlotNo &&
+ !pIrlapCb->DscvRespSent)
+ {
+ RetOnErr(SendDscvXIDRsp(pIrlapCb));
+ pIrlapCb->DscvRespSent = TRUE;
+ }
+ }
+ break;
+
+ default:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ }
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+void
+ExtractDeviceInfo(IRDA_DEVICE *pDevice, IRLAP_XID_DSCV_FORMAT *pXIDFormat,
+ BYTE *pEndDscvInfoByte)
+{
+ memcpy(pDevice->DevAddr, pXIDFormat->SrcAddr, IRDA_DEV_ADDR_LEN);
+ pDevice->IRLAP_Version = pXIDFormat->Version;
+
+ // ??? what about DscvMethod
+
+ pDevice->DscvInfoLen = pEndDscvInfoByte > &pXIDFormat->FirstDscvInfoByte ?
+ pEndDscvInfoByte-&pXIDFormat->FirstDscvInfoByte :
+ 0;
+ memcpy(pDevice->DscvInfo, &pXIDFormat->FirstDscvInfoByte,
+ pDevice->DscvInfoLen);
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+InitDscvCmdProcessing(PIRLAP_CB pIrlapCb,
+ IRLAP_XID_DSCV_FORMAT *pXIDFormat)
+{
+ pIrlapCb->RemoteMaxSlot = IRLAP_SlotTable[pXIDFormat->NoOfSlots];
+
+ pIrlapCb->RespSlot = IRLAP_RAND(pXIDFormat->SlotNo,
+ pIrlapCb->RemoteMaxSlot - 1);
+
+ memcpy(pIrlapCb->RemoteDevice.DevAddr, pXIDFormat->SrcAddr, IRDA_DEV_ADDR_LEN);
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Responding in slot %d to device %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)
+ {
+ RetOnErr(SendDscvXIDRsp(pIrlapCb));
+ pIrlapCb->DscvRespSent = TRUE;
+ }
+ else
+ {
+ pIrlapCb->DscvRespSent = FALSE;
+ }
+
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->QueryTimer);
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func UINT | ProcessDscvXIDRsp | Process received XID Discovery response
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*/
+UINT
+ProcessDscvXIDRsp(PIRLAP_CB pIrlapCb,
+ IRLAP_XID_DSCV_FORMAT *pXIDFormat,
+ BYTE *pEndDscvInfoByte)
+{
+ if (pIrlapCb->State == DSCV_QUERY)
+ {
+
+ if (DevInDevList(pXIDFormat->SrcAddr, &pIrlapCb->DevList))
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->SlotTimer);
+ pIrlapCb->SlotCnt = 0;
+ pIrlapCb->GenNewAddr = TRUE;
+ ClearDevList(&pIrlapCb->DevList);
+ RetOnErr(SendDscvXIDCmd(pIrlapCb));
+
+ IMsg.Prim = MAC_CONTROL_REQ;
+ IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
+ IMsg.IRDA_MSG_SenseTime = IRLAP_DSCV_SENSE_TIME;
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ (dscv sense)")));
+ RetOnErr(IrmacDown(pIrlapCb->pIrdaLinkCb,&IMsg));
+ }
+ else
+ {
+ RetOnErr(AddDevToList(pIrlapCb, pXIDFormat, pEndDscvInfoByte));
+ }
+ }
+ else
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ }
+
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func BOOL | DevInDevList | Determines if given device is already in list
+*
+* @rdesc returns:
+* @flag TRUE | if device is alreay in list
+* @flag FALSE | if device is not in list
+*
+* @parm BYTE | DevAddr[] | Device address
+* @parm IRDA_DEVICE * | pDevList | pointer to list of devices
+*
+*/
+BOOL
+DevInDevList(BYTE DevAddr[], LIST_ENTRY *pDevList)
+{
+ IRDA_DEVICE *pDevice;
+
+ pDevice = (IRDA_DEVICE *) pDevList->Flink;
+
+ while (pDevList != (LIST_ENTRY *) pDevice)
+ {
+ if (memcmp(pDevice->DevAddr, DevAddr, IRDA_DEV_ADDR_LEN) == 0)
+ return (TRUE);
+
+ pDevice = (IRDA_DEVICE *) pDevice->Linkage.Flink;
+ }
+ return (FALSE);
+}
+/*****************************************************************************
+*
+* @func void | AddDevToList | Adds elements in a device list
+*
+* @parm IRDA_DEVICE ** | ppDevList | address of pointer to an
+* IRDA device list
+*
+*/
+UINT
+AddDevToList(PIRLAP_CB pIrlapCb,
+ IRLAP_XID_DSCV_FORMAT *pXIDFormat,
+ BYTE *pEndDscvInfoByte)
+{
+ IRDA_DEVICE *pDevice;
+
+ if (IRDA_ALLOC_MEM(pDevice, sizeof(IRDA_DEVICE), MT_IRLAP_DEVICE) == NULL)
+ {
+ return (IRLAP_MALLOC_FAILED);
+ }
+ else
+ {
+ ExtractDeviceInfo(pDevice, pXIDFormat, pEndDscvInfoByte);
+
+ InsertTailList(&pIrlapCb->DevList, &(pDevice->Linkage));
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("%02X%02X%02X%02X added to Device List"),
+ EXPAND_ADDR(pDevice->DevAddr)));
+ }
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func void | ClearDevList | Frees elements in a device list
+*
+* @parm IRDA_DEVICE ** | ppDevList | address of pointer to an
+* IRDA device list
+*
+*/
+void
+ClearDevList(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")));
+}
+/*****************************************************************************
+*
+* @func UINT | ProcessSNRM | process received SNRM frame
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm IRLAP_SNRM_FORMAT * | pSNRMFormat | Pointer to SNRM frame
+* Information Field
+* BYTE * | pLastQosByte | Pointer to last byte in SNRM
+*
+* @comm
+* comments
+*/
+UINT
+ProcessSNRM(PIRLAP_CB pIrlapCb,
+ IRLAP_SNRM_FORMAT *pSNRMFormat,
+ BYTE *pEndQosByte)
+{
+ BOOL Qos_InSNRM = &pSNRMFormat->FirstQosByte < pEndQosByte;// Is there Qos?
+ BOOL Addrs_InSNRM = (BYTE *)pSNRMFormat < pEndQosByte;
+
+ if (Addrs_InSNRM)
+ {
+ if (!MyDevAddr(pIrlapCb, pSNRMFormat->DestAddr))
+ {
+ IRLAP_LOG_ACTION((pIrlapCb,
+ TEXT("Ignoring SNRM addressed to:%02X%02X%02X%02X"),
+ EXPAND_ADDR(pSNRMFormat->DestAddr)));
+ return SUCCESS;
+ }
+ memcpy(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;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ // fall through and send connect indication
+ case DSCV_REPLY:
+ case NDM:
+ if (Addrs_InSNRM)
+ {
+ pIrlapCb->SNRMConnAddr = (int)IRLAP_GET_ADDR(pSNRMFormat->ConnAddr);
+ }
+ if (Qos_InSNRM)
+ {
+ ExtractQosParms(&pIrlapCb->RemoteQos, &pSNRMFormat->FirstQosByte,
+ pEndQosByte);
+
+ RetOnErr(NegotiateQosParms(pIrlapCb, &pIrlapCb->RemoteQos));
+ }
+
+ memcpy(IMsg.IRDA_MSG_RemoteDevAddr,
+ pIrlapCb->RemoteDevice.DevAddr, IRDA_DEV_ADDR_LEN);
+ IMsg.IRDA_MSG_pQOS = &pIrlapCb->NegotiatedQos;
+ IMsg.Prim = IRLAP_CONNECT_IND;
+ RetOnErr(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 (Addrs_InSNRM)
+ {
+ if (memcmp(pSNRMFormat->SrcAddr,
+ pIrlapCb->LocalDevice.DevAddr, IRDA_DEV_ADDR_LEN) > 0)
+ {
+ IRLAP_TimerStop(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 (Addrs_InSNRM &&
+ memcmp(pSNRMFormat->SrcAddr,
+ pIrlapCb->LocalDevice.DevAddr, IRDA_DEV_ADDR_LEN) > 0)
+ {
+ if (pIrlapCb->State != BACKOFF_WAIT)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ InitializeState(pIrlapCb, SECONDARY);
+
+ if (Qos_InSNRM)
+ {
+ ExtractQosParms(&pIrlapCb->RemoteQos,
+ &pSNRMFormat->FirstQosByte, pEndQosByte);
+ RetOnErr(NegotiateQosParms(pIrlapCb,&pIrlapCb->RemoteQos));
+ }
+
+ if (Addrs_InSNRM)
+ {
+ pIrlapCb->ConnAddr = (int)IRLAP_GET_ADDR(pSNRMFormat->ConnAddr);
+ }
+
+ RetOnErr(SendUA(pIrlapCb, TRUE));
+
+ if (Qos_InSNRM)
+ {
+ RetOnErr(ApplyQosParms(pIrlapCb));
+ }
+
+ IMsg.IRDA_MSG_pQOS = &pIrlapCb->NegotiatedQos;
+ IMsg.Prim = IRLAP_CONNECT_CONF;
+ IMsg.IRDA_MSG_ConnStatus = IRLAP_CONNECTION_COMPLETED;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ pIrlapCb->State = S_NRM;
+ }
+ break;
+
+ case P_RECV:
+ case P_DISCONNECT_PEND:
+ case P_CLOSE:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ RetOnErr(StationConflict(pIrlapCb));
+ RetOnErr(ReturnTxMsgs(pIrlapCb));
+ if (pIrlapCb->State == P_CLOSE)
+ {
+ RetOnErr(GotoNDMThenDscvOrConn(pIrlapCb));
+ }
+ else
+ {
+ pIrlapCb->State = NDM;
+ }
+ break;
+
+ case S_NRM:
+ case S_CLOSE:
+ case S_DISCONNECT_PEND:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ RetOnErr(SendDM(pIrlapCb));
+ RetOnErr(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;
+ }
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ pIrlapCb->State = NDM;
+ break;
+
+ case S_ERROR:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ RetOnErr(SendFRMR(pIrlapCb, &FrmRejFormat));
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ pIrlapCb->State = S_NRM;
+ break;
+
+ default:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("SNRM ignored in this state")));
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func UINT | ProcessUA | process received UA frame
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm IRLAP_UA_FORMAT * | pUAFormat | Pointer to UA frame
+* Information Field
+* BYTE * | pLastQosByte | Pointer to last byte in SNRM
+*
+* @comm
+* When &pUAFormat->FirstQosByte = pLastQosByte there is no Qos in UA
+*/
+UINT
+ProcessUA(PIRLAP_CB pIrlapCb,
+ IRLAP_UA_FORMAT *pUAFormat,
+ BYTE *pEndQosByte)
+{
+ BOOL Qos_InUA = &pUAFormat->FirstQosByte < pEndQosByte;// Is there QOS?
+ BOOL Addrs_InUA = (BYTE *)pUAFormat < pEndQosByte;
+ int Tmp;
+
+ if (Addrs_InUA && !MyDevAddr(pIrlapCb, pUAFormat->DestAddr))
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring UA addressed to:%02X%02X%02X%02X"),
+ EXPAND_ADDR(pUAFormat->DestAddr)));
+ return SUCCESS;
+ }
+
+ switch (pIrlapCb->State)
+ {
+ case BACKOFF_WAIT:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->BackoffTimer);
+ // fall through
+ case SNRM_SENT:
+ if (pIrlapCb->State != BACKOFF_WAIT)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+
+ InitializeState(pIrlapCb, PRIMARY);
+
+ if (Qos_InUA)
+ {
+ ExtractQosParms(&pIrlapCb->RemoteQos, &pUAFormat->FirstQosByte,
+ pEndQosByte);
+
+ RetOnErr(NegotiateQosParms(pIrlapCb,&pIrlapCb->RemoteQos));
+
+ RetOnErr(ApplyQosParms(pIrlapCb));
+ }
+
+ IMsg.IRDA_MSG_pQOS = &pIrlapCb->NegotiatedQos;
+
+ IMsg.Prim = IRLAP_CONNECT_CONF;
+ IMsg.IRDA_MSG_ConnStatus = IRLAP_CONNECTION_COMPLETED;
+
+ // notify LMP of connection
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+
+ // send RR (turn link), start FinalTimer/2
+ RetOnErr(SendRR_RNR(pIrlapCb));
+
+ Tmp = pIrlapCb->FinalTimer.Timeout;
+ pIrlapCb->FinalTimer.Timeout = pIrlapCb->FinalTimer.Timeout/2;
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ pIrlapCb->FinalTimer.Timeout = Tmp;
+
+ pIrlapCb->State = P_RECV;
+ break;
+
+ case P_RECV: // Unsolicited UA, may want to do something else ???
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->PollTimer);
+ pIrlapCb->State = P_XMIT;
+ break;
+
+ case P_DISCONNECT_PEND:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ RetOnErr(SendDISC(pIrlapCb));
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ pIrlapCb->RetryCnt = 0;
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ break;
+
+ case P_CLOSE:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ RetOnErr(ApplyDefaultParms(pIrlapCb));
+ if (pIrlapCb->LocalDiscReq == TRUE)
+ {
+ pIrlapCb->LocalDiscReq = FALSE;
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_DISCONNECT_COMPLETED;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ }
+ RetOnErr(GotoNDMThenDscvOrConn(pIrlapCb));
+ break;
+
+ case S_NRM:
+ case S_DISCONNECT_PEND:
+ case S_ERROR:
+ case S_CLOSE:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+ break;
+
+ default:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("UA ignored in this state")));
+ }
+
+ return SUCCESS;
+}
+
+BYTE *
+GetPv(BYTE *pQosByte,
+ UINT *pBitField)
+{
+ int Pl = (int) *pQosByte++;
+
+ *pBitField = 0;
+
+ if (Pl == 1)
+ {
+ *pBitField = (UINT) *pQosByte;
+ }
+ else
+ {
+ *pBitField = ((UINT) *pQosByte)<<8;
+ *pBitField |= (UINT) *(pQosByte+1);
+ }
+
+ return pQosByte + Pl;
+}
+/*****************************************************************************
+*
+* @func void | ExtractQosParms | Extracts Qos from SNRM/UA/XID and
+* places in an IRDA_QOS_PARM struct
+*
+* @parm IRDA_QOS_PARMS * | pIRDA_QOSParms | Pointer to QOS parm struct
+* BYTE * | pQOSByte | Pointer to first byte of
+* QOS in frame
+* BYTE * | pEndQOSByte | Pointer to last byte of
+* QOS in frame
+* @comm
+* THIS WILL BREAK IF PARAMETER LENGTH (PL) IS GREATER THAN 2
+*/
+void
+ExtractQosParms(IRDA_QOS_PARMS *pQos,
+ BYTE *pQosByte,
+ BYTE *pEndQosByte)
+{
+ while (pQosByte + 2 < pEndQosByte)
+ {
+ switch (*pQosByte)
+ {
+ case QOS_PI_BAUD:
+ pQosByte = GetPv(pQosByte, &pQos->bfBaud);
+ break;
+
+ case QOS_PI_MAX_TAT:
+ pQosByte = GetPv(pQosByte, &pQos->bfMaxTurnTime);
+ break;
+
+ case QOS_PI_DATA_SZ:
+ pQosByte = GetPv(pQosByte, &pQos->bfDataSize);
+ break;
+
+ case QOS_PI_WIN_SZ:
+ pQosByte = GetPv(pQosByte, &pQos->bfWindowSize);
+ break;
+
+ case QOS_PI_BOFS:
+ pQosByte = GetPv(pQosByte, &pQos->bfBofs);
+ break;
+
+ case QOS_PI_MIN_TAT:
+ pQosByte = GetPv(pQosByte, &pQos->bfMinTurnTime);
+ break;
+
+ case QOS_PI_DISC_THRESH:
+ pQosByte = GetPv(pQosByte, &pQos->bfDisconnectTime);
+ break;
+
+ default:
+ pQosByte += (*(pQosByte+1));
+ }
+ }
+}
+/*****************************************************************************
+*
+* @func UINT | NegotiateQosParms | Take the received Qos build
+* negotiated Qos.
+*
+* @rdesc SUCCESS, otherwise one of the folowing:
+* @flag IRLAP_BAUD_NEG_ERR | Failed to negotiate baud
+* @flag IRLAP_DISC_NEG_ERR | Failed to negotiate disconnect time
+* @flag IRLAP_MAXTAT_NEG_ERR | Failed to negotiate max turn time
+* @flag IRLAP_DATASIZE_NEG_ERR | Failed to negotiate data size
+* @flag IRLAP_WINSIZE_NEG_ERR | Failed to negotiate window size
+* @flag IRLAP_BOFS_NEG_ERR | Failed to negotiate number of BOFS
+* @flag IRLAP_WINSIZE_NEG_ERR | Failed to window size
+* @flag IRLAP_LINECAP_ERR | Failed to determine valid line capacity
+*
+* @parm IRDA_QOS_PARMS * | pRemoteQos | Pointer to QOS parm struct
+*/
+UINT
+NegotiateQosParms(PIRLAP_CB pIrlapCb,
+ IRDA_QOS_PARMS *pRemoteQos)
+{
+ UINT BitSet;
+ BOOL ParmSet = FALSE;
+ UINT BOFSDivisor = 1;
+ UINT MaxLineCap = 0;
+ UINT LineCapacity;
+ UINT DataSizeBit = 0;
+ UINT WinSizeBit = 0;
+ UINT WSBit;
+ int RemoteDataSize = 0;
+ int RemoteWinSize = 0;
+
+ // Baud rate is Type 0 parm
+ pIrlapCb->Baud = IrlapGetQosParmVal(vBaudTable,
+ (BYTE) (pIrlapCb->LocalQos.bfBaud & pRemoteQos->bfBaud),
+ &BitSet);
+ BOFSDivisor = IrlapGetQosParmVal(vBOFSDivTable,
+ (BYTE) (pIrlapCb->LocalQos.bfBaud & pRemoteQos->bfBaud),
+ &BitSet);
+ pIrlapCb->NegotiatedQos.bfBaud = BitSet;
+
+ if (-1 == pIrlapCb->Baud)
+ {
+ return (IRLAP_BAUD_NEG_ERR);
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Negotiated Baud:%d"), pIrlapCb->Baud));
+
+ // Disconnect/Threshold time is Type 0 parm
+ pIrlapCb->DisconnectTime = IrlapGetQosParmVal(vDiscTable,
+ (BYTE)(pIrlapCb->LocalQos.bfDisconnectTime &
+ pRemoteQos->bfDisconnectTime), &BitSet);
+ pIrlapCb->ThresholdTime = IrlapGetQosParmVal(vThreshTable,
+ (BYTE)(pIrlapCb->LocalQos.bfDisconnectTime &
+ pRemoteQos->bfDisconnectTime), &BitSet);
+ pIrlapCb->NegotiatedQos.bfDisconnectTime = BitSet;
+
+ if (-1 == pIrlapCb->DisconnectTime)
+ {
+ return (IRLAP_DISC_NEG_ERR);
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Negotiated Disconnect/Threshold time:%d/%d"),
+ pIrlapCb->DisconnectTime, pIrlapCb->ThresholdTime));
+
+ pIrlapCb->RemoteMaxTAT = IrlapGetQosParmVal(vMaxTATTable,
+ pRemoteQos->bfMaxTurnTime,
+ &BitSet);
+ pIrlapCb->NegotiatedQos.bfMaxTurnTime = BitSet;
+ if (-1 == pIrlapCb->RemoteMaxTAT)
+ {
+ return (IRLAP_MAXTAT_NEG_ERR);
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Remote max turnaround time:%d"),
+ pIrlapCb->RemoteMaxTAT));
+
+ pIrlapCb->RemoteMinTAT = IrlapGetQosParmVal(vMinTATTable,
+ pRemoteQos->bfMinTurnTime,
+ &BitSet);
+ pIrlapCb->NegotiatedQos.bfMinTurnTime = BitSet;
+ if (-1 == pIrlapCb->RemoteMinTAT)
+ {
+ return (IRLAP_MINTAT_NEG_ERR);
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Remote min turnaround time:%d"),
+ pIrlapCb->RemoteMinTAT));
+
+ // DataSize ISNOT A TYPE 0 PARAMETER. BUT WIN95's IRCOMM implementation
+ // ASSUMES THAT IT IS. SO FOR NOW, NEGOTIATE IT. grrrr..
+ /* WIN95 out
+ pIrlapCb->RemoteDataSize = IrlapGetQosParmVal(vDataSizeTable,
+ (BYTE) (pIrlapCb->LocalQos.bfDataSize &
+ pRemoteQos->bfDataSize), &BitSet);
+ */
+ pIrlapCb->RemoteDataSize = IrlapGetQosParmVal(vDataSizeTable,
+ pRemoteQos->bfDataSize, &BitSet);
+ DataSizeBit = BitSet;
+ pIrlapCb->NegotiatedQos.bfDataSize = BitSet;
+ if (-1 == pIrlapCb->RemoteDataSize)
+ {
+ return (IRLAP_DATASIZE_NEG_ERR);
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Remote data size:%d"), pIrlapCb->RemoteDataSize));
+
+ pIrlapCb->RemoteWinSize = IrlapGetQosParmVal(vWinSizeTable,
+ pRemoteQos->bfWindowSize, &BitSet);
+ WinSizeBit = BitSet;
+ pIrlapCb->NegotiatedQos.bfWindowSize = BitSet;
+ if (-1 == pIrlapCb->RemoteWinSize)
+ {
+ return (IRLAP_WINSIZE_NEG_ERR);
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Remote window size:%d"), pIrlapCb->RemoteWinSize));
+
+ pIrlapCb->RemoteNumBOFS=(IrlapGetQosParmVal(vBOFSTable,
+ pRemoteQos->bfBofs, &BitSet)
+ / BOFSDivisor)+1;
+ pIrlapCb->NegotiatedQos.bfBofs = BitSet;
+ if (-1 == pIrlapCb->RemoteNumBOFS)
+ {
+ return (IRLAP_BOFS_NEG_ERR);
+ }
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Remote number of BOFS:%d"),
+ pIrlapCb->RemoteNumBOFS));
+
+ // The maximum line capacity is in bytes and comes from a table in spec.
+ // (can't calc because table isn't linear). It is determined by the
+ // maximum line capacity and baud rate.
+ //
+ // Later note: Errata corrected table so values could be calculated.
+ // Could get rid of tables
+ switch (pIrlapCb->Baud)
+ {
+ case 9600:
+ MaxLineCap = IrlapGetQosParmVal(MAXCAP_9600,
+ pRemoteQos->bfMaxTurnTime, &BitSet);
+ break;
+
+ case 19200:
+ MaxLineCap = IrlapGetQosParmVal(MAXCAP_19200,
+ pRemoteQos->bfMaxTurnTime, &BitSet);
+ break;
+
+ case 38400:
+ MaxLineCap = IrlapGetQosParmVal(MAXCAP_38400,
+ pRemoteQos->bfMaxTurnTime, &BitSet);
+ break;
+
+ case 57600:
+ MaxLineCap = IrlapGetQosParmVal(MAXCAP_57600,
+ pRemoteQos->bfMaxTurnTime, &BitSet);
+ break;
+
+ case 115200:
+ MaxLineCap = IrlapGetQosParmVal(MAXCAP_115200,
+ pRemoteQos->bfMaxTurnTime, &BitSet);
+ break;
+ }
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Maximum line capacity:%d"), MaxLineCap));
+ LineCapacity = LINE_CAPACITY(pIrlapCb);
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Requested line capacity:%d"), LineCapacity));
+
+ if (LineCapacity > MaxLineCap)
+ {
+ ParmSet = FALSE;
+ // Adjust data and window size to fit within the line capacity.
+ // Get largest possible datasize
+ for (; DataSizeBit != 0 && !ParmSet; DataSizeBit >>= 1)
+ {
+ pIrlapCb->RemoteDataSize = IrlapGetQosParmVal(vDataSizeTable,
+ DataSizeBit, NULL);
+ // Start with smallest window
+ for (WSBit=1; WSBit <= WinSizeBit; WSBit <<=1)
+ {
+ pIrlapCb->RemoteWinSize = IrlapGetQosParmVal(vWinSizeTable,
+ WSBit, NULL);
+ LineCapacity = LINE_CAPACITY(pIrlapCb);
+
+ IRLAP_LOG_ACTION((pIrlapCb,
+ TEXT("adjusted data size=%d, window size= %d, line cap=%d"),
+ pIrlapCb->RemoteDataSize, pIrlapCb->RemoteWinSize,
+ LineCapacity));
+
+ if (LineCapacity > MaxLineCap)
+ {
+ break; // Get a smaller data size (only if ParmSet is false)
+ }
+ ParmSet = TRUE;
+ // Save the last good one,then loop and try a larger window
+ RemoteDataSize = pIrlapCb->RemoteDataSize;
+ RemoteWinSize = pIrlapCb->RemoteWinSize;
+ pIrlapCb->NegotiatedQos.bfWindowSize = WSBit;
+ pIrlapCb->NegotiatedQos.bfDataSize = DataSizeBit;
+ }
+ }
+ if (!ParmSet)
+ {
+ return (IRLAP_LINECAP_ERR);
+ }
+
+ pIrlapCb->RemoteDataSize = RemoteDataSize;
+ pIrlapCb->RemoteWinSize = RemoteWinSize;
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("final data size=%d, window size= %d, line cap=%d"),
+ pIrlapCb->RemoteDataSize, pIrlapCb->RemoteWinSize,
+ LINE_CAPACITY(pIrlapCb)));
+ }
+
+ return (SUCCESS);
+}
+/*****************************************************************************
+*
+* @func UINT | ApplyQosParms | Apply negotiated Qos in control block
+*
+* @rdesc return status from IrmacDown()
+*/
+UINT
+ApplyQosParms(PIRLAP_CB pIrlapCb)
+{
+ // convert disconnect/threshold time to ms and divide by turn around time
+ // to get number of retries
+ pIrlapCb->N1 = pIrlapCb->ThresholdTime * 1000 / pIrlapCb->RemoteMaxTAT;
+ pIrlapCb->N2 = pIrlapCb->DisconnectTime * 1000 / pIrlapCb->RemoteMaxTAT;
+
+ // hmmmm...???
+ pIrlapCb->PollTimer.Timeout = pIrlapCb->RemoteMaxTAT;
+ pIrlapCb->FinalTimer.Timeout = pIrlapCb->LocalMaxTAT;
+
+ IMsg.Prim = MAC_CONTROL_REQ;
+ IMsg.IRDA_MSG_Op = MAC_RECONFIG_LINK;
+ IMsg.IRDA_MSG_Baud = pIrlapCb->Baud;
+ IMsg.IRDA_MSG_NumBOFs = pIrlapCb->RemoteNumBOFS; // Number of BOFS
+ // to add to tx
+ IMsg.IRDA_MSG_DataSize = pIrlapCb->RemoteDataSize; // Max rx size packet
+ // causes major heap
+ // problems later
+ IMsg.IRDA_MSG_MinTat = pIrlapCb->RemoteMinTAT;
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Reconfig link for Baud:%d, Local data size:%d, Remote BOFS:%d"), pIrlapCb->Baud, pIrlapCb->LocalDataSize, pIrlapCb->RemoteNumBOFS));
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Retry counts N1=%d, N2=%d"), pIrlapCb->N1, pIrlapCb->N2));
+ return (IrmacDown(pIrlapCb->pIrdaLinkCb,&IMsg));
+}
+/*****************************************************************************
+*
+* @func UINT | IrlapGetQosParmVal |
+* retrieves the parameters value from table
+*
+* @rdesc value contained in parmeter value table, 0 if not found
+* (0 is a valid parameter in some tables though)
+*
+* @parm UINT [] | PVTable | table containing parm values
+* USHORT | BitField | contains bit indicating which parm to select
+*
+* @comm
+*/
+UINT
+IrlapGetQosParmVal(UINT PVTable[], UINT BitField, UINT *pBitSet)
+{
+ int i;
+ UINT Mask;
+
+ for (i = PV_TABLE_MAX_BIT, Mask = (1<<PV_TABLE_MAX_BIT);
+ Mask > 0; i--, Mask = Mask >> 1)
+ {
+ if (Mask & BitField)
+ {
+ if (pBitSet != NULL)
+ {
+ *pBitSet = Mask;
+ }
+ return (PVTable[i]);
+ }
+ }
+ return (UINT) -1;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessTEST(PIRLAP_CB pIrlapCb,
+ PIRDA_MSG pMsg,
+ IRLAP_UA_FORMAT *pTestFormat,
+ int CRBit,
+ int PFBit)
+{
+ BYTE TmpAddr[IRDA_DEV_ADDR_LEN];
+
+ if (!MyDevAddr(pIrlapCb, pTestFormat->DestAddr))
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring XID addressed to:%02X%02X%02X%02X"),
+ EXPAND_ADDR(pTestFormat->DestAddr)));
+ return SUCCESS;
+ }
+
+ if (IRLAP_CMD == CRBit && IRLAP_PFBIT_SET == PFBit)
+ {
+ // bounce it back
+ memcpy(TmpAddr,pTestFormat->SrcAddr, IRDA_DEV_ADDR_LEN);
+ memcpy(pTestFormat->SrcAddr, pTestFormat->DestAddr, IRDA_DEV_ADDR_LEN);
+ memcpy(pTestFormat->DestAddr, TmpAddr, IRDA_DEV_ADDR_LEN);
+ *(pMsg->IRDA_MSG_pRead) ^= 1; // swap cr bit
+ return SendFrame(pIrlapCb, pMsg);
+ }
+ else
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring")));
+ }
+
+ // Not implementing TEST responses for now
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessUI(PIRLAP_CB pIrlapCb,
+ PIRDA_MSG pMsg,
+ int CRBit,
+ int PFBit)
+{
+ BOOL LinkTurned = TRUE;
+
+ pMsg->IRDA_MSG_pRead += 2; // chop the IRLAP header
+
+ switch (pIrlapCb->State)
+ {
+ case NDM:
+ case DSCV_MEDIA_SENSE:
+ case DSCV_QUERY:
+ case DSCV_REPLY:
+ case CONN_MEDIA_SENSE:
+ case SNRM_SENT:
+ case BACKOFF_WAIT:
+ case SNRM_RECEIVED:
+ pMsg->Prim = IRLAP_UDATA_IND;
+ return (IrlmpUp(pIrlapCb->pIrdaLinkCb, pMsg));
+
+ case P_XMIT:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ return SUCCESS;
+ }
+
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ // stop timers if PF bit set or invalid CRBit (matches mine)
+ if (IRLAP_PFBIT_SET == PFBit || pIrlapCb->CRBit == CRBit)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ }
+ else
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+
+ if (pIrlapCb->CRBit == CRBit)
+ {
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+ return SUCCESS;
+ }
+
+ // Send the Unnumber information to LMP
+ pMsg->Prim = IRLAP_UDATA_IND;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, pMsg));
+
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ switch (pIrlapCb->State)
+ {
+ case P_RECV:
+ RetOnErr(XmitTxMsgList(pIrlapCb, FALSE, &LinkTurned));
+ break;
+
+ case P_DISCONNECT_PEND:
+ RetOnErr(SendDISC(pIrlapCb));
+ pIrlapCb->RetryCnt = 0;
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ break;
+
+ case P_CLOSE:
+ RetOnErr(ResendDISC(pIrlapCb));
+ break;
+
+ case S_NRM:
+ RetOnErr(XmitTxMsgList(pIrlapCb, TRUE, NULL));
+ break;
+
+ case S_DISCONNECT_PEND:
+ RetOnErr(SendRD(pIrlapCb));
+ pIrlapCb->State = S_CLOSE;
+ break;
+
+ case S_ERROR:
+ RetOnErr(SendFRMR(pIrlapCb, &FrmRejFormat));
+ pIrlapCb->State = S_NRM;
+ break;
+
+ case S_CLOSE:
+ RetOnErr(SendRD(pIrlapCb));
+ }
+ }
+
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ if (IRLAP_PFBIT_SET == PFBit && pIrlapCb->State != NDM)
+ {
+ if (LinkTurned)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ else
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->PollTimer);
+ pIrlapCb->State = P_XMIT;
+ }
+ }
+ }
+ else
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessDM(PIRLAP_CB pIrlapCb)
+{
+ BOOL LinkTurned;
+
+ switch (pIrlapCb->State)
+ {
+ case NDM:
+ case DSCV_MEDIA_SENSE:
+ case DSCV_QUERY:
+ case DSCV_REPLY:
+ case CONN_MEDIA_SENSE:
+ case BACKOFF_WAIT:
+ case SNRM_RECEIVED:
+ case P_XMIT:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ return TRUE;
+ }
+
+ if (PRIMARY != pIrlapCb->StationType)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+ return SUCCESS;
+ }
+
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+
+ switch (pIrlapCb->State)
+ {
+ case P_RECV: // I'm not sure why I am doing this ???
+ RetOnErr(XmitTxMsgList(pIrlapCb, FALSE, &LinkTurned));
+ if (LinkTurned)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ else
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->PollTimer);
+ pIrlapCb->State = P_XMIT;
+ }
+ break;
+
+ case P_DISCONNECT_PEND:
+ pIrlapCb->RetryCnt = 0;
+ RetOnErr(SendDISC(pIrlapCb));
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ break;
+
+ case SNRM_SENT:
+ case P_CLOSE:
+ RetOnErr(ApplyDefaultParms(pIrlapCb));
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ if (pIrlapCb->State == P_CLOSE)
+ {
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_DISCONNECT_COMPLETED;
+ }
+ else
+ {
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_REMOTE_INITIATED;
+ }
+ if (pIrlapCb->LocalDiscReq || pIrlapCb->State == SNRM_SENT)
+ {
+ pIrlapCb->LocalDiscReq = FALSE;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ }
+
+ if (pIrlapCb->State == P_CLOSE)
+ {
+ return GotoNDMThenDscvOrConn(pIrlapCb);
+ }
+
+ pIrlapCb->State = NDM;
+ break;
+ }
+
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessDISC(PIRLAP_CB pIrlapCb)
+{
+ if (IgnoreState(pIrlapCb))
+ {
+ return SUCCESS;
+ }
+
+ if (SECONDARY != pIrlapCb->StationType)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+ return SUCCESS;
+ }
+
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+
+ // Acknowledge primary's disconnect request
+ RetOnErr(SendUA(pIrlapCb, FALSE /* No Qos */));
+ RetOnErr(ApplyDefaultParms(pIrlapCb));
+
+ RetOnErr(ReturnTxMsgs(pIrlapCb));
+
+ // notify LMP of disconnect
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ if (pIrlapCb->LocalDiscReq)
+ {
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_DISCONNECT_COMPLETED;
+ pIrlapCb->LocalDiscReq = FALSE;
+ }
+ else
+ {
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_REMOTE_INITIATED;
+ }
+
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+
+ pIrlapCb->State = NDM;
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessRD(PIRLAP_CB pIrlapCb)
+{
+ if (IgnoreState(pIrlapCb))
+ {
+ return SUCCESS;
+ }
+
+ if (PRIMARY != pIrlapCb->StationType)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+ return SUCCESS;
+ }
+
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+
+ if (pIrlapCb->State == P_CLOSE)
+ {
+ RetOnErr(ResendDISC(pIrlapCb));
+ }
+ else
+ {
+ RetOnErr(ReturnTxMsgs(pIrlapCb));
+ pIrlapCb->RetryCnt = 0;
+ RetOnErr(SendDISC(pIrlapCb));
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ }
+ if (pIrlapCb->State != NDM)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessFRMR(PIRLAP_CB pIrlapCb)
+{
+ if (IgnoreState(pIrlapCb))
+ {
+ return SUCCESS;
+ }
+
+ if (PRIMARY != pIrlapCb->StationType)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+ return SUCCESS;
+ }
+
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+
+ switch (pIrlapCb->State)
+ {
+ case P_RECV:
+ RetOnErr(ReturnTxMsgs(pIrlapCb));
+ // fall through
+
+ case P_DISCONNECT_PEND:
+ pIrlapCb->RetryCnt = 0;
+ RetOnErr(SendDISC(pIrlapCb));
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ break;
+
+ case P_CLOSE:
+ RetOnErr(ResendDISC(pIrlapCb));
+ break;
+ }
+
+ if (pIrlapCb->State != NDM)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessRNRM(PIRLAP_CB pIrlapCb)
+{
+ if (IgnoreState(pIrlapCb))
+ {
+ return SUCCESS;
+ }
+
+ if (PRIMARY != pIrlapCb->StationType)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+ return SUCCESS;
+ }
+
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+
+ switch (pIrlapCb->State)
+ {
+ case P_RECV:
+ case P_DISCONNECT_PEND:
+ pIrlapCb->RetryCnt = 0;
+ RetOnErr(SendDISC(pIrlapCb));
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ break;
+
+ case P_CLOSE:
+ RetOnErr(ResendDISC(pIrlapCb));
+ break;
+ }
+
+ if (pIrlapCb->State != NDM)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessREJ_SREJ(PIRLAP_CB pIrlapCb,
+ int FrameType,
+ PIRDA_MSG pMsg,
+ int CRBit,
+ int PFBit,
+ UINT Nr)
+{
+ if (IgnoreState(pIrlapCb))
+ {
+ return SUCCESS;
+ }
+
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ // stop timers if PF bit set or invalid CRBit (matches mine)
+ if (IRLAP_PFBIT_SET == PFBit || pIrlapCb->CRBit == CRBit)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ }
+ else
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+
+ if (pIrlapCb->CRBit == CRBit)
+ {
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+ return SUCCESS;
+ }
+
+ switch (pIrlapCb->State)
+ {
+ case P_RECV:
+ case S_NRM:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ if (InvalidNr(pIrlapCb,Nr) || Nr == pIrlapCb->TxWin.End)
+ {
+ RetOnErr(ProcessInvalidNr(pIrlapCb, PFBit));
+ }
+ else
+ {
+ RetOnErr(FreeAckedTxMsgs(pIrlapCb, Nr));
+ if (FrameType == IRLAP_REJ)
+ {
+ RetOnErr(ResendRejects(pIrlapCb, Nr)); // link turned here
+ }
+ else // selective reject
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("RETRANSMISSION:")));
+ RetOnErr(SendIFrame(pIrlapCb,
+ pIrlapCb->TxWin.pMsg[Nr],
+ Nr, IRLAP_PFBIT_SET));
+ }
+ }
+ }
+ break;
+
+ case P_DISCONNECT_PEND:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ pIrlapCb->RetryCnt = 0;
+ RetOnErr(SendDISC(pIrlapCb));
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ }
+ break;
+
+ case P_CLOSE:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ RetOnErr(ResendDISC(pIrlapCb));
+ }
+ break;
+
+ case S_DISCONNECT_PEND:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ RetOnErr(SendRD(pIrlapCb));
+ pIrlapCb->State = S_CLOSE;
+ }
+ break;
+
+ case S_ERROR:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ RetOnErr(SendFRMR(pIrlapCb, &FrmRejFormat));
+ pIrlapCb->State = S_NRM;
+ }
+ break;
+
+ case S_CLOSE:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ RetOnErr(SendRD(pIrlapCb));
+ }
+ break;
+
+ }
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ if (IRLAP_PFBIT_SET == PFBit && pIrlapCb->State != NDM)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ }
+ else
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessRR_RNR(PIRLAP_CB pIrlapCb,
+ int FrameType,
+ PIRDA_MSG pMsg,
+ int CRBit,
+ int PFBit,
+ UINT Nr)
+{
+ BOOL LinkTurned = TRUE;
+
+ if (IgnoreState(pIrlapCb))
+ {
+ return SUCCESS;
+ }
+
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ // stop timers if PF bit set or invalid CRBit (matches mine)
+ if (IRLAP_PFBIT_SET == PFBit || pIrlapCb->CRBit == CRBit)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ }
+ else // SECONDARY, restart WDog
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ if (pIrlapCb->CRBit != CRBit)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+ }
+
+ if (pIrlapCb->CRBit == CRBit)
+ {
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+ return SUCCESS;
+ }
+
+ if (FrameType == IRLAP_RR)
+ {
+ pIrlapCb->RemoteBusy = FALSE;
+ }
+ else // RNR
+ {
+ pIrlapCb->RemoteBusy = TRUE;
+ }
+
+ switch (pIrlapCb->State)
+ {
+ case P_RECV:
+ case S_NRM:
+ if (PFBit == IRLAP_PFBIT_SET)
+ {
+ if (InvalidNr(pIrlapCb, Nr))
+ {
+ RetOnErr(ProcessInvalidNr(pIrlapCb, PFBit));
+ }
+ else
+ {
+ RetOnErr(FreeAckedTxMsgs(pIrlapCb,Nr));
+
+ if (Nr != pIrlapCb->Vs) // Implicit reject
+ {
+ if (PRIMARY == pIrlapCb->StationType &&
+ IRLAP_RNR == FrameType)
+ {
+ LinkTurned = FALSE;
+ }
+ else
+ {
+ RetOnErr(ResendRejects(pIrlapCb,
+ Nr)); // always turns link
+ }
+ }
+ else
+ {
+ if (pIrlapCb->Vr != pIrlapCb->RxWin.End)
+ {
+ RetOnErr(MissingRxFrames(pIrlapCb)); // Send SREJ or REJ
+ }
+ else
+ {
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ LinkTurned = FALSE;
+ if (IRLAP_RR == FrameType)
+ {
+ RetOnErr(XmitTxMsgList(pIrlapCb,
+ FALSE, &LinkTurned));
+ }
+ }
+ else
+ {
+ // Always turn link if secondary
+ // with data or an RR if remote is busy
+ if (IRLAP_RR == FrameType)
+ {
+ RetOnErr(XmitTxMsgList(pIrlapCb, TRUE, NULL));
+ }
+ else
+ {
+ RetOnErr(SendRR_RNR(pIrlapCb));
+ }
+ }
+ }
+ }
+ }
+ // If the link was turned, restart Final timer,
+ // else start the Poll timer and enter the transmit state
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ if (LinkTurned)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ else
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->PollTimer);
+ pIrlapCb->State = P_XMIT;
+ }
+ }
+ }
+ break;
+
+ case P_DISCONNECT_PEND:
+ RetOnErr(SendDISC(pIrlapCb));
+ pIrlapCb->RetryCnt = 0;
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ break;
+
+ case P_CLOSE:
+ RetOnErr(ResendDISC(pIrlapCb));
+ if (pIrlapCb->State != NDM)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ break;
+
+ case S_DISCONNECT_PEND:
+ case S_CLOSE:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ RetOnErr(SendRD(pIrlapCb));
+ if (pIrlapCb->State != S_CLOSE)
+ pIrlapCb->State = S_CLOSE;
+ }
+ break;
+
+ case S_ERROR:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ RetOnErr(SendFRMR(pIrlapCb, &FrmRejFormat));
+ pIrlapCb->State = S_NRM;
+ }
+ break;
+
+ default:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessInvalidNr(PIRLAP_CB pIrlapCb,
+ int PFBit)
+{
+ DEBUGMSG(DBG_ERROR, (TEXT("IRLAP: ERROR, Invalid Nr\r\n")));
+
+ RetOnErr(ReturnTxMsgs(pIrlapCb));
+
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ if (PFBit == IRLAP_PFBIT_SET)
+ {
+ RetOnErr(SendDISC(pIrlapCb));
+ pIrlapCb->RetryCnt = 0;
+ // F-timer will be started by caller
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ }
+ else
+ {
+ pIrlapCb->State = P_DISCONNECT_PEND;
+ }
+ }
+ else // SECONDARY
+ {
+ if (PFBit == IRLAP_PFBIT_SET)
+ {
+ FrmRejFormat.Vs = pIrlapCb->Vs;
+ FrmRejFormat.Vr = pIrlapCb->Vr;
+ FrmRejFormat.W = 0;
+ FrmRejFormat.X = 0;
+ FrmRejFormat.Y = 0;
+ FrmRejFormat.Z = 1; // bad NR
+ RetOnErr(SendFRMR(pIrlapCb, &FrmRejFormat));
+ }
+ }
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessIFrame(PIRLAP_CB pIrlapCb,
+ PIRDA_MSG pMsg,
+ int CRBit,
+ int PFBit,
+ UINT Ns,
+ UINT Nr,
+ BOOL *pFreeMsg)
+{
+#ifdef DEBUG
+ BYTE *p1, *p2;
+#endif
+
+ pMsg->IRDA_MSG_pRead += 2; // chop the IRLAP header
+
+ switch (pIrlapCb->State)
+ {
+ case S_NRM:
+ case P_RECV:
+ // Stop Timers: if PFSet stop Final (I frame from secondary)
+ // Always stop WDog (I from primary)
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ if (PFBit == IRLAP_PFBIT_SET)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ }
+ else
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+
+ if (pIrlapCb->CRBit == CRBit)
+ {
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+ return SUCCESS;
+ }
+
+ if (InvalidNsOrNr(pIrlapCb, Ns, Nr))
+ {
+#ifdef DEBUG
+ p1 = pMsg->IRDA_MSG_pRead - 2; // Get header back
+ p2 = pMsg->IRDA_MSG_pWrite + 2; // and FCS
+
+ while (p1 < p2)
+ DEBUGMSG(DBG_ERROR, (TEXT("%02X "), *p1++));
+ DEBUGMSG(DBG_ERROR, (TEXT("\n")));
+#endif
+
+#ifdef TEMPERAMENTAL_SERIAL_DRIVER
+ if (pIrlapCb->RxWin.FCS[Ns] == pMsg->IRDA_MSG_FCS)
+ TossedDups++;
+ else
+ RetOnErr(ProcessInvalidNsOrNr(pIrlapCb, PFBit));
+#else
+ RetOnErr(ProcessInvalidNsOrNr(pIrlapCb, PFBit));
+#endif
+ }
+ else
+ {
+ if (PFBit == IRLAP_PFBIT_SET)
+ {
+ RetOnErr(InsertRxWinAndForward(pIrlapCb,
+ pMsg, Ns, pFreeMsg));
+
+ if (Nr != pIrlapCb->Vs)
+ {
+ RetOnErr(ResendRejects(pIrlapCb, Nr)); // always turns link
+ }
+ else // Nr == Vs, Good Nr
+ {
+ RetOnErr(FreeAckedTxMsgs(pIrlapCb, Nr));
+ // Link will always be turned here
+ if (pIrlapCb->Vr != pIrlapCb->RxWin.End)
+ {
+ RetOnErr(MissingRxFrames(pIrlapCb));
+ }
+ else
+ {
+ RetOnErr(XmitTxMsgList(pIrlapCb, TRUE, NULL));
+ }
+ }
+ }
+ else // PF Bit not set
+ {
+ RetOnErr(InsertRxWinAndForward(pIrlapCb,
+ pMsg, Ns, pFreeMsg));
+ RetOnErr(FreeAckedTxMsgs(pIrlapCb, Nr));
+ }
+ }
+ // Start Timers: If PFBit set, link was turned so start final
+ // WDog is always stopped, so restart
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ if (PFBit == IRLAP_PFBIT_SET)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ }
+ else // command from primary
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+ break;
+
+ default:
+ RetOnErr(IFrameOtherStates(pIrlapCb, CRBit, PFBit));
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+*
+* @ex
+* example
+*/
+BOOL
+InvalidNsOrNr(PIRLAP_CB pIrlapCb,
+ UINT Ns,
+ UINT Nr)
+{
+ if (InvalidNr(pIrlapCb, Nr))
+ {
+ return TRUE;
+ }
+
+ // Valididate ns
+ if (!InWindow(pIrlapCb->Vr,
+ (pIrlapCb->RxWin.Start + pIrlapCb->LocalWinSize-1) % IRLAP_MOD, Ns)
+ || !InWindow(pIrlapCb->RxWin.Start,
+ (pIrlapCb->RxWin.Start + pIrlapCb->LocalWinSize-1) % IRLAP_MOD, Ns))
+ {
+ DEBUGMSG(DBG_ERROR,
+ (TEXT("IRLAP: ERROR, Invalid Ns=%d! Vr=%d, RxStrt=%d Win=%d\r\n"),
+ Ns, pIrlapCb->Vr, pIrlapCb->RxWin.Start, pIrlapCb->LocalWinSize));
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("** INVALID Ns **")));
+ return TRUE;
+ }
+ return FALSE;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+*
+* @ex
+* example
+*/
+BOOL
+InvalidNr(PIRLAP_CB pIrlapCb,
+ UINT Nr)
+{
+ if (!InWindow(pIrlapCb->TxWin.Start, pIrlapCb->Vs, Nr))
+ {
+ DEBUGMSG(DBG_ERROR,
+ (TEXT("IRLAP: ERROR, Invalid Nr=%d! Vs=%d, TxStrt=%d\r\n"),
+ Nr, pIrlapCb->Vs, pIrlapCb->TxWin.Start));
+ return TRUE; // Invalid Nr
+ }
+ return FALSE;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+BOOL
+InWindow(UINT Start, UINT End, UINT i)
+{
+ if (Start <= End)
+ {
+ if (i >= Start && i <= End)
+ return TRUE;
+ }
+ else
+ {
+ if (i >= Start || i <= End)
+ return TRUE;
+ }
+ return FALSE;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ProcessInvalidNsOrNr(PIRLAP_CB pIrlapCb,
+ int PFBit)
+{
+ RetOnErr(ReturnTxMsgs(pIrlapCb));
+
+ if (PRIMARY == pIrlapCb->StationType)
+ {
+ if (PFBit == IRLAP_PFBIT_SET)
+ {
+ RetOnErr(SendDISC(pIrlapCb));
+ pIrlapCb->RetryCnt = 0;
+ // F-timer will be started by caller
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ }
+ else
+ {
+ pIrlapCb->State = P_DISCONNECT_PEND;
+ }
+ }
+ else // SECONDARY
+ {
+ FrmRejFormat.Vs = pIrlapCb->Vs;
+ FrmRejFormat.Vr = pIrlapCb->Vr;
+ FrmRejFormat.W = 0;
+ FrmRejFormat.X = 0;
+ FrmRejFormat.Y = 0;
+ FrmRejFormat.Z = 1; // bad NR
+ if (PFBit == IRLAP_PFBIT_SET)
+ {
+ RetOnErr(SendFRMR(pIrlapCb, &FrmRejFormat));
+ }
+ else
+ {
+ pIrlapCb->State = S_ERROR;
+ }
+ }
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+InsertRxWinAndForward(PIRLAP_CB pIrlapCb,
+ PIRDA_MSG pMsg,
+ UINT Ns,
+ BOOL *pFreeMsg)
+{
+ UINT rc = SUCCESS;
+
+ // insert message into receive window
+ pIrlapCb->RxWin.pMsg[Ns] = pMsg;
+#ifdef TEMPERAMENTAL_SERIAL_DRIVER
+ pIrlapCb->RxWin.FCS[Ns] = pMsg->IRDA_MSG_FCS;
+#endif
+
+ // Advance RxWin.End to Ns+1 if Ns is at or beyond RxWin.End
+ if (!InWindow(pIrlapCb->RxWin.Start, pIrlapCb->RxWin.End, Ns) ||
+ Ns == pIrlapCb->RxWin.End)
+ {
+ pIrlapCb->RxWin.End = (Ns + 1) % IRLAP_MOD;
+ }
+
+ // Forward in sequence frames starting from Vr
+ while (pIrlapCb->RxWin.pMsg[pIrlapCb->Vr] != NULL && !pIrlapCb->LocalBusy)
+ {
+ pIrlapCb->RxWin.pMsg[pIrlapCb->Vr]->Prim = IRLAP_DATA_IND;
+
+ rc =IrlmpUp(pIrlapCb->pIrdaLinkCb, pIrlapCb->RxWin.pMsg[pIrlapCb->Vr]);
+
+ if (rc == SUCCESS || rc == IRLMP_LOCAL_BUSY)
+ {
+ // Delivered successfully. Done with this message. Remove it from
+ // the RxWin and return message to rx free list. Update Vr
+
+/* !!! here it is again
+ RetOnErr(EnqueMsgList(&pIrlapCb->RxMsgFreeList,
+ pIrlapCb->RxWin.pMsg[pIrlapCb->Vr],
+ pIrlapCb->MaxRxMsgFreeListLen));
+*/
+ pIrlapCb->RxWin.pMsg[pIrlapCb->Vr] = NULL;
+ pIrlapCb->Vr = (pIrlapCb->Vr + 1) % IRLAP_MOD;
+
+ // LMP doesn't want anymore messages
+ if (rc == IRLMP_LOCAL_BUSY)
+ {
+ // The receive window will be cleaned out when RNR is sent
+ pIrlapCb->LocalBusy = TRUE;
+ }
+ }
+ else
+ {
+ return rc;
+ }
+ }
+ *pFreeMsg = FALSE; // we either already freed it or placed it in the window
+ // i.e. the caller should not free the message
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ResendRejects(PIRLAP_CB pIrlapCb, UINT Nr)
+{
+ if (!pIrlapCb->RemoteBusy)
+ {
+ // Set Vs back
+
+ for (pIrlapCb->Vs = Nr;pIrlapCb->Vs != (pIrlapCb->TxWin.End-1)%IRLAP_MOD;
+ pIrlapCb->Vs = (pIrlapCb->Vs + 1) % IRLAP_MOD)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("RETRANSMISSION:")));
+ RetOnErr(SendIFrame(pIrlapCb,
+ pIrlapCb->TxWin.pMsg[pIrlapCb->Vs],
+ pIrlapCb->Vs,
+ IRLAP_PFBIT_CLEAR));
+ }
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("RETRANSMISSION:")));
+ // Send last one with PFBit set
+ RetOnErr(SendIFrame(pIrlapCb, pIrlapCb->TxWin.pMsg[pIrlapCb->Vs],
+ pIrlapCb->Vs, IRLAP_PFBIT_SET));
+
+ pIrlapCb->Vs = (pIrlapCb->Vs + 1) % IRLAP_MOD; // Vs == TxWin.End
+ }
+ else
+ {
+ RetOnErr(SendRR_RNR(pIrlapCb));
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+FreeAckedTxMsgs(PIRLAP_CB pIrlapCb,
+ UINT Nr)
+{
+ UINT i = pIrlapCb->TxWin.Start;
+
+ while (i != Nr)
+ {
+ if (pIrlapCb->TxWin.pMsg[i] != NULL)
+ {
+ pIrlapCb->TxWin.pMsg[i]->Prim = IRLAP_DATA_CONF;
+ pIrlapCb->TxWin.pMsg[i]->IRDA_MSG_DataStatus =
+ IRLAP_DATA_REQUEST_COMPLETED;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, pIrlapCb->TxWin.pMsg[i]));
+
+ pIrlapCb->TxWin.pMsg[i] = NULL;
+ }
+ i = (i + 1) % IRLAP_MOD;
+ }
+ pIrlapCb->TxWin.Start = i;
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+MissingRxFrames(PIRLAP_CB pIrlapCb)
+{
+ int MissingFrameCnt = 0;
+ int MissingFrame = -1;
+ UINT i;
+
+ i = pIrlapCb->Vr;
+
+ // Count missing frame, determine first missing frame
+
+ for (i = pIrlapCb->Vr; (i + 1) % IRLAP_MOD != pIrlapCb->RxWin.End;
+ i = (i+1) % IRLAP_MOD)
+ {
+ if (pIrlapCb->RxWin.pMsg[i] == NULL)
+ {
+ MissingFrameCnt++;
+ if (MissingFrame == -1)
+ {
+ MissingFrame = i;
+ }
+ }
+ }
+
+ // if there are missing frames send SREJ (1) or RR (more than 1)
+ // and turn link around
+ if (MissingFrameCnt == 1 && !pIrlapCb->LocalBusy)
+ {
+ // we don't want to send the SREJ when local is busy because
+ // peer *MAY* interpret it as a clearing of the local busy condition
+ RetOnErr(SendSREJ(pIrlapCb, MissingFrame));
+ }
+ else
+ {
+ // The RR/RNR will serve as an implicit REJ
+ RetOnErr(SendRR_RNR(pIrlapCb));
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+IFrameOtherStates(PIRLAP_CB pIrlapCb,
+ int CRBit,
+ int PFBit)
+{
+ switch (pIrlapCb->State)
+ {
+ case NDM:
+ case DSCV_MEDIA_SENSE:
+ case DSCV_QUERY:
+ case DSCV_REPLY:
+ case CONN_MEDIA_SENSE:
+ case SNRM_SENT:
+ case BACKOFF_WAIT:
+ case SNRM_RECEIVED:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ return SUCCESS;
+ }
+
+ if (pIrlapCb->CRBit == CRBit) // should be opposite of mine
+ {
+ if (pIrlapCb->StationType == PRIMARY)
+ {
+ if (pIrlapCb->State == P_XMIT)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->PollTimer);
+ }
+ else
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ }
+ else
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+ RetOnErr(StationConflict(pIrlapCb));
+ pIrlapCb->State = NDM;
+
+ return SUCCESS;
+ }
+
+ if (pIrlapCb->StationType == PRIMARY) // I'm PRIMARY, this is a
+ { // response from secondary
+ switch (pIrlapCb->State)
+ {
+ case P_DISCONNECT_PEND:
+ if (PFBit == IRLAP_PFBIT_CLEAR)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ }
+ else
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ RetOnErr(SendDISC(pIrlapCb));
+ pIrlapCb->RetryCnt = 0;
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ RetOnErr(GotoPCloseState(pIrlapCb));
+ }
+ break;
+
+ case P_CLOSE:
+ if (PFBit == IRLAP_PFBIT_CLEAR)
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ }
+ else
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->FinalTimer);
+ RetOnErr(ResendDISC(pIrlapCb));
+ if (pIrlapCb->State != NDM)
+ {
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ }
+ break;
+
+ case S_CLOSE:
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ break;
+
+ default:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ }
+ }
+ else
+ {
+ switch (pIrlapCb->State)
+ {
+ case S_DISCONNECT_PEND:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ RetOnErr(SendRD(pIrlapCb));
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ pIrlapCb->State = S_CLOSE;
+ }
+ else
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ }
+ break;
+
+ case S_ERROR:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ RetOnErr(SendFRMR(pIrlapCb, &FrmRejFormat));
+ pIrlapCb->State = S_NRM;
+ }
+ else
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+ break;
+
+ case S_CLOSE:
+ if (IRLAP_PFBIT_SET == PFBit)
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ RetOnErr(SendRD(pIrlapCb));
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+ else
+ {
+ IRLAP_TimerStop(pIrlapCb, &pIrlapCb->WDogTimer);
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+ default:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignore in this state")));
+ }
+ }
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func UINT | StationConflict | Sends disconnect due to receipt of
+* by primary of frame with Poll
+*
+* @rdesc SUCCESS otherwise one of the following errors:
+* @flag val | desc
+*
+* @comm
+* comments
+*/
+UINT
+StationConflict(PIRLAP_CB pIrlapCb)
+{
+ InitializeState(pIrlapCb, PRIMARY); // Primary doesn't mean anything here
+
+ RetOnErr(ApplyDefaultParms(pIrlapCb));
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_PRIMARY_CONFLICT;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func UINT | ApplyDefaultParms | Apply default parameters and
+* reinitalize MAC
+*
+* @rdesc SUCCESS otherwise one of the following errors:
+* @flag val | desc
+*
+*/
+UINT
+ApplyDefaultParms(PIRLAP_CB pIrlapCb)
+{
+ pIrlapCb->Baud = IRLAP_DEFAULT_BAUD;
+
+ pIrlapCb->RemoteMaxTAT = IRLAP_DEFAULT_MAX_TAT;
+
+ pIrlapCb->RemoteDataSize = IRLAP_DEFAULT_DATA_SIZE;
+
+ pIrlapCb->RemoteWinSize = IRLAP_DEFAULT_WIN_SIZE;
+
+ pIrlapCb->RemoteNumBOFS = IRLAP_DEFAULT_BOFS;
+
+ pIrlapCb->ConnAddr = IRLAP_BROADCAST_CONN_ADDR;
+
+ IMsg.Prim = MAC_CONTROL_REQ;
+ IMsg.IRDA_MSG_Op = MAC_RECONFIG_LINK;
+ IMsg.IRDA_MSG_Baud = IRLAP_DEFAULT_BAUD;
+ IMsg.IRDA_MSG_NumBOFs = IRLAP_DEFAULT_BOFS;
+ IMsg.IRDA_MSG_DataSize = IRLAP_DEFAULT_DATA_SIZE;
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ - reconfig link")));
+
+ return (IrmacDown(pIrlapCb->pIrdaLinkCb,&IMsg));
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+ResendDISC(PIRLAP_CB pIrlapCb)
+{
+ if (pIrlapCb->RetryCnt >= pIrlapCb->N3)
+ {
+ RetOnErr(ApplyDefaultParms(pIrlapCb));
+ pIrlapCb->RetryCnt = 0;
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_NO_RESPONSE;
+ RetOnErr(IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg));
+ pIrlapCb->State = NDM;
+ }
+ else
+ {
+ RetOnErr(SendDISC(pIrlapCb));
+ pIrlapCb->RetryCnt++;
+ }
+ return SUCCESS;
+}
+
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+BOOL
+IgnoreState(PIRLAP_CB pIrlapCb)
+{
+ switch (pIrlapCb->State)
+ {
+ case NDM:
+ case DSCV_MEDIA_SENSE:
+ case DSCV_QUERY:
+ case DSCV_REPLY:
+ case CONN_MEDIA_SENSE:
+ case SNRM_SENT:
+ case BACKOFF_WAIT:
+ case SNRM_RECEIVED:
+ case P_XMIT:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring in this state")));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+VOID
+QueryTimerExp(PVOID Context)
+{
+ PIRLAP_CB pIrlapCb = (PIRLAP_CB) Context;
+
+ IRLAP_LOG_START((pIrlapCb, "Query timer expired"));
+
+ if (pIrlapCb->State == DSCV_REPLY)
+ {
+ pIrlapCb->State = NDM;
+ }
+ else
+ {
+ IRLAP_LOG_ACTION((pIrlapCb,
+ TEXT("Ignoring QueryTimer Expriation in state %s"),
+ IRLAP_StateStr[pIrlapCb->State]));
+ }
+
+ IRLAP_LOG_COMPLETE(pIrlapCb);
+
+ return;
+}
+
+VOID
+SlotTimerExp(PVOID Context)
+{
+ PIRLAP_CB pIrlapCb = (PIRLAP_CB) Context;
+
+ IRLAP_LOG_START((pIrlapCb, "Slot timer expired"));
+
+ if (pIrlapCb->State == DSCV_QUERY)
+ {
+ pIrlapCb->SlotCnt++;
+ SendDscvXIDCmd(pIrlapCb);
+ if (pIrlapCb->SlotCnt < pIrlapCb->MaxSlot)
+ {
+ IMsg.Prim = MAC_CONTROL_REQ;
+ IMsg.IRDA_MSG_Op = MAC_MEDIA_SENSE;
+ IMsg.IRDA_MSG_SenseTime = IRLAP_DSCV_SENSE_TIME;
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_CONTROL_REQ (dscv sense)")));
+ IrmacDown(pIrlapCb->pIrdaLinkCb,&IMsg);
+ }
+ else
+ {
+ pIrlapCb->GenNewAddr = FALSE;
+
+ IMsg.Prim = IRLAP_DISCOVERY_CONF;
+ IMsg.IRDA_MSG_pDevList = &pIrlapCb->DevList;
+ IMsg.IRDA_MSG_DscvStatus = IRLAP_DISCOVERY_COMPLETED;
+
+ // Change state now so IRLMP can do DISCOVERY_REQ on this thread
+ pIrlapCb->State = NDM;
+
+ IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
+ }
+ }
+ else
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring SlotTimer Expriation in state %s"),
+ IRLAP_StateStr[pIrlapCb->State]));
+ ; // maybe return bad state ???
+ }
+ IRLAP_LOG_COMPLETE(pIrlapCb);
+ return;
+}
+
+VOID
+FinalTimerExp(PVOID Context)
+{
+ PIRLAP_CB pIrlapCb = (PIRLAP_CB) Context;
+
+ IRLAP_LOG_START((pIrlapCb, "Final timer expired"));
+
+ pIrlapCb->NoResponse = TRUE;
+
+ switch (pIrlapCb->State)
+ {
+ case SNRM_SENT:
+ if (pIrlapCb->RetryCnt < pIrlapCb->N3)
+ {
+ pIrlapCb->BackoffTimer.Timeout = IRLAP_BACKOFF_TIME();
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->BackoffTimer);
+ pIrlapCb->State = BACKOFF_WAIT;
+ }
+ else
+ {
+ ApplyDefaultParms(pIrlapCb);
+
+ pIrlapCb->RetryCnt = 0;
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_NO_RESPONSE;
+ IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
+ pIrlapCb->State = NDM;
+ }
+ break;
+
+ case P_RECV:
+ if (pIrlapCb->RetryCnt == pIrlapCb->N2)
+ {
+ ReturnTxMsgs(pIrlapCb);
+ ApplyDefaultParms(pIrlapCb);
+
+ pIrlapCb->RetryCnt = 0; // Don't have to, do it for logger
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_NO_RESPONSE;
+ IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
+ pIrlapCb->State = NDM;
+ }
+ else
+ {
+ pIrlapCb->RetryCnt++;
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ SendRR_RNR(pIrlapCb);
+ if (pIrlapCb->RetryCnt == pIrlapCb->N1)
+ {
+ IMsg.Prim = IRLAP_STATUS_IND;
+ IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
+ }
+ }
+ break;
+
+ case P_DISCONNECT_PEND:
+ SendDISC(pIrlapCb);
+ pIrlapCb->RetryCnt = 0;
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ GotoPCloseState(pIrlapCb);
+ break;
+
+ case P_CLOSE:
+ if (pIrlapCb->RetryCnt >= pIrlapCb->N3)
+ {
+ ApplyDefaultParms(pIrlapCb);
+
+ pIrlapCb->RetryCnt = 0; // Don't have to, do it for logger
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_NO_RESPONSE;
+ IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
+ GotoNDMThenDscvOrConn(pIrlapCb);
+ }
+ else
+ {
+ pIrlapCb->RetryCnt++;
+ SendDISC(pIrlapCb);
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ }
+ break;
+
+ default:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring Final Expriation in state %s"),
+ IRLAP_StateStr[pIrlapCb->State]));
+ }
+
+ IRLAP_LOG_COMPLETE(pIrlapCb);
+ return;
+}
+
+VOID
+PollTimerExp(PVOID Context)
+{
+ PIRLAP_CB pIrlapCb = (PIRLAP_CB) Context;
+
+ IRLAP_LOG_START((pIrlapCb, "Poll timer expired"));
+
+ if (pIrlapCb->State == P_XMIT)
+ {
+ SendRR_RNR(pIrlapCb);
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ pIrlapCb->State = P_RECV;
+ }
+ else
+ {
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignoring Poll Expriation in state %s"),
+ IRLAP_StateStr[pIrlapCb->State]));
+ }
+
+ IRLAP_LOG_COMPLETE(pIrlapCb);
+ return;
+}
+
+VOID
+BackoffTimerExp(PVOID Context)
+{
+ PIRLAP_CB pIrlapCb = (PIRLAP_CB) Context;
+
+ IRLAP_LOG_START((pIrlapCb, "Backoff timer expired"));
+
+ if (pIrlapCb->State == BACKOFF_WAIT)
+ {
+ SendSNRM(pIrlapCb, TRUE);
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->FinalTimer);
+ pIrlapCb->RetryCnt += 1;
+ pIrlapCb->State = SNRM_SENT;
+ }
+ else
+ {
+ IRLAP_LOG_ACTION((pIrlapCb,
+ TEXT("Ignoring BackoffTimer Expriation in this state ")));
+ }
+ IRLAP_LOG_COMPLETE(pIrlapCb);
+ return;
+}
+
+VOID
+WDogTimerExp(PVOID Context)
+{
+ PIRLAP_CB pIrlapCb = (PIRLAP_CB) Context;
+
+ IRLAP_LOG_START((pIrlapCb, "WDog timer expired"));
+
+ pIrlapCb->NoResponse = TRUE;
+
+ switch (pIrlapCb->State)
+ {
+ case S_DISCONNECT_PEND:
+ case S_NRM:
+ pIrlapCb->WDogExpCnt++;
+ // Disconnect/threshold time is in seconds
+ if (pIrlapCb->WDogExpCnt * (int)pIrlapCb->WDogTimer.Timeout >=
+ pIrlapCb->DisconnectTime * 1000)
+ {
+ ReturnTxMsgs(pIrlapCb);
+ ApplyDefaultParms(pIrlapCb);
+
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_NO_RESPONSE;
+ IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
+ pIrlapCb->State = NDM;
+ }
+ else
+ {
+ if ((pIrlapCb->WDogExpCnt * (int) pIrlapCb->WDogTimer.Timeout >=
+ pIrlapCb->ThresholdTime * 1000) && !pIrlapCb->StatusSent)
+ {
+ IMsg.Prim = IRLAP_STATUS_IND;
+ IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
+ pIrlapCb->StatusSent = TRUE;
+ }
+ IRLAP_TimerStart(pIrlapCb, &pIrlapCb->WDogTimer);
+ }
+ break;
+
+ case S_CLOSE:
+ ApplyDefaultParms(pIrlapCb);
+
+ IMsg.Prim = IRLAP_DISCONNECT_IND;
+ IMsg.IRDA_MSG_DiscStatus = IRLAP_NO_RESPONSE;
+ IrlmpUp(pIrlapCb->pIrdaLinkCb, &IMsg);
+ pIrlapCb->State = NDM;
+ break;
+
+ default:
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("Ignore WDogTimer expiration in state %s"),
+ IRLAP_StateStr[pIrlapCb->State]));
+ }
+ IRLAP_LOG_COMPLETE(pIrlapCb);
+ return;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+UINT
+DequeMsgList(IRDA_MSG_LIST *pList, IRDA_MSG **ppMsg)
+{
+ if (pList->Len != 0)
+ {
+ *ppMsg = (IRDA_MSG *) RemoveHeadList(&pList->ListHead);
+/**
+ {
+ IRDA_MSG *pAMsg = pList->ListHead.Flink;
+
+ printf(TEXT("\nDEQUE: %x\n"), *ppMsg);
+
+ while (pAMsg != &(pList->ListHead))
+ {
+ printf(TEXT("%x->"),pAMsg);
+ pAMsg = pAMsg->Linkage.Flink;
+ }
+ printf(TEXT("\n"));
+ }
+**/
+ pList->Len--;
+ return SUCCESS;
+ }
+ return IRLAP_MSG_LIST_EMPTY;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+
+
+* @ex
+* example
+*/
+UINT
+EnqueMsgList(IRDA_MSG_LIST *pList, IRDA_MSG *pMsg, int MaxLen)
+{
+ if (MaxLen == -1 || pList->Len < MaxLen)
+ {
+ InsertTailList(&pList->ListHead, &(pMsg->Linkage));
+ pList->Len++;
+/**
+ {
+ IRDA_MSG *pAMsg = pList->ListHead.Flink;
+
+ printf(TEXT("\nENQUE: %x\n"), pMsg);
+ while (pAMsg != &(pList->ListHead))
+ {
+ printf(TEXT("%x->"),pAMsg);
+ pAMsg = pAMsg->Linkage.Flink;
+ }
+ printf(TEXT("\n"));
+ }
+**/
+ return SUCCESS;
+ }
+ return IRLAP_MSG_LIST_FULL;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+void
+InitMsgList(IRDA_MSG_LIST *pList)
+{
+ InitializeListHead(&pList->ListHead);
+ pList->Len = 0;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc return desc
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*
+* @ex
+* example
+*/
+/* !!!
+void
+IRLAP_PrintState()
+{
+#ifdef DEBUG
+ DEBUGMSG(1, (TEXT("IRLAP State %s\n"), IRLAP_StateStr[pIrlapCb->State]));
+#else
+ DEBUGMSG(1, (TEXT("IRLAP State %d\n"), pIrlapCb->State));
+#endif
+ DEBUGMSG(1,
+ (TEXT(" Vs=%d Vr=%d RxWin(%d,%d) TxWin(%d,%d) TxMsgListLen=%d RxMsgFreeListLen=%d\r\n"),
+ pIrlapCb->Vs, pIrlapCb->Vr,
+ pIrlapCb->RxWin.Start, pIrlapCb->RxWin.End,
+ pIrlapCb->TxWin.Start, pIrlapCb->TxWin.End,
+ pIrlapCb->TxMsgList.Len, pIrlapCb->RxMsgFreeList.Len));
+
+#ifdef TEMPERAMENTAL_SERIAL_DRIVER
+ DEBUGMSG(1, (TEXT(" Tossed duplicates %d\n"), TossedDups));
+#endif
+
+ IRMAC_PrintState();
+
+ return;
+}
+*/
+int
+GetMyDevAddr(BOOL New)
+{
+#ifdef PEG
+ HKEY hKey;
+ LONG hRes;
+ TCHAR KeyName[32];
+#endif
+ int DevAddr, NewDevAddr;
+ DWORD RegDevAddr = 0;
+ TCHAR ValName[] = TEXT("DevAddr");
+ LARGE_INTEGER li;
+
+ KeQueryTickCount(&li);
+
+ NewDevAddr = (int) li.LowPart;
+
+ // Get the device address from the registry. If the key exists and the
+ // value is 0, store a new random address. If no key, then return
+ // a random address.
+#ifdef PEG
+ _tcscpy (KeyName, COMM_REG_KEY);
+ _tcscat (KeyName, TEXT("IrDA"));
+
+ hRes = RegOpenKeyEx (HKEY_LOCAL_MACHINE, KeyName, 0, 0, &hKey);
+
+ if (hRes == ERROR_SUCCESS &&
+ GetRegDWORDValue(hKey, ValName, &RegDevAddr))
+ {
+ if (RegDevAddr == 0)
+ {
+ RegDevAddr = KeQueryTickCount();
+ SetRegDWORDValue(hKey, ValName, RegDevAddr);
+ }
+ RegCloseKey(hKey);
+
+ DevAddr = (int) RegDevAddr;
+ }
+#else
+ DevAddr = NewDevAddr;
+#endif
+ return DevAddr;
+}
+
diff --git a/private/ntos/tdi/irda/irlap/irlapio.c b/private/ntos/tdi/irda/irlap/irlapio.c
new file mode 100644
index 000000000..0c4a8361d
--- /dev/null
+++ b/private/ntos/tdi/irda/irlap/irlapio.c
@@ -0,0 +1,900 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: irlapio.c
+*
+* Description: IRLAP I/O routines
+*
+* Author: mbert
+*
+* Date: 4/25/95
+*
+*/
+#include <irda.h>
+#include <irdalink.h>
+#include <irmac.h>
+#include <irlap.h>
+#include <irlmp.h>
+#include <irlapp.h>
+#include <irlapio.h>
+#include <irlaplog.h>
+
+extern BYTE IRLAP_BroadcastDevAddr[];
+
+// The largest MAC message is the XID Frame consisting of address,
+// control, XID Format ID, XID format, + Discovery Information
+#define _MAC_MSG_LEN 3+sizeof(IRLAP_XID_DSCV_FORMAT)+IRLAP_DSCV_INFO_LEN
+
+//static BYTE IRLAP_MAC_MsgData[_MAC_MSG_LEN];
+//static IRDA_MSG MAC_Message;
+//static PIRDA_MSG pMACMsg = &MAC_Message;
+
+UINT
+SendFrame(PIRLAP_CB, PIRDA_MSG );
+
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*/
+UINT
+ClearRxWindow(PIRLAP_CB pIrlapCb)
+{
+ UINT i, rc;
+
+ // Remove everything from Rx window
+ for (i = pIrlapCb->Vr; i != pIrlapCb->RxWin.End; i = (i+1) % IRLAP_MOD)
+ {
+ if (pIrlapCb->RxWin.pMsg[i] != NULL)
+ {
+ /* !!! fix this OH SHIT
+ if((rc = EnqueMsgList(&pIrlapCb->RxMsgFreeList,
+ pIrlapCb->RxWin.pMsg[i],
+ pIrlapCb->MaxRxMsgFreeListLen)) != SUCCESS)
+ {
+ return rc;
+ }
+ */
+ pIrlapCb->RxWin.pMsg[i] = NULL;
+ }
+ pIrlapCb->RxWin.End = pIrlapCb->Vr;
+ }
+ return SUCCESS;
+}
+/*****************************************************************************
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*/
+UINT
+SendDscvXIDCmd(PIRLAP_CB pIrlapCb)
+{
+ UINT rc = SUCCESS;
+ IRLAP_XID_DSCV_FORMAT XIDFormat;
+ CHAR *DscvInfo;
+ int DscvInfoLen;
+ IRDA_MSG *pIMsg;
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+
+ memcpy(XIDFormat.SrcAddr, pIrlapCb->LocalDevice.DevAddr, IRDA_DEV_ADDR_LEN);
+ memcpy(XIDFormat.DestAddr, IRLAP_BroadcastDevAddr, IRDA_DEV_ADDR_LEN);
+
+ XIDFormat.NoOfSlots = IRLAP_SLOT_FLAG(pIrlapCb->MaxSlot);
+ XIDFormat.GenNewAddr = pIrlapCb->GenNewAddr;
+ XIDFormat.Reserved = 0;
+
+ if (pIrlapCb->SlotCnt == pIrlapCb->MaxSlot)
+ {
+ DscvInfo = pIrlapCb->LocalDevice.DscvInfo;
+ DscvInfoLen = pIrlapCb->LocalDevice.DscvInfoLen;
+ XIDFormat.SlotNo = IRLAP_END_DSCV_SLOT_NO;
+ }
+ else
+ {
+ DscvInfo = NULL;
+ DscvInfoLen = 0;
+ XIDFormat.SlotNo = pIrlapCb->SlotCnt;
+ }
+ XIDFormat.Version = pIrlapCb->LocalDevice.IRLAP_Version;
+
+ pIMsg->IRDA_MSG_pWrite = Format_DscvXID(pIMsg,
+ IRLAP_BROADCAST_CONN_ADDR,
+ IRLAP_CMD, IRLAP_PFBIT_SET,
+ &XIDFormat, DscvInfo,
+ DscvInfoLen);
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/****************************************************************************S*
+*
+* @func ret_type | func_name | funcdesc
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm data_type | parm_name | description
+*
+* @comm
+* comments
+*/
+UINT
+SendDscvXIDRsp(PIRLAP_CB pIrlapCb)
+{
+ UINT rc = SUCCESS;
+ IRLAP_XID_DSCV_FORMAT XIDFormat;
+ IRDA_MSG *pIMsg;
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+
+ XIDFormat.GenNewAddr = pIrlapCb->GenNewAddr;
+ if (pIrlapCb->GenNewAddr)
+ {
+ StoreULAddr(pIrlapCb->LocalDevice.DevAddr, GetMyDevAddr(TRUE));
+ pIrlapCb->GenNewAddr = FALSE;
+ }
+ memcpy(XIDFormat.SrcAddr, pIrlapCb->LocalDevice.DevAddr, IRDA_DEV_ADDR_LEN);
+ memcpy(XIDFormat.DestAddr, pIrlapCb->RemoteDevice.DevAddr, IRDA_DEV_ADDR_LEN);
+ XIDFormat.NoOfSlots = IRLAP_SLOT_FLAG(pIrlapCb->RemoteMaxSlot);
+ XIDFormat.Reserved = 0;
+ XIDFormat.SlotNo = pIrlapCb->RespSlot;
+ XIDFormat.Version = pIrlapCb->LocalDevice.IRLAP_Version;
+
+ pIMsg->IRDA_MSG_pWrite = Format_DscvXID(pIMsg,
+ IRLAP_BROADCAST_CONN_ADDR,
+ IRLAP_RSP, IRLAP_PFBIT_SET,
+ &XIDFormat,
+ pIrlapCb->LocalDevice.DscvInfo,
+ pIrlapCb->LocalDevice.DscvInfoLen);
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendSNRM | formats a SNRM frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm BYTE | ConnAddr | Connection address
+*
+* @comm
+* The ConnAddr can be different than that in the control block.
+* For reset, its the same, but set to broadcast for initial
+* connection.
+*/
+UINT
+SendSNRM(PIRLAP_CB pIrlapCb, BOOL SendQos)
+{
+ IRDA_QOS_PARMS *pQos = NULL;
+ int ConnAddr = pIrlapCb->ConnAddr;
+ IRDA_MSG *pIMsg;
+
+ if (SendQos)
+ {
+ ConnAddr = IRLAP_BROADCAST_CONN_ADDR;
+ pQos = &pIrlapCb->LocalQos;
+ }
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+
+ pIMsg->IRDA_MSG_pWrite = Format_SNRM(pIMsg, ConnAddr,
+ IRLAP_CMD,
+ IRLAP_PFBIT_SET,
+ pIrlapCb->LocalDevice.DevAddr,
+ pIrlapCb->RemoteDevice.DevAddr,
+ pIrlapCb->ConnAddr,
+ pQos);
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendUA | formats a UA frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm BOOL | SendQos | Send the Qos
+*
+* @comm
+* comments
+*/
+UINT
+SendUA(PIRLAP_CB pIrlapCb, BOOL SendQos)
+{
+ IRDA_QOS_PARMS NegQos;
+ IRDA_QOS_PARMS *pNegQos = NULL;
+ BYTE *pSrcAddr = NULL;
+ BYTE *pDestAddr = NULL;
+ IRDA_MSG *pIMsg;
+
+ if (SendQos)
+ {
+ // Put all parms (type 0 and 1) in NegQos
+ memcpy(&NegQos, &pIrlapCb->LocalQos, sizeof(IRDA_QOS_PARMS));
+ // Overwrite type 0 parameters that have already been negotiated
+ NegQos.bfBaud = pIrlapCb->NegotiatedQos.bfBaud;
+ NegQos.bfDisconnectTime = pIrlapCb->NegotiatedQos.bfDisconnectTime;
+ pNegQos = &NegQos;
+ }
+
+ // This will be moved into the "if" above when the spec is clarified
+ pSrcAddr = pIrlapCb->LocalDevice.DevAddr;
+ pDestAddr = pIrlapCb->RemoteDevice.DevAddr;
+ //------------------------------------------------------------------
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+
+ pIMsg->IRDA_MSG_pWrite = Format_UA(pIMsg,
+ pIrlapCb->ConnAddr,
+ IRLAP_RSP,
+ IRLAP_PFBIT_SET,
+ pSrcAddr, pDestAddr, pNegQos);
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendDM | formats a DM frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+*
+* @comm
+* comments
+*/
+UINT
+SendDM(PIRLAP_CB pIrlapCb)
+{
+ IRDA_MSG *pIMsg;
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+
+ pIMsg->IRDA_MSG_pWrite = Format_DM(pIMsg,
+ pIrlapCb->ConnAddr,
+ IRLAP_RSP,
+ IRLAP_PFBIT_SET);
+
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendRD | formats a RD frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+*
+* @comm
+* comments
+*/
+UINT
+SendRD(PIRLAP_CB pIrlapCb)
+{
+ IRDA_MSG *pIMsg;
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+
+ pIMsg->IRDA_MSG_pWrite = Format_RD(pIMsg,
+ pIrlapCb->ConnAddr,
+ IRLAP_RSP,
+ IRLAP_PFBIT_SET);
+
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendRR | formats a RR frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+*
+* @comm
+* comments
+*/
+UINT
+SendRR(PIRLAP_CB pIrlapCb)
+{
+ IRDA_MSG *pIMsg;
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+ ClearRxWindow(pIrlapCb);
+
+ pIrlapCb->RxWin.Start = pIrlapCb->Vr; // RxWin.Start = what we've acked
+
+ pIMsg->IRDA_MSG_pWrite = Format_RR(pIMsg, pIrlapCb->ConnAddr,
+ pIrlapCb->CRBit, IRLAP_PFBIT_SET,
+ pIrlapCb->Vr);
+
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendRNR | formats a RNR frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+*
+* @comm
+* comments
+*/
+UINT
+SendRR_RNR(PIRLAP_CB pIrlapCb)
+{
+ IRDA_MSG *pIMsg;
+
+ BYTE *(*pFormatRR_RNR)();
+
+ if (pIrlapCb->LocalBusy)
+ {
+ pFormatRR_RNR = Format_RNR;
+ }
+ else
+ {
+ pFormatRR_RNR = Format_RR;
+ }
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+ ClearRxWindow(pIrlapCb);
+
+
+ pIrlapCb->RxWin.Start = pIrlapCb->Vr; // RxWin.Start = what we've acked
+
+
+ pIMsg->IRDA_MSG_pWrite = (*pFormatRR_RNR)(pIMsg, pIrlapCb->ConnAddr,
+ pIrlapCb->CRBit, IRLAP_PFBIT_SET,
+ pIrlapCb->Vr);
+
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendDISC | formats a DISC frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+*
+* @comm
+* comments
+*/
+UINT
+SendDISC(PIRLAP_CB pIrlapCb)
+{
+ IRDA_MSG *pIMsg;
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+
+ pIMsg->IRDA_MSG_pWrite = Format_DISC(pIMsg, pIrlapCb->ConnAddr,
+ IRLAP_CMD, IRLAP_PFBIT_SET);
+
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendRNRM | formats a RNRM frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+*
+* @comm
+* comments
+*/
+UINT
+SendRNRM(PIRLAP_CB pIrlapCb)
+{
+ IRDA_MSG *pIMsg;
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+
+ pIMsg->IRDA_MSG_pWrite = Format_RNRM(pIMsg, pIrlapCb->ConnAddr,
+ IRLAP_RSP, IRLAP_PFBIT_SET);
+
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendREJ | formats a REJ frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+*
+* @comm
+* comments
+*/
+UINT
+SendREJ(PIRLAP_CB pIrlapCb)
+{
+ IRDA_MSG *pIMsg;
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+ ClearRxWindow(pIrlapCb);
+
+ pIrlapCb->RxWin.Start = pIrlapCb->Vr; // RxWin.Start = what we've acked
+
+ pIMsg->IRDA_MSG_pWrite = Format_REJ(pIMsg, pIrlapCb->ConnAddr,
+ pIrlapCb->CRBit, IRLAP_PFBIT_SET,
+ pIrlapCb->Vr);
+
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendSREJ | formats a SREJ frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm int | Nr | Nr to be placed in SREJ frame
+*
+* @comm
+* comments
+*/
+UINT
+SendSREJ(PIRLAP_CB pIrlapCb, int Nr)
+{
+ IRDA_MSG *pIMsg;
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+
+ pIMsg->IRDA_MSG_pWrite = Format_SREJ(pIMsg, pIrlapCb->ConnAddr,
+ pIrlapCb->CRBit, IRLAP_PFBIT_SET, Nr);
+
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendFRMR | formats a FRMR frame and sends it
+*
+* @rdesc SUCCESS, otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm int | Nr | Nr to be placed in SREJ frame
+*
+* @comm
+* comments
+*/
+UINT
+SendFRMR(PIRLAP_CB pIrlapCb, IRLAP_FRMR_FORMAT *pFRMRFormat)
+{
+ IRDA_MSG *pIMsg;
+
+ pIMsg = AllocMacIMsg(pIrlapCb->pIrdaLinkCb);
+
+ pIMsg->IRDA_MSG_pWrite = Format_FRMR(pIMsg, pIrlapCb->ConnAddr,
+ pIrlapCb->CRBit, IRLAP_PFBIT_SET,
+ pFRMRFormat);
+
+ return SendFrame(pIrlapCb, pIMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendIFrame | Builds and sends an I frame to MAC
+*
+* @rdesc SUCCESS otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm | |
+*
+* @comm
+* comments
+*/
+UINT
+SendIFrame(PIRLAP_CB pIrlapCb, PIRDA_MSG pMsg, int Ns, int PFBit)
+{
+ UINT rc;
+
+ if (NULL == pMsg)
+ {
+ return IRLAP_NULL_MSG;
+ }
+
+ ClearRxWindow(pIrlapCb);
+
+ pIrlapCb->RxWin.Start = pIrlapCb->Vr; // RxWin.Start = what we've acked
+
+ (void) Format_I(pMsg, pIrlapCb->ConnAddr, pIrlapCb->CRBit, PFBit,
+ pIrlapCb->Vr, Ns);
+
+ rc = SendFrame(pIrlapCb, pMsg);
+
+ pMsg->IRDA_MSG_pHdrRead +=2; // uglyness.. chop header in case frame
+ // requires retransmission
+ return rc;
+}
+/*****************************************************************************
+*
+* @func UINT | SendUIFrame | Builds and sends an UI frame to MAC
+*
+* @rdesc SUCCESS otherwise one of the following errors:
+* @flag val | desc
+*
+* @parm | |
+*
+* @comm
+* comments
+*/
+UINT
+SendUIFrame(PIRLAP_CB pIrlapCb, PIRDA_MSG pMsg)
+{
+ if (NULL == pMsg)
+ {
+ return IRLAP_NULL_MSG;
+ }
+ (void) Format_UI(pMsg, pIrlapCb->ConnAddr, pIrlapCb->CRBit,IRLAP_PFBIT_SET);
+
+ return SendFrame(pIrlapCb, pMsg);
+}
+/*****************************************************************************
+*
+* @func UINT | SendFrame | Builds and sends an Unnumbered frame to MAC
+*
+* @rdesc SUCCESS otherwise one of the following errors:
+* @flag val | desc
+*
+* @comm
+* comments
+*/
+UINT
+SendFrame(PIRLAP_CB pIrlapCb, PIRDA_MSG pMsg)
+{
+ UINT rc = SUCCESS;
+
+ pMsg->Prim = MAC_DATA_REQ;
+
+ rc = IrmacDown(pIrlapCb->pIrdaLinkCb, pMsg);
+
+ IRLAP_LOG_ACTION((pIrlapCb, TEXT("MAC_DATA_REQ: %s"), FrameToStr(pMsg)));
+
+ return rc;
+}
+/*****************************************************************************
+*
+* @func UINT | _IRLMP_Up | Adds logging to the IRLMP_Up
+*
+* @rdesc returns of IRLMP_Up
+*
+* @parm PIRDA_MSG | pMsg | pointer to IRDA message
+*
+* @comm
+* comments
+*/
+/*
+UINT
+_IRLMP_Up(PIRDA_MSG pMsg)
+{
+ IRLAP_LOG_ACTION((TEXT("%s%s"), IRDA_PrimStr[pMsg->Prim],
+ pMsg->Prim == IRLAP_DISCOVERY_CONF ?
+ IRDA_StatStr[pMsg->IRDA_MSG_DscvStatus] :
+ pMsg->Prim == IRLAP_CONNECT_CONF ?
+ IRDA_StatStr[pMsg->IRDA_MSG_ConnStatus] :
+ pMsg->Prim == IRLAP_DISCONNECT_IND ?
+ IRDA_StatStr[pMsg->IRDA_MSG_DiscStatus] :
+ pMsg->Prim == IRLAP_DATA_CONF || pMsg->Prim == IRLAP_UDATA_CONF ?
+ IRDA_StatStr[pMsg->IRDA_MSG_DataStatus] : TEXT("")));
+
+ return (IRLMP_Up(pMsg));
+}
+*/
+
+BYTE *
+BuildTuple(BYTE *pBuf, BYTE Pi, UINT BitField)
+{
+ *pBuf++ = Pi;
+
+ if (BitField > 0xFF)
+ {
+ *pBuf++ = 2; // Pl
+ *pBuf++ = (BYTE) (BitField >> 8);
+ *pBuf++ = (BYTE) (BitField);
+ }
+ else
+ {
+ *pBuf++ = 1; // Pl
+ *pBuf++ = (BYTE) (BitField);
+ }
+ return pBuf;
+}
+
+BYTE *
+BuildNegParms(BYTE *pBuf, IRDA_QOS_PARMS *pQos)
+{
+ pBuf = BuildTuple(pBuf, QOS_PI_BAUD, pQos->bfBaud);
+ pBuf = BuildTuple(pBuf, QOS_PI_MAX_TAT, pQos->bfMaxTurnTime);
+ pBuf = BuildTuple(pBuf, QOS_PI_DATA_SZ, pQos->bfDataSize);
+ pBuf = BuildTuple(pBuf, QOS_PI_WIN_SZ, pQos->bfWindowSize);
+ pBuf = BuildTuple(pBuf, QOS_PI_BOFS, pQos->bfBofs);
+ pBuf = BuildTuple(pBuf, QOS_PI_MIN_TAT, pQos->bfMinTurnTime);
+ pBuf = BuildTuple(pBuf, QOS_PI_DISC_THRESH, pQos->bfDisconnectTime);
+
+ return pBuf;
+}
+
+void
+StoreULAddr(BYTE Addr[], ULONG ULAddr)
+{
+ Addr[0] = (BYTE) ( 0xFF & ULAddr);
+ Addr[1] = (BYTE) ((0xFF00 & ULAddr) >> 8);
+ Addr[2] = (BYTE) ((0xFF0000 & ULAddr) >> 16);
+ Addr[3] = (BYTE) ((0xFF000000 & ULAddr) >> 24);
+}
+
+BYTE *
+_PutAddr(BYTE *pBuf, BYTE Addr[])
+{
+ *pBuf++ = Addr[0];
+ *pBuf++ = Addr[1];
+ *pBuf++ = Addr[2];
+ *pBuf++ = Addr[3];
+
+ return (pBuf);
+}
+
+void
+BuildUHdr(IRDA_MSG *pMsg, int FrameType, int Addr, int CRBit, int PFBit)
+{
+ if (pMsg->IRDA_MSG_pHdrRead != NULL)
+ {
+ pMsg->IRDA_MSG_pHdrRead -= 2;
+
+ ASSERT(pMsg->IRDA_MSG_pHdrRead >= pMsg->IRDA_MSG_Header);
+
+ *(pMsg->IRDA_MSG_pHdrRead) = (BYTE) _MAKE_ADDR(Addr, CRBit);
+ *(pMsg->IRDA_MSG_pHdrRead+1) = (BYTE) _MAKE_UCNTL(FrameType, PFBit);
+ }
+ else
+ {
+ pMsg->IRDA_MSG_pRead -= 2;
+ *(pMsg->IRDA_MSG_pRead) = (BYTE) _MAKE_ADDR(Addr, CRBit);
+ *(pMsg->IRDA_MSG_pRead+1) = (BYTE) _MAKE_UCNTL(FrameType, PFBit);
+ }
+ return;
+}
+
+void
+BuildSHdr(IRDA_MSG *pMsg, int FrameType, int Addr, int CRBit, int PFBit, int Nr)
+{
+ if (pMsg->IRDA_MSG_pHdrRead != NULL)
+ {
+ pMsg->IRDA_MSG_pHdrRead -= 2;
+
+ ASSERT(pMsg->IRDA_MSG_pHdrRead >= pMsg->IRDA_MSG_Header);
+
+ *(pMsg->IRDA_MSG_pHdrRead) = (BYTE) _MAKE_ADDR(Addr, CRBit);
+ *(pMsg->IRDA_MSG_pHdrRead+1) = (BYTE) _MAKE_SCNTL(FrameType, PFBit, Nr);
+ }
+ else
+ {
+ pMsg->IRDA_MSG_pRead -= 2;
+ *(pMsg->IRDA_MSG_pRead) = (BYTE) _MAKE_ADDR(Addr, CRBit);
+ *(pMsg->IRDA_MSG_pRead+1) = (BYTE) _MAKE_SCNTL(FrameType, PFBit, Nr);
+ }
+ return;
+}
+
+BYTE *
+Format_SNRM(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, BYTE SAddr[],
+ BYTE DAddr[], int CAddr, IRDA_QOS_PARMS *pQos)
+{
+ BuildUHdr(pMsg, IRLAP_SNRM, Addr, CRBit, PFBit);
+
+ if (pQos != NULL)
+ {
+ pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, SAddr);
+ pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, DAddr);
+ *pMsg->IRDA_MSG_pWrite++ = CAddr << 1; // Thats what the f'n spec says
+ pMsg->IRDA_MSG_pWrite = BuildNegParms(pMsg->IRDA_MSG_pWrite, pQos);
+ }
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_DISC(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit)
+{
+ BuildUHdr(pMsg, IRLAP_DISC, Addr, CRBit, PFBit);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_UI(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit)
+{
+ BuildUHdr(pMsg, IRLAP_UI, Addr, CRBit, PFBit);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_DscvXID(IRDA_MSG *pMsg, int ConnAddr, int CRBit, int PFBit,
+ IRLAP_XID_DSCV_FORMAT *pXIDFormat,
+ CHAR DscvInfo[], int DscvInfoLen)
+{
+ if (pMsg->IRDA_MSG_pHdrRead != NULL)
+ {
+ pMsg->IRDA_MSG_pHdrRead -= 2;
+
+ ASSERT(pMsg->IRDA_MSG_pHdrRead >= pMsg->IRDA_MSG_Header);
+
+ *(pMsg->IRDA_MSG_pHdrRead) = (BYTE) _MAKE_ADDR(ConnAddr, CRBit);
+ if (CRBit)
+ *(pMsg->IRDA_MSG_pHdrRead+1)=
+ (BYTE) _MAKE_UCNTL(IRLAP_XID_CMD, PFBit);
+ else
+ *(pMsg->IRDA_MSG_pHdrRead+1)=
+ (BYTE) _MAKE_UCNTL(IRLAP_XID_RSP, PFBit);
+ }
+ else
+ {
+ pMsg->IRDA_MSG_pRead -= 2;
+ *(pMsg->IRDA_MSG_pRead) = (BYTE) _MAKE_ADDR(ConnAddr, CRBit);
+ if (CRBit)
+ *(pMsg->IRDA_MSG_pRead+1)=
+ (BYTE) _MAKE_UCNTL(IRLAP_XID_CMD, PFBit);
+ else
+ *(pMsg->IRDA_MSG_pRead+1)=
+ (BYTE) _MAKE_UCNTL(IRLAP_XID_RSP, PFBit);
+ }
+
+ *pMsg->IRDA_MSG_pWrite++ = IRLAP_XID_DSCV_FORMAT_ID;
+
+ memcpy(pMsg->IRDA_MSG_pWrite, (CHAR *) pXIDFormat,
+ sizeof(IRLAP_XID_DSCV_FORMAT) - 1); // Subtract for FirstDscvByte
+ // in structure
+ pMsg->IRDA_MSG_pWrite += sizeof(IRLAP_XID_DSCV_FORMAT) - 1;
+
+ if (DscvInfo != NULL)
+ {
+ memcpy(pMsg->IRDA_MSG_pWrite, DscvInfo, DscvInfoLen);
+ pMsg->IRDA_MSG_pWrite += DscvInfoLen;
+ }
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_TEST(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit,
+ BYTE SAddr[], BYTE DAddr[])
+{
+ BuildUHdr(pMsg, IRLAP_TEST, Addr, CRBit, PFBit);
+
+ pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, SAddr);
+ pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, DAddr);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_RNRM(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit)
+{
+ BuildUHdr(pMsg, IRLAP_RNRM, Addr, CRBit, PFBit);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_UA(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, BYTE SAddr[],
+ BYTE DAddr[], IRDA_QOS_PARMS *pQos)
+{
+ BuildUHdr(pMsg, IRLAP_UA, Addr, CRBit, PFBit);
+
+ if (SAddr != NULL)
+ {
+ pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, SAddr);
+ }
+ if (DAddr != NULL)
+ {
+ pMsg->IRDA_MSG_pWrite = _PutAddr(pMsg->IRDA_MSG_pWrite, DAddr);
+ }
+
+ if (pQos != NULL)
+ pMsg->IRDA_MSG_pWrite = BuildNegParms(pMsg->IRDA_MSG_pWrite, pQos);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_FRMR(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit,
+ IRLAP_FRMR_FORMAT *pFormat)
+{
+ BuildUHdr(pMsg, IRLAP_FRMR, Addr, CRBit, PFBit);
+
+ memcpy(pMsg->IRDA_MSG_pWrite, (CHAR *)pFormat,sizeof(IRLAP_FRMR_FORMAT));
+ pMsg->IRDA_MSG_pWrite += sizeof(IRLAP_FRMR_FORMAT);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_DM(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit)
+{
+ BuildUHdr(pMsg, IRLAP_DM, Addr, CRBit, PFBit);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_RD(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit)
+{
+ BuildUHdr(pMsg, IRLAP_RD, Addr, CRBit, PFBit);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_RR(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr)
+{
+ BuildSHdr(pMsg, IRLAP_RR, Addr, CRBit, PFBit, Nr);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_RNR(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr)
+{
+ BuildSHdr(pMsg, IRLAP_RNR, Addr, CRBit, PFBit, Nr);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_REJ(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr)
+{
+ BuildSHdr(pMsg, IRLAP_REJ, Addr, CRBit, PFBit, Nr);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_SREJ(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr)
+{
+ BuildSHdr(pMsg, IRLAP_SREJ, Addr, CRBit, PFBit, Nr);
+
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+BYTE *
+Format_I(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr, int Ns)
+{
+ if (pMsg->IRDA_MSG_pHdrRead != NULL)
+ {
+ pMsg->IRDA_MSG_pHdrRead -= 2;
+
+ ASSERT(pMsg->IRDA_MSG_pHdrRead >= pMsg->IRDA_MSG_Header);
+
+ *(pMsg->IRDA_MSG_pHdrRead) = (BYTE) _MAKE_ADDR(Addr, CRBit);
+ *(pMsg->IRDA_MSG_pHdrRead+1) = (BYTE) (((Ns & 7) << 1) +
+ ((PFBit & 1)<< 4) + (Nr <<5));
+ }
+ else
+ {
+ pMsg->IRDA_MSG_pRead -= 2;
+ *(pMsg->IRDA_MSG_pRead) = (BYTE) _MAKE_ADDR(Addr, CRBit);
+ *(pMsg->IRDA_MSG_pRead+1) = (BYTE) (((Ns & 7) << 1) +
+ ((PFBit & 1)<< 4) + (Nr <<5));
+ }
+ return (pMsg->IRDA_MSG_pWrite);
+}
+
+
+// TEMP
+UINT IrlmpUp(PVOID IrlmpContext, PIRDA_MSG pIMsg)
+{
+ return 0;
+}
diff --git a/private/ntos/tdi/irda/irlap/irlapio.h b/private/ntos/tdi/irda/irlap/irlapio.h
new file mode 100644
index 000000000..f65d390eb
--- /dev/null
+++ b/private/ntos/tdi/irda/irlap/irlapio.h
@@ -0,0 +1,32 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: irlapio.h
+*
+* Description: prototypes for IRLAP I/O routines
+*
+* Author: mbert
+*
+* Date: 4/25/95
+*
+*/
+void SetMsgPointers(PIRLAP_CB, PIRDA_MSG);
+UINT SendDscvXIDCmd(PIRLAP_CB);
+UINT SendDscvXIDRsp(PIRLAP_CB);
+UINT SendSNRM(PIRLAP_CB, BOOL);
+UINT SendUA(PIRLAP_CB, BOOL);
+UINT SendDM(PIRLAP_CB);
+UINT SendRD(PIRLAP_CB);
+UINT SendRR(PIRLAP_CB);
+UINT SendRR_RNR(PIRLAP_CB);
+UINT SendDISC(PIRLAP_CB);
+UINT SendRNRM(PIRLAP_CB);
+UINT SendIFrame(PIRLAP_CB, PIRDA_MSG, int, int);
+UINT SendSREJ(PIRLAP_CB, int);
+UINT SendREJ(PIRLAP_CB);
+UINT SendFRMR(PIRLAP_CB, IRLAP_FRMR_FORMAT *);
+UINT SendUIFrame(PIRLAP_CB, PIRDA_MSG);
+UINT SendFrame(PIRLAP_CB, PIRDA_MSG);
+UINT _IRLMP_Up(PIRDA_MSG);
+
diff --git a/private/ntos/tdi/irda/irlap/irlaplog.c b/private/ntos/tdi/irda/irlap/irlaplog.c
new file mode 100644
index 000000000..ae95fa8c0
--- /dev/null
+++ b/private/ntos/tdi/irda/irlap/irlaplog.c
@@ -0,0 +1,265 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: irlaplog.c
+*
+* Description: IRLAP state machine logging and errors
+*
+* Author: mbert
+*
+* Date: 4/15/95
+*
+*/
+#include <irda.h>
+#include <irdalink.h>
+#include <irlap.h>
+#include <irlapp.h>
+#include <irlaplog.h>
+#include <decdirda.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define _IRLAPLOG_C_
+
+#ifdef DEBUG
+
+
+TCHAR *DecodeIRDA(int *pFrameType,// returned frame type (-1=bad frame)
+ BYTE *pFrameBuf, // pointer to buffer containing IRLAP frame
+ UINT FrameLen, // length of buffer
+ TCHAR *pOutStr, // string where decoded packet is placed
+ UINT DecodeLayer,// 1,LAP only, 2 LAP/LMP, 3, LAP/LMP/TTP
+ BOOL fNoConnAddr,// TRUE->Don't show connection address in str
+ int DispMode )
+{
+ *pOutStr = TEXT('\0');
+
+ return pOutStr;
+}
+TCHAR _ABuf[512];
+
+#ifndef PEG
+TCHAR _DecodeStr1[1000];
+TCHAR _DecodeStr2[1000];
+#else
+TCHAR _DecodeStr1[] = TEXT("(null)");
+TCHAR _DecodeStr2[] = TEXT("(null)");
+#endif
+
+int _FrameType;
+
+int ActCnt[10];
+
+int vNestedEvent = 0;
+
+// Keep in sync with IRLAP_STATE in irlap.h
+TCHAR *IRLAP_StateStr[] = {
+ TEXT("NDM"),
+ TEXT("DSCV_MEDIA_SENSE"),
+ TEXT("DSCV_QUERY"),
+ TEXT("DSCV_REPLY"),
+ TEXT("CONN_MEDIA_SENSE"),
+ TEXT("SNRM_SENT"),
+ TEXT("BACKOFF_WAIT"),
+ TEXT("SNRM_RECEIVED"),
+ TEXT("P_XMIT"),
+ TEXT("P_RECV"),
+ TEXT("P_DISCONNECT_PEND"),
+ TEXT("P_CLOSE"),
+ TEXT("S_NRM"),
+ TEXT("S_DISCONNECT_PEND"),
+ TEXT("S_ERROR"),
+ TEXT("S_CLOSE")
+};
+
+// Keep in sync with IRDA_SERVICE_PRIM in irda.h
+TCHAR *IRDA_PrimStr[] =
+{
+ TEXT("MAC_DATA_REQ"),
+ TEXT("MAC_DATA_IND"),
+ TEXT("MAC_CONTROL_REQ"),
+ TEXT("MAC_CONTROL_CONF"),
+ TEXT("IRLAP_DISCOVERY_REQ"),
+ TEXT("IRLAP_DISCOVERY_IND"),
+ TEXT("IRLAP_DISCOVERY_CONF"),
+ TEXT("IRLAP_CONNECT_REQ"),
+ TEXT("IRLAP_CONNECT_IND"),
+ TEXT("IRLAP_CONNECT_RESP"),
+ TEXT("IRLAP_CONNECT_CONF"),
+ TEXT("IRLAP_DISCONNECT_REQ"),
+ TEXT("IRLAP_DISCONNECT_IND"),
+ TEXT("IRLAP_DATA_REQ"),
+ TEXT("IRLAP_DATA_IND"),
+ TEXT("IRLAP_DATA_CONF"),
+ TEXT("IRLAP_UDATA_REQ"),
+ TEXT("IRLAP_UDATA_IND"),
+ TEXT("IRLAP_UDATA_CONF"),
+ TEXT("IRLAP_STATUS_IND"),
+ TEXT("IRLAP_FLOWON_REQ"),
+ TEXT("IRLAP_FLOWON_IND")
+ TEXT("IRLMP_DISCOVERY_REQ"),
+ TEXT("IRLMP_DISCOVERY_CONF"),
+ TEXT("IRLMP_CONNECT_REQ"),
+ TEXT("IRLMP_CONNECT_IND"),
+ TEXT("IRLMP_CONNECT_RESP"),
+ TEXT("IRLMP_CONNECT_CONF"),
+ TEXT("IRLMP_DISCONNECT_REQ"),
+ TEXT("IRLMP_DISCONNECT_IND"),
+ TEXT("IRLMP_DATA_REQ"),
+ TEXT("IRLMP_DATA_IND"),
+ TEXT("IRLMP_DATA_CONF"),
+ TEXT("IRLMP_UDATA_REQ"),
+ TEXT("IRLMP_UDATA_IND"),
+ TEXT("IRLMP_UDATA_CONF"),
+ TEXT("IRLMP_ACCESSMODE_REQ"),
+ TEXT("IRLMP_ACCESSMODE_IND"),
+ TEXT("IRLMP_ACCESSMODE_CONF"),
+ TEXT("IRLMP_FLOWON_REQ"),
+ TEXT("IRLMP_FLOWON_IND")
+};
+
+// keep in sync with IRDA_ServiceStatus in irda.h
+TCHAR *IRDA_StatStr[] =
+{
+ TEXT(" - MEDIA_BUSY"),
+ TEXT(" - MEDIA_CLEAR"),
+ TEXT(" - DISCOVERY_COLLISION"),
+ TEXT(" - REMOTE_DISCOVERY_IN_PROGRESS"),
+ TEXT(" - REMOTE_CONNECT_IN_PROGRSS"),
+ TEXT(" - DISCOVERY_COMPLETED"),
+ TEXT(" - REMOTE_CONNECTION_IN_PROGRESS"),
+ TEXT(" - CONNECTION_COMPLETED"),
+ TEXT(" - REMOTE_INITIATED"),
+ TEXT(" - PRIMARY_CONFLICT"),
+ TEXT(" - DISCONNECT_COMPLETE"),
+ TEXT(" - NO_RESPONSE"),
+ TEXT(" - IRLAP_DECLINE_RESET"),
+ TEXT(" - DATA_REQUEST_COMPLETED"),
+ TEXT(" - DATA_REQUEST_FAILED_LINK_RESET"),
+ TEXT(" - DATA_REQUEST_FAILED_REMOTE_BUSY")
+};
+
+// Keep in sync with MAC_CONTROL_OPERATION in irda.h
+TCHAR *MAC_OpStr[] =
+{
+ TEXT("initialize link"),
+ TEXT("shutdown link"),
+ TEXT("reconfig link"),
+ TEXT("media sense")
+};
+
+TCHAR
+*FrameToStr(IRDA_MSG *pMsg)
+{
+#ifndef PEG
+ BYTE *ptr;
+ int i = 0;
+ int j;
+ TCHAR *pD1 = _DecodeStr1;
+ TCHAR *pD2 = _DecodeStr2;
+
+ // copy the frame to a contiguous buffer
+
+ ptr = pMsg->IRDA_MSG_pHdrRead;
+ while (ptr != pMsg->IRDA_MSG_pHdrWrite)
+ {
+ _ABuf[i++] = *ptr++;
+ }
+ ptr = pMsg->IRDA_MSG_pRead;
+ while (ptr != pMsg->IRDA_MSG_pWrite)
+ {
+ _ABuf[i++] = *ptr++;
+ }
+
+ DecodeIRDA(&_FrameType, (char *)_ABuf, i, _DecodeStr1, 2, FALSE, 1);
+
+ // insert spaces and break-up into multiple lines
+ i = 0;
+ do
+ {
+ if (i++%69 == 0)
+ {
+ *pD2++ = TEXT('\r');
+ *pD2++ = TEXT('\n');
+ for (j = 0; j<7;j++)
+ {
+ *pD2++ = TEXT(' ');
+ }
+ }
+ *pD2++ = *pD1++;
+ } while (*pD1 != TEXT('\0'));
+
+ *pD2 = TEXT('\0');
+#endif
+ return (_DecodeStr2);
+}
+void
+IRLAP_EventLogStart(PIRLAP_CB pIrlapCb, TCHAR *pFormat, ...)
+{
+ va_list ArgList;
+
+ va_start (ArgList, pFormat);
+
+ if (++vNestedEvent == 1)
+ {
+ DEBUGMSG(DBG_IRLAPLOG, (TEXT("----------------\r\n")));
+ }
+ else
+ {
+ DEBUGMSG(DBG_IRLAPLOG, (TEXT("!!!!!!!!!!!!!!!!\r\n")));
+ }
+
+ DEBUGMSG(DBG_IRLAPLOG, (TEXT("Ev%d: "), vNestedEvent));
+
+ ActCnt[vNestedEvent] = 0;
+
+ vsprintf(_ABuf, pFormat, ArgList);
+ DEBUGMSG(DBG_IRLAPLOG, (_ABuf));
+
+ DEBUGMSG(DBG_IRLAPLOG, (TEXT("\r\nStart State: %s\r\nActions:\r\n"),
+ IRLAP_StateStr[pIrlapCb->State]));
+
+ va_end (ArgList);
+}
+
+void __cdecl
+IRLAP_LogAction(PIRLAP_CB pIrlapCb, TCHAR *pFormat, ...)
+{
+ va_list ArgList;
+
+ va_start (ArgList, pFormat);
+
+ DEBUGMSG(DBG_IRLAPLOG, (TEXT(" %d. "), ++ActCnt[vNestedEvent]));
+
+ vsprintf(_ABuf, pFormat, ArgList);
+ DEBUGMSG(DBG_IRLAPLOG, (_ABuf));
+
+ DEBUGMSG(DBG_IRLAPLOG, (TEXT("\n")));
+
+ va_end (ArgList);
+}
+
+#define PRINT_IF_TRUE(bool, str) (bool == TRUE ? str : TEXT(""))
+
+void
+IRLAP_EventLogComplete(PIRLAP_CB pIrlapCb)
+{
+ DEBUGMSG(DBG_IRLAPLOG,
+ (TEXT("Vs=%d Vr=%d RxWin(%d,%d) TxWin(%d,%d) TxListLen=%d\r\n"),
+ pIrlapCb->Vs, pIrlapCb->Vr,
+ pIrlapCb->RxWin.Start, pIrlapCb->RxWin.End,
+ pIrlapCb->TxWin.Start, pIrlapCb->TxWin.End,
+ pIrlapCb->TxMsgList.Len));
+
+ DEBUGMSG(DBG_IRLAPLOG, (TEXT("Ev%d End St: %s\r\n"),
+ vNestedEvent--, IRLAP_StateStr[pIrlapCb->State]));
+
+ if (vNestedEvent > 0)
+ {
+ DEBUGMSG(DBG_IRLAPLOG, (TEXT("!!!!!!!!!!!!!!!!\r\n")));
+ }
+}
+
+#endif
diff --git a/private/ntos/tdi/irda/irlap/irlapp.h b/private/ntos/tdi/irda/irlap/irlapp.h
new file mode 100644
index 000000000..bd2498263
--- /dev/null
+++ b/private/ntos/tdi/irda/irlap/irlapp.h
@@ -0,0 +1,299 @@
+/*****************************************************************************
+*
+* Copyright (c) 1995 Microsoft Corporation
+*
+* File: irlap.h
+*
+* Description: IRLAP Protocol and control block definitions
+*
+* Author: mbert
+*
+* Date: 4/15/95
+*
+*/
+
+#define IRLAP_MEDIA_SENSE_TIME 500
+#define IRLAP_SLOT_TIMEOUT 50
+#define IRLAP_DSCV_SENSE_TIME 30
+
+// XID Format
+#define IRLAP_XID_DSCV_FORMAT_ID 0x01
+#define IRLAP_XID_NEGPARMS_FORMAT_ID 0x02
+typedef struct
+{
+ BYTE SrcAddr[IRDA_DEV_ADDR_LEN];
+ BYTE DestAddr[IRDA_DEV_ADDR_LEN];
+ BYTE NoOfSlots:2;
+ BYTE GenNewAddr:1;
+ BYTE Reserved:5;
+ BYTE SlotNo;
+ BYTE Version;
+ BYTE FirstDscvInfoByte;
+} IRLAP_XID_DSCV_FORMAT;
+
+// Frame Reject Format
+typedef struct
+{
+ BYTE CntlField;
+ BYTE Fill1:1;
+ BYTE Vs:3;
+ BYTE CRBit:1;
+ BYTE Vr:3;
+ BYTE W:1;
+ BYTE X:1;
+ BYTE Y:1;
+ BYTE Z:1;
+ BYTE Fill2:4;
+} IRLAP_FRMR_FORMAT;
+
+// SNRM Frame Format
+typedef struct
+{
+ BYTE SrcAddr[IRDA_DEV_ADDR_LEN];
+ BYTE DestAddr[IRDA_DEV_ADDR_LEN];
+ BYTE ConnAddr; // actually shifted for CRBit -> STUPID !!
+ BYTE FirstQosByte;
+} IRLAP_SNRM_FORMAT;
+
+// UA Frame Format
+typedef struct
+{
+ BYTE SrcAddr[IRDA_DEV_ADDR_LEN];
+ BYTE DestAddr[IRDA_DEV_ADDR_LEN];
+ BYTE FirstQosByte;
+} IRLAP_UA_FORMAT;
+
+#define IRLAP_MAX_TX_MSG_LIST_LEN 8
+#define IRLAP_MAX_DATA_SIZE 4096
+#define IRLAP_MAX_SLOTS 16
+#define IRLAP_DEFAULT_BAUD 9600
+#define IRLAP_DEFAULT_DATA_SIZE 64
+#define IRLAP_DEFAULT_MAX_TAT 500
+#define IRLAP_DEFAULT_BOFS 11
+#define IRLAP_DEFAULT_WIN_SIZE 1
+
+// Macros for extracting various fields
+#define IRLAP_GET_ADDR(addr) (addr >> 1)
+#define IRLAP_GET_CRBIT(addr) (addr & 1)
+#define IRLAP_GET_PFBIT(cntl) ((cntl >>4) & 1)
+#define IRLAP_GET_UCNTL(cntl) (cntl & 0xEF)
+#define IRLAP_GET_SCNTL(cntl) (cntl & 0x0F)
+#define IRLAP_FRAME_TYPE(cntl) (cntl & 0x01 ? (cntl & 3) : 0)
+#define IRLAP_GET_NR(cntl) ((cntl & 0xE0) >> 5)
+#define IRLAP_GET_NS(cntl) ((cntl & 0xE) >> 1)
+
+// IRLAP constants
+#define IRLAP_BROADCAST_CONN_ADDR 0x7F
+#define IRLAP_END_DSCV_SLOT_NO 0xFF
+#define IRLAP_CMD 1
+#define IRLAP_RSP 0
+#define IRLAP_PFBIT_SET 1
+#define IRLAP_PFBIT_CLEAR 0
+#define IRLAP_GEN_NEW_ADDR 1
+#define IRLAP_NO_NEW_ADDR 0
+
+// Macro for creating Number of Slots of Discovery Flags Field of XID Format
+// if S(Slots) <= 1 return 0, <= 6 return 1, <= 8 return 2, else return 3
+#define IRLAP_SLOT_FLAG(S) (S <= 1 ? 0 : (S <= 6 ? 1 : (S <= 8 ? 2 : 3)))
+
+int _inline IRLAP_RAND(int Min, int Max)
+{
+ LARGE_INTEGER li;
+
+ KeQueryTickCount(&li);
+
+ return ((li.LowPart % (Max+1-Min)) + Min);
+}
+
+// Backoff time is a random time between 0.5 and 1.5 times the time to
+// send a SNRM. _SNRM_TIME() is actually half (1000ms/2) time to send
+// SNRM_LEN of characters at 9600 (9600/10 bits per char).
+#define _SNRM_LEN 32
+#define _SNRM_TIME() (_SNRM_LEN*500/960)
+#define IRLAP_BACKOFF_TIME() IRLAP_RAND(_SNRM_TIME(), 3*_SNRM_TIME())
+
+#define QOS_PI_BAUD 0x01
+#define QOS_PI_MAX_TAT 0x82
+#define QOS_PI_DATA_SZ 0x83
+#define QOS_PI_WIN_SZ 0x84
+#define QOS_PI_BOFS 0x85
+#define QOS_PI_MIN_TAT 0x86
+#define QOS_PI_DISC_THRESH 0x08
+
+
+#define IRLAP_I_FRAME 0x00
+#define IRLAP_S_FRAME 0x01
+#define IRLAP_U_FRAME 0x03
+
+// Unnumbered Frame types with P/F bit set to 0
+#define IRLAP_UI 0x03
+#define IRLAP_XID_CMD 0x2f
+#define IRLAP_TEST 0xe3
+#define IRLAP_SNRM 0x83
+#define IRLAP_RNRM 0x83
+#define IRLAP_DISC 0x43
+#define IRLAP_RD 0x43
+#define IRLAP_UA 0x63
+#define IRLAP_FRMR 0x87
+#define IRLAP_DM 0x0f
+#define IRLAP_XID_RSP 0xaf
+
+// Supervisory Frames
+#define IRLAP_RR 0x01
+#define IRLAP_RNR 0x05
+#define IRLAP_REJ 0x09
+#define IRLAP_SREJ 0x0d
+
+#define _MAKE_ADDR(Addr, CRBit) ((Addr << 1) + (CRBit & 1))
+#define _MAKE_UCNTL(Cntl, PFBit) (Cntl + ((PFBit & 1)<< 4))
+#define _MAKE_SCNTL(Cntl, PFBit, Nr) (Cntl + ((PFBit & 1)<< 4) + (Nr <<5))
+
+#define IRLAP_CB_SIG 0x7f2a364bUL
+
+// IRLAP Control Block
+typedef struct
+{
+ IRDA_MSG *pMsg[IRLAP_MOD];
+ UINT Start;
+ UINT End;
+#ifdef TEMPERAMENTAL_SERIAL_DRIVER
+ int FCS[IRLAP_MOD];
+#endif
+} IRLAP_WINDOW;
+
+typedef enum
+{
+ PRIMARY,
+ SECONDARY
+} IRLAP_STN_TYPE;
+
+typedef enum // KEEP IN SYNC with IRLAP_StateStr in irlaplog.c
+{
+ NDM, // Normal Disconnect Mode
+ DSCV_MEDIA_SENSE, // Discovery Media Sense (Before Discovery)
+ DSCV_QUERY, // Discovery Query (Discovery initiated)
+ DSCV_REPLY, // Discovery Reply (Received DSCV XID cmd from Remote)
+ CONN_MEDIA_SENSE, // Connect Media Sense (Before connection estab)
+ SNRM_SENT, // SNRM sent - waiting for UA or DM from Remote
+ BACKOFF_WAIT, // Waiting random backoff before sending next SNRM
+ SNRM_RECEIVED, // SNRM rcvd - waiting for response from upper layer
+ P_XMIT, // Primary transmit
+ P_RECV, // Primary receive
+ P_DISCONNECT_PEND, // Upper layer request disconnect while in P_RECV
+ P_CLOSE, // Sent DISC, waiting for response
+ S_NRM, // Secondary Normal Response Mode XMIT/RECV
+ S_DISCONNECT_PEND, // Upper layer request disconnect while in S_NRM
+ S_ERROR, // Waiting for PF bit then send a FRMR
+ S_CLOSE, // Requested disconnect (RD) waiting for DISC command
+} IRLAP_STATE;
+
+typedef struct IrlapControlBlock
+{
+ IRLAP_STATE State;
+ IRDA_DEVICE LocalDevice;
+ IRDA_DEVICE RemoteDevice;
+ PIRDA_LINK_CB pIrdaLinkCb;
+ IRDA_QOS_PARMS LocalQos; // QOS from LMP
+ IRDA_QOS_PARMS RemoteQos; // QOS of remote taken from SNRM/UA
+ IRDA_QOS_PARMS NegotiatedQos; // Union of remote and local QOS
+ int Baud; // Type 0 negotiation parm
+ int DisconnectTime;// Type 0 negotiation parm
+ int ThresholdTime; // Type 0 negotiotion parm
+ int LocalMaxTAT; // Type 1 negotiation parm
+ int LocalDataSize; // Type 1 negotiation parm
+ int LocalWinSize; // Type 1 negotiation parm
+ int LocalNumBOFS; // Type 1 negotiation parm
+ int RemoteMaxTAT; // Type 1 negotiation parm
+ int RemoteDataSize;// Type 1 negotiation parm
+ int RemoteWinSize; // Type 1 negotiation parm
+ int RemoteNumBOFS; // Type 1 negotiation parm
+ int RemoteMinTAT; // Type 1 negotiation parm
+ IRLAP_STN_TYPE StationType; // PRIMARY or SECONDARY
+ int ConnAddr; // Connection Address
+ int SNRMConnAddr; // Connection address contained in SNRM
+ // save it until get CONNECT_RESP
+ int CRBit; // Primary = 1, Secondary = 0
+ int RespSlot; // Secondary. Slot to respond in
+ int SlotCnt; // Primary. Current slot number
+ int MaxSlot; // Maximum slots to send in Dscv
+ int RemoteMaxSlot; // Number of Dscv's remote will send
+ LIST_ENTRY DevList; // Discovered device list
+ UINT Vs; // send state variable
+ UINT Vr; // receive state variable
+ IRLAP_WINDOW RxWin; // Holds out of sequence rxd frames
+ IRLAP_WINDOW TxWin; // Holds unacked txd frames
+ IRDA_MSG_LIST TxMsgList; // DATA_REQ, UDATA_REQ queued here
+ int RetryCnt; // Count of number of retrans of DSCV,SNRM
+ int N1; // const# retries before sending status up
+ int N2; // const# retries before disconnecting
+ int N3; // const# of connection retries
+ IRDA_TIMER SlotTimer;
+ IRDA_TIMER QueryTimer;
+ IRDA_TIMER PollTimer;
+ IRDA_TIMER FinalTimer;
+ IRDA_TIMER WDogTimer;
+ IRDA_TIMER BackoffTimer;
+ int WDogExpCnt; // Count of WDog expirations
+ int StatusSent; // Status ind has been sent
+ CRITICAL_SECTION CS; // Control block synchronization
+ BOOL GenNewAddr; // Flag indicating whether to set new addr
+ BOOL DscvRespSent; // Secondary. Sent XID Discv response
+ BOOL RemoteBusy; // Remote has sent a RNR
+ BOOL LocalBusy; // Local busy condition, we sent RNR
+ BOOL ClrLocalBusy; // Send RR
+ BOOL LocalDiscReq; // why 2ndary got DISC
+ BOOL ConnAfterClose;// Conn req while in p_close
+ BOOL DscvAfterClose;// Dscv_req while in p_close
+ BOOL NoResponse; // Final/WD timer exp'd, used with RetryCnt
+ UINT Sig; // Signature
+} IRLAP_CB, *PIRLAP_CB;
+
+#define LINE_CAPACITY(icb) (icb->RemoteWinSize * \
+ (icb->RemoteDataSize + \
+ 6+icb->RemoteNumBOFS))
+
+BYTE *BuildNegParms(BYTE *pBuf, IRDA_QOS_PARMS *pQos);
+
+void StoreULAddr(BYTE Addr[], ULONG ULAddr);
+
+BYTE *Format_SNRM(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit,
+ BYTE SAddr[], BYTE DAddr[], int CAddr,
+ IRDA_QOS_PARMS *pQos);
+
+BYTE *Format_DISC(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit);
+
+BYTE *Format_UI(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit);
+
+BYTE *Format_DscvXID(IRDA_MSG *pMsg, int ConnAddr, int CRBit, int PFBit,
+ IRLAP_XID_DSCV_FORMAT *pXidFormat, CHAR DscvInfo[],
+ int Len);
+
+BYTE *Format_TEST(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit,
+ BYTE SAddr[], BYTE DAddr[]);
+
+BYTE *Format_RNRM(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit);
+
+BYTE *Format_UA(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit,
+ BYTE SAddr[], BYTE DAddr[], IRDA_QOS_PARMS *pQos);
+
+BYTE *Format_FRMR(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit,
+ IRLAP_FRMR_FORMAT *pFormat);
+
+BYTE *Format_DM(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit);
+
+BYTE *Format_RD(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit);
+
+BYTE *Format_RR(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr);
+
+BYTE *Format_RNR(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr);
+
+BYTE *Format_REJ(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr);
+
+BYTE *Format_SREJ(IRDA_MSG *pMsg, int Addr, int CRBit, int PFBit, int Nr);
+
+BYTE * Format_I(IRDA_MSG *pMsg, int Addr, int CRBit,
+ int PFBit, int Nr, int Ns);
+
+int GetMyDevAddr(BOOL New);
+
+
diff --git a/private/ntos/tdi/irda/irlap/makefile b/private/ntos/tdi/irda/irlap/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/ntos/tdi/irda/irlap/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/ntos/tdi/irda/irlap/sources b/private/ntos/tdi/irda/irlap/sources
new file mode 100644
index 000000000..0f1ba5b0c
--- /dev/null
+++ b/private/ntos/tdi/irda/irlap/sources
@@ -0,0 +1,23 @@
+MAJORCOMP=ntos
+MINORCOMP=irda
+
+NTPROFILEINPUT=yes
+
+TARGETNAME=irlap
+TARGETTYPE=LIBRARY
+TARGETPATH=..\lib
+TARGETLIBS=
+
+
+INCLUDES=..\inc;..\..\..\inc;..\..\..\..\inc;
+
+C_DEFINES=$(C_DEFINES) -DNT -D_NTDRIVER_ -DRASAUTODIAL -D_PNP_POWER -DSECFLTR
+
+MSC_WARNING_LEVEL=/W3 /WX
+
+
+SOURCES= irlap.c \
+ irlaplog.c \
+ irlapio.c
+
+