1 package org.metricshub.ipmi.core.connection;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import org.metricshub.ipmi.core.coding.PayloadCoder;
26 import org.metricshub.ipmi.core.coding.protocol.Ipmiv20Message;
27 import org.metricshub.ipmi.core.connection.queue.MessageQueue;
28 import org.metricshub.ipmi.core.sm.StateMachine;
29 import org.metricshub.ipmi.core.sm.events.Sendv20Message;
30 import org.metricshub.ipmi.core.sm.states.SessionValid;
31
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34
35
36
37
38 public abstract class MessageHandler {
39
40 private static final Logger logger = LoggerFactory.getLogger(MessageHandler.class);
41
42 protected int lastReceivedSequenceNumber = 0;
43 protected final MessageQueue messageQueue;
44 protected final Connection connection;
45
46 public MessageHandler(Connection connection, int timeout, int minSequenceNumber, int maxSequenceNumber) {
47 this.messageQueue = new MessageQueue(connection, timeout, minSequenceNumber, maxSequenceNumber);
48 this.connection = connection;
49 }
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 public int sendMessage(PayloadCoder payloadCoder, StateMachine stateMachine, int sessionId, boolean isOneWay)
67 throws ConnectionException {
68 validateSessionState(stateMachine);
69
70 int seq = isOneWay ? messageQueue.getSequenceNumber() : messageQueue.add(payloadCoder);
71 if (seq > 0) {
72 stateMachine.doTransition(new Sendv20Message(payloadCoder, sessionId, seq, connection.getNextSessionSequenceNumber()));
73 }
74
75 return seq;
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90 public int retryMessage(int tag, StateMachine stateMachine, int sessionId) throws ConnectionException {
91 validateSessionState(stateMachine);
92
93 PayloadCoder payloadCoder = messageQueue.getMessageFromQueue(tag);
94
95 if (payloadCoder == null) {
96 return -1;
97 }
98
99 stateMachine.doTransition(new Sendv20Message(payloadCoder, sessionId, tag, connection.getNextSessionSequenceNumber()));
100
101 return tag;
102 }
103
104 private void validateSessionState(StateMachine stateMachine) throws ConnectionException {
105 if (stateMachine.getCurrent().getClass() != SessionValid.class) {
106 throw new ConnectionException("Illegal connection state: " + stateMachine.getCurrent().getClass().getSimpleName());
107 }
108 }
109
110
111
112
113
114
115
116 public void handleIncomingMessage(Ipmiv20Message message) {
117
118 int seq = message.getSessionSequenceNumber();
119
120 if (seq != 0 && (seq > lastReceivedSequenceNumber + 15 || seq < lastReceivedSequenceNumber - 16)) {
121 logger.debug("Dropping message " + seq);
122 return;
123
124 }
125
126 if (seq != 0) {
127 lastReceivedSequenceNumber = (seq > lastReceivedSequenceNumber ? seq : lastReceivedSequenceNumber);
128 }
129
130 handleIncomingMessageInternal(message);
131 }
132
133 public void setTimeout(int timeout) {
134 messageQueue.setTimeout(timeout);
135 }
136
137 public void tearDown() {
138 messageQueue.tearDown();
139 }
140
141 public int getSequenceNumber() {
142 return messageQueue.getSequenceNumber();
143 }
144
145
146
147
148
149
150
151 protected abstract void handleIncomingMessageInternal(Ipmiv20Message message);
152
153 }