1 package org.metricshub.ipmi.core.sm.states;
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.Encoder;
26 import org.metricshub.ipmi.core.coding.commands.session.GetChannelCipherSuites;
27 import org.metricshub.ipmi.core.coding.payload.lan.IpmiLanResponse;
28 import org.metricshub.ipmi.core.coding.protocol.AuthenticationType;
29 import org.metricshub.ipmi.core.coding.protocol.IpmiMessage;
30 import org.metricshub.ipmi.core.coding.protocol.PayloadType;
31 import org.metricshub.ipmi.core.coding.protocol.decoder.ProtocolDecoder;
32 import org.metricshub.ipmi.core.coding.protocol.decoder.Protocolv20Decoder;
33 import org.metricshub.ipmi.core.coding.protocol.encoder.Protocolv20Encoder;
34 import org.metricshub.ipmi.core.coding.rmcp.RmcpMessage;
35 import org.metricshub.ipmi.core.coding.security.CipherSuite;
36 import org.metricshub.ipmi.core.common.TypeConverter;
37 import org.metricshub.ipmi.core.sm.StateMachine;
38 import org.metricshub.ipmi.core.sm.actions.ErrorAction;
39 import org.metricshub.ipmi.core.sm.actions.ResponseAction;
40 import org.metricshub.ipmi.core.sm.events.DefaultAck;
41 import org.metricshub.ipmi.core.sm.events.GetChannelCipherSuitesPending;
42 import org.metricshub.ipmi.core.sm.events.StateMachineEvent;
43 import org.metricshub.ipmi.core.sm.events.Timeout;
44
45
46
47
48
49
50
51 public class CiphersWaiting extends State {
52
53 private int index;
54
55 private int tag;
56
57
58
59
60
61
62
63
64
65 public CiphersWaiting(int index, int tag) {
66 this.index = index;
67 this.tag = tag;
68 }
69
70 @Override
71 public void doTransition(StateMachine stateMachine, StateMachineEvent machineEvent) {
72 if (machineEvent instanceof Timeout) {
73 stateMachine.setCurrent(new Uninitialized());
74 } else if (machineEvent instanceof GetChannelCipherSuitesPending) {
75 GetChannelCipherSuitesPending event = (GetChannelCipherSuitesPending) machineEvent;
76 GetChannelCipherSuites cipherSuites = new GetChannelCipherSuites(
77 TypeConverter.intToByte(0xE),
78 TypeConverter.intToByte(index + 1));
79 try {
80 tag = event.getSequenceNumber();
81 stateMachine
82 .sendMessage(Encoder.encode(new Protocolv20Encoder(), cipherSuites, event.getSequenceNumber(), 0, 0));
83 ++index;
84 } catch (Exception e) {
85 stateMachine.setCurrent(new Uninitialized());
86 stateMachine.doExternalAction(new ErrorAction(e));
87 }
88 } else if (machineEvent instanceof DefaultAck) {
89 stateMachine.setCurrent(new Ciphers());
90 } else {
91 stateMachine.doExternalAction(new ErrorAction(new IllegalArgumentException("Invalid transition")));
92 }
93 }
94
95 @Override
96 public void doAction(StateMachine stateMachine, RmcpMessage message) {
97 if (ProtocolDecoder.decodeAuthenticationType(message) != AuthenticationType.RMCPPlus) {
98 return;
99 }
100 if (Protocolv20Decoder.decodeSessionID(message) != 0) {
101 return;
102 }
103 if (Protocolv20Decoder.decodePayloadType(message.getData()[1]) != PayloadType.Ipmi) {
104 return;
105 }
106 Protocolv20Decoder decoder = new Protocolv20Decoder(CipherSuite.getEmpty());
107 if (decoder.decodeAuthentication(message.getData()[1])) {
108 return;
109 }
110 IpmiMessage ipmiMessage = null;
111 try {
112 ipmiMessage = decoder.decode(message);
113 GetChannelCipherSuites suites = new GetChannelCipherSuites();
114 if (suites.isCommandResponse(ipmiMessage)
115 && TypeConverter.byteToInt(((IpmiLanResponse) ipmiMessage.getPayload()).getSequenceNumber()) == tag) {
116 stateMachine.doExternalAction(new ResponseAction(suites.getResponseData(ipmiMessage)));
117 }
118 } catch (Exception e) {
119 stateMachine.setCurrent(new Uninitialized());
120 stateMachine.doExternalAction(new ErrorAction(e));
121 }
122 }
123
124 }