View Javadoc
1   package org.metricshub.ipmi.core.coding.payload.lan;
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.payload.CompletionCode;
26  import org.metricshub.ipmi.core.common.TypeConverter;
27  
28  /**
29   * A wrapper class for IPMB response message.
30   */
31  public class IpmiLanResponse extends IpmiLanMessage {
32  
33  	private static final int GENERIC_CODES_START = 0xC0;
34  
35  	private CompletionCode completionCode;
36  
37  	private int rawCompletionCode;
38  
39  	/**
40  	 * Decodes the completion code. Only 00h and the generic codes (C0h-FFh, IPMI 2.0 Table 5-2) have a meaning
41  	 * common to every command; an OEM (01h-7Eh) or command-specific (80h-BEh) code is {@link CompletionCode#Unknown}
42  	 * here, and the command coder may give it its own meaning.
43  	 *
44  	 * @param completionCode the completion code byte of the response
45  	 */
46  	public void setCompletionCode(byte completionCode) {
47  		rawCompletionCode = TypeConverter.byteToInt(completionCode);
48  		this.completionCode = rawCompletionCode == 0 || rawCompletionCode >= GENERIC_CODES_START ?
49  				CompletionCode.parseInt(rawCompletionCode) :
50  				CompletionCode.Unknown;
51  	}
52  
53  	public CompletionCode getCompletionCode() {
54  		return completionCode;
55  	}
56  
57  	/**
58  	 * @return the completion code byte as the BMC sent it
59  	 */
60  	public int getRawCompletionCode() {
61  		return rawCompletionCode;
62  	}
63  
64  	/**
65  	 * Builds IPMI LAN response message from byte array.
66  	 *
67  	 * @param rawData
68  	 * @throws IllegalArgumentException
69  	 *         when the message is too short or a checksum is corrupted
70  	 */
71  	public IpmiLanResponse(byte[] rawData) {
72  		// rqAddr, netFn/rqLUN, checksum 1, rsAddr, rqSeq/rsLUN, cmd, completion code, checksum 2
73  		if (rawData.length < 8) {
74  			throw new IllegalArgumentException("IPMI LAN response is too short: " + rawData.length + " bytes");
75  		}
76  		setRequesterAddress(rawData[0]);
77  		setNetworkFunctionCode(TypeConverter.intToByte((TypeConverter.byteToInt(rawData[1]) & 0xfC) >> 2));
78  		setRequesterLogicalUnitNumber(TypeConverter.intToByte(TypeConverter.byteToInt(rawData[1]) & 0x03));
79  		if (rawData[2] != getChecksum1(rawData)) {
80  			throw new IllegalArgumentException("Checksum 1 failed");
81  		}
82  		setResponderAddress(rawData[3]);
83  		setSequenceNumber(TypeConverter.intToByte((TypeConverter.byteToInt(rawData[4]) & 0xfC) >> 2));
84  		setResponderLogicalUnitNumber(TypeConverter.intToByte(TypeConverter.byteToInt(rawData[4]) & 0x03));
85  		setCommand(rawData[5]);
86  		setCompletionCode(rawData[6]);
87  
88  		if (rawData.length > 8) {
89  			byte[] data = new byte[rawData.length - 8];
90  
91  			System.arraycopy(rawData, 7, data, 0, rawData.length - 8);
92  
93  			setData(data);
94  		}
95  
96  		if (rawData[rawData.length - 1] != getChecksum2(rawData)) {
97  			throw new IllegalArgumentException("Checksum 2 failed");
98  		}
99  	}
100 
101 	@Override
102 	public int getPayloadLength() {
103 		int length = 8;
104 		if (getData() != null) {
105 			length += getData().length;
106 		}
107 		return length;
108 	}
109 
110 	/**
111 	 * @deprecated LAN response does not hve payload data
112 	 */
113 	@Override
114 	@Deprecated
115 	public byte[] getPayloadData() {
116 		return null;
117 	}
118 
119 }