View Javadoc
1   package org.metricshub.ipmi.core.coding.commands.payload;
2   
3   /*-
4    * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5    * IPMI Java Client
6    * ჻჻჻჻჻჻
7    * Copyright 2023 Verax Systems, MetricsHub
8    * ჻჻჻჻჻჻
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation, either version 3 of the
12   * License, or (at your option) any later version.
13   *
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Lesser Public License for more details.
18   *
19   * You should have received a copy of the GNU General Lesser Public
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
22   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
23   */
24  
25  import org.metricshub.ipmi.core.coding.commands.CommandCodes;
26  import org.metricshub.ipmi.core.coding.commands.IpmiCommandCoder;
27  import org.metricshub.ipmi.core.coding.commands.IpmiVersion;
28  import org.metricshub.ipmi.core.coding.commands.ResponseData;
29  import org.metricshub.ipmi.core.coding.payload.CompletionCode;
30  import org.metricshub.ipmi.core.coding.payload.IpmiPayload;
31  import org.metricshub.ipmi.core.coding.payload.lan.IPMIException;
32  import org.metricshub.ipmi.core.coding.payload.lan.IpmiLanRequest;
33  import org.metricshub.ipmi.core.coding.payload.lan.IpmiLanResponse;
34  import org.metricshub.ipmi.core.coding.payload.lan.NetworkFunction;
35  import org.metricshub.ipmi.core.coding.protocol.AuthenticationType;
36  import org.metricshub.ipmi.core.coding.protocol.IpmiMessage;
37  import org.metricshub.ipmi.core.coding.protocol.PayloadType;
38  import org.metricshub.ipmi.core.coding.security.CipherSuite;
39  import org.metricshub.ipmi.core.common.MessageComposer;
40  import org.metricshub.ipmi.core.common.TypeConverter;
41  
42  import org.slf4j.Logger;
43  import org.slf4j.LoggerFactory;
44  
45  import java.security.InvalidKeyException;
46  import java.security.NoSuchAlgorithmException;
47  
48  /**
49   * A wrapper class for Deactivate Payload Command.
50   */
51  public class DeactivatePayload extends IpmiCommandCoder {
52  
53      private static final Logger logger = LoggerFactory.getLogger(DeactivatePayload.class);
54  
55      private static final int REQUEST_DATA_LENGTH = 6;
56  
57      /**
58       * Payload type to be deactivated by this command.
59       */
60      private final PayloadType payloadType;
61  
62      /**
63       * Number of payload instance to use when activating.
64       */
65      private final int payloadInstance;
66  
67      public DeactivatePayload(CipherSuite cipherSuite, PayloadType payloadType, int payloadInstance) {
68          super(IpmiVersion.V20, cipherSuite, AuthenticationType.RMCPPlus);
69          this.payloadType = payloadType;
70          this.payloadInstance = payloadInstance;
71      }
72  
73      @Override
74      public byte getCommandCode() {
75          return CommandCodes.DEACTIVATE_PAYLOAD;
76      }
77  
78      /**
79       * Creates new instance of the {@link DeactivatePayload} command for deactivating given {@link PayloadType}.
80       *
81       * @param payloadType
82       *          payload to be deactivated.
83       */
84      public DeactivatePayload(PayloadType payloadType, int payloadInstance) {
85          this.payloadType = payloadType;
86          this.payloadInstance = payloadInstance;
87      }
88  
89      @Override
90      public NetworkFunction getNetworkFunction() {
91          return NetworkFunction.ApplicationRequest;
92      }
93  
94      @Override
95      protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException {
96          //We put just 2 bytes into the 6-bytes array, as specification for this command says to leave the rest 4 bytes as zeros
97          byte[] message = MessageComposer.get(REQUEST_DATA_LENGTH)
98                  .appendField(TypeConverter.intToByte(payloadType.getCode()))
99                  .appendField(TypeConverter.intToByte(payloadInstance))
100                 .getMessage();
101 
102         return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), message, TypeConverter.intToByte(sequenceNumber));
103     }
104 
105     @Override
106     public ResponseData getResponseData(IpmiMessage message) throws IPMIException, NoSuchAlgorithmException, InvalidKeyException {
107         if (!isCommandResponse(message)) {
108             throw new IllegalArgumentException("This is not a response for Deactivate Payload command");
109         }
110 
111         if (!(message.getPayload() instanceof IpmiLanResponse)) {
112             throw new IllegalArgumentException("Invalid response payload");
113         }
114 
115         CompletionCode completionCode = ((IpmiLanResponse) message.getPayload()).getCompletionCode();
116 
117         if (completionCode != CompletionCode.Ok) {
118             DeactivatePayloadCompletionCode specificCompletionCode = DeactivatePayloadCompletionCode.parseInt(completionCode.getCode());
119 
120             if (specificCompletionCode == DeactivatePayloadCompletionCode.PAYLOAD_ALREADY_DEACTIVATED) {
121                 logger.warn(specificCompletionCode.getMessage());
122             } else {
123                 throw new IPMIException(((IpmiLanResponse) message.getPayload()).getCompletionCode());
124             }
125         }
126 
127         return new DeactivatePayloadResponseData();
128     }
129 
130     @Override
131     public boolean equals(Object o) {
132         if (this == o) return true;
133         if (o == null || getClass() != o.getClass()) return false;
134 
135         DeactivatePayload that = (DeactivatePayload) o;
136 
137         if (payloadInstance != that.payloadInstance) {
138             return false;
139         }
140 
141         if (payloadType != that.payloadType) {
142             return false;
143         }
144 
145         return getCipherSuite().equals(that.getCipherSuite());
146     }
147 
148     @Override
149     public int hashCode() {
150         int result = payloadInstance;
151         result = 31 * result + payloadType.getCode();
152         result = 31 * result + (getCipherSuite() == null ? 0 : getCipherSuite().hashCode());
153         return result;
154     }
155 }