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.payload.CompletionCode;
28  import org.metricshub.ipmi.core.coding.payload.IpmiPayload;
29  import org.metricshub.ipmi.core.coding.payload.lan.IPMIException;
30  import org.metricshub.ipmi.core.coding.payload.lan.IpmiLanRequest;
31  import org.metricshub.ipmi.core.coding.payload.lan.IpmiLanResponse;
32  import org.metricshub.ipmi.core.coding.payload.lan.NetworkFunction;
33  import org.metricshub.ipmi.core.coding.protocol.IpmiMessage;
34  import org.metricshub.ipmi.core.coding.protocol.PayloadType;
35  import org.metricshub.ipmi.core.common.MessageComposer;
36  import org.metricshub.ipmi.core.common.TypeConverter;
37  
38  import java.security.InvalidKeyException;
39  import java.security.NoSuchAlgorithmException;
40  
41  /**
42   * A wrapper class for Deactivate Payload Command.
43   */
44  public class DeactivatePayload extends IpmiCommandCoder<DeactivatePayloadResponseData> {
45  
46  	private static final int REQUEST_DATA_LENGTH = 6;
47  
48  	/**
49  	 * Payload type to be deactivated by this command.
50  	 */
51  	private final PayloadType payloadType;
52  
53  	/**
54  	 * Number of payload instance to use when activating.
55  	 */
56  	private final int payloadInstance;
57  
58  	/**
59  	 * Creates new instance of the {@link DeactivatePayload} command for deactivating given {@link PayloadType}.
60  	 *
61  	 * @param payloadType
62  	 *        payload to be deactivated.
63  	 * @param payloadInstance
64  	 *        the instance of the payload, from 1
65  	 */
66  	public DeactivatePayload(PayloadType payloadType, int payloadInstance) {
67  		this.payloadType = payloadType;
68  		this.payloadInstance = payloadInstance;
69  	}
70  
71  	@Override
72  	public byte getCommandCode() {
73  		return CommandCodes.DEACTIVATE_PAYLOAD;
74  	}
75  
76  	@Override
77  	public NetworkFunction getNetworkFunction() {
78  		return NetworkFunction.ApplicationRequest;
79  	}
80  
81  	@Override
82  	protected IpmiPayload preparePayload(int sequenceNumber) throws NoSuchAlgorithmException, InvalidKeyException {
83  		// We put just 2 bytes into the 6-bytes array, as specification for this command says to leave the rest 4 bytes as
84  		// zeros
85  		byte[] message = MessageComposer.get(REQUEST_DATA_LENGTH)
86  				.appendField(TypeConverter.intToByte(payloadType.getCode()))
87  				.appendField(TypeConverter.intToByte(payloadInstance))
88  				.getMessage();
89  
90  		return new IpmiLanRequest(getNetworkFunction(), getCommandCode(), message, TypeConverter.intToByte(sequenceNumber));
91  	}
92  
93  	@Override
94  	public DeactivatePayloadResponseData getResponseData(IpmiMessage message)
95  			throws IPMIException,
96  			NoSuchAlgorithmException,
97  			InvalidKeyException {
98  		if (!isCommandResponse(message)) {
99  			throw new IllegalArgumentException("This is not a response for Deactivate Payload command");
100 		}
101 
102 		if (!(message.getPayload() instanceof IpmiLanResponse)) {
103 			throw new IllegalArgumentException("Invalid response payload");
104 		}
105 
106 		IpmiLanResponse response = (IpmiLanResponse) message.getPayload();
107 
108 		if (response.getCompletionCode() != CompletionCode.Ok) {
109 			// The command-specific codes (IPMI 2.0 Table 24-8) are read from the raw byte
110 			DeactivatePayloadCompletionCode specificCompletionCode = DeactivatePayloadCompletionCode
111 					.parseInt(response.getRawCompletionCode());
112 
113 			// A payload already deactivated is the outcome the caller wants
114 			if (specificCompletionCode != DeactivatePayloadCompletionCode.PAYLOAD_ALREADY_DEACTIVATED) {
115 				throw new IPMIException(
116 						response.getCompletionCode(),
117 						response.getRawCompletionCode(),
118 						specificCompletionCode == null ? null : specificCompletionCode.getMessage() + ".");
119 			}
120 		}
121 
122 		return new DeactivatePayloadResponseData();
123 	}
124 
125 	@Override
126 	public boolean equals(Object o) {
127 		if (this == o) {
128 			return true;
129 		}
130 		if (o == null || getClass() != o.getClass()) {
131 			return false;
132 		}
133 
134 		DeactivatePayload that = (DeactivatePayload) o;
135 
136 		if (payloadInstance != that.payloadInstance) {
137 			return false;
138 		}
139 
140 		return payloadType == that.payloadType;
141 	}
142 
143 	@Override
144 	public int hashCode() {
145 		int result = payloadInstance;
146 		result = 31 * result + payloadType.getCode();
147 		return result;
148 	}
149 }