-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathTransWaitState.cs
110 lines (102 loc) · 4.09 KB
/
TransWaitState.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using static UniversaLIS.UniversaLIService;
namespace UniversaLIS
{
class TransWaitState : ILISState
{
public TransWaitState(CommFacilitator comm)
{
this.comm = comm;
}
private readonly CommFacilitator comm;
public void RcvInput(string InputString)
{
switch (InputString)
{
case Constants.ACK:
RcvACK();
break;
case Constants.NAK:
RcvNAK();
break;
case Constants.ENQ:
RcvENQ();
break;
case Constants.EOT:
RcvEOT();
break;
default:
RcvData(InputString);
break;
}
}
public void RcvACK()
{
#if DEBUG
AppendToLog("CurrentMessage.FrameList.Count: " + comm.CurrentMessage.FrameList.Count);
AppendToLog("CurrentFrameCounter: " + comm.CurrentFrameCounter);
#endif
// If all frames have been sent, end the transmission.
if (comm.CurrentMessage.FrameList.Count == comm.CurrentFrameCounter)
{
comm.Send(Constants.EOT);
comm.CurrentMessage = new Message(comm);
}
else
{
// Otherwise, send next frame.
comm.Send(comm.CurrentMessage.FrameList[comm.CurrentFrameCounter]);
comm.CurrentFrameCounter++;
// Reset the NAK count to 0.
comm.NumNAK = 0;
// Reset the transaction timer to 15 seconds.
comm.TransTimer.Reset(15);
}
}
public void RcvData(string InputString)
{
// Data frames should always be preceded by other signals, so for now, just log it.
// Signal the instrument to interrupt the transmission with an EOT.
AppendToLog("Data received in TransWait state: " + InputString);
comm.Send(Constants.EOT);
}
public void RcvENQ()
{
// This really shouldn't happen.
// The instrument is supposed to send an EOT first to get us to stop transmitting.
// Nevertheless, log the occurrence for troubleshooting purposes.
AppendToLog("ENQ received in TransWait state.");
}
public void RcvEOT()
{
/* This is a Receiver Interrupt request.
* Ideally, this would cause the host to stop transmitting, enter the idle state,
* and not try to send again for at least 15 seconds.
* TODO: Honor Receiver Interrupt requests.
* Or, we could choose to ignore the interrupt request,
* in which case we could treat this as a positive acknowledgement and keep going.
* We'll start with that for now.
*/
RcvACK();
}
public void RcvNAK()
{
// Send old frame.
comm.Send(comm.CurrentMessage.FrameList[comm.CurrentFrameCounter - 1]);
// Increment NAK count.
comm.NumNAK++;
if (comm.NumNAK == 6)
{
// Too many NAKs. Something's wrong. Send an EOT and go back to Idle.
// Maybe stick the message back in the queue to try again later?
comm.Send(Constants.EOT);
comm.OutboundMessageQueue.Enqueue(comm.CurrentMessage);
comm.CurrentMessage = new Message(comm);
}
}
void ILISState.HaveData()
{
// It doesn't matter if we have data to send. We're already sending something.
AppendToLog("HaveData called in TransWait state.");
}
}
}